diff --git a/.eslintrc b/.eslintrc index b676b196..dbb4ec45 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,40 +1,38 @@ { + "env": { + "es6": true, + "node": true + }, "extends": [ - "airbnb-base", + "airbnb-typescript/base", "plugin:@typescript-eslint/recommended", - "plugin:prettier/recommended" + "plugin:prettier/recommended", + "plugin:import/recommended" ], - "plugins": ["prettier", "import"], + "plugins": ["prettier"], + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, "parser": "@typescript-eslint/parser", "parserOptions": { "ecmaVersion": 2018, "sourceType": "module", - "project": "./tsconfig.eslint.json" - }, - "globals": { - "expectAsync": true - }, - "env": { - "node": true, - "es6": true, - "jest": true + "project": "./tsconfig.eslint.json" }, "rules": { - "valid-jsdoc": ["error", { "requireReturn": false }], - "consistent-return": 0, - "@typescript-eslint/no-plusplus": 0, + "no-plusplus": 0, "prettier/prettier": 2, "class-methods-use-this": 0, "no-else-return": 0, - "@typescript-eslint/lines-between-class-members": 0, + "lines-between-class-members": 0, "import/no-extraneous-dependencies": 0, "func-names": 0, "import/prefer-default-export": 0, - "@typescript-eslint/naming-convention": 0, - "@typescript-eslint/dot-notation": 0, + "@typescript-eslint/ban-ts-ignore": 0, "@typescript-eslint/ban-ts-comment": 0, - "@typescript-eslint/no-var-requires": 0, - "@typescript-eslint/no-floating-promises": 2, - "max-classes-per-file": 0 + "@typescript-eslint/no-implied-eval": 0, + "dot-notation": 0, + "@typescript-eslint/naming-convention": 0 } } diff --git a/.github/workflows/CI-pipeline.yml b/.github/workflows/CI-pipeline.yml index 90a0aef2..442a574b 100644 --- a/.github/workflows/CI-pipeline.yml +++ b/.github/workflows/CI-pipeline.yml @@ -34,7 +34,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node: [14, 16, 18, 20, 22] + node: [16, 18, 20, 22, 24] steps: - name: Checkout repository uses: actions/checkout@v4 diff --git a/__tests__/client-id.spec.js b/__tests__/client-id.spec.ts similarity index 84% rename from __tests__/client-id.spec.js rename to __tests__/client-id.spec.ts index 130b9ffa..e382b045 100644 --- a/__tests__/client-id.spec.js +++ b/__tests__/client-id.spec.ts @@ -1,9 +1,9 @@ -const fs = require('fs'); -const util = require('util'); -const os = require('os'); -const path = require('path'); -const { v4: uuidv4 } = require('uuid'); -const { getClientId } = require('../statistics/client-id'); +import fs from 'fs'; +import util from 'util'; +import os from 'os'; +import path from 'path'; +import { v4 as uuidv4 } from 'uuid'; +import { getClientId } from '../statistics/client-id'; const uuidv4Validation = /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i; const clientIdFile = path.join(os.homedir(), '.rp', 'rp.properties'); @@ -36,12 +36,12 @@ describe('Client ID test suite', () => { await unlink(clientIdFile); const clientId = await getClientId(); const content = await readFile(clientIdFile, 'utf-8'); - expect(content).toMatch(new RegExp(`^client\\.id\\s*=\\s*${clientId}\\s*(?:$|\n)`)); + expect(content).toContain(`client.id=${clientId}`); }); it('getClientId should read client ID from ~/.rp/rp.properties', async () => { await unlink(clientIdFile); - const clientId = uuidv4(undefined, undefined, 0); + const clientId = uuidv4(); await writeFile(clientIdFile, `client.id=${clientId}\n`, 'utf-8'); expect(await getClientId()).toEqual(clientId); }); @@ -51,7 +51,7 @@ describe('Client ID test suite', () => { 'first line', async () => { await unlink(clientIdFile); - const clientId = uuidv4(undefined, undefined, 0); + const clientId = uuidv4(); await writeFile(clientIdFile, `client.id=${clientId}\ntest.property=555\n`, 'utf-8'); expect(await getClientId()).toEqual(clientId); }, @@ -62,7 +62,7 @@ describe('Client ID test suite', () => { 'first line', async () => { await unlink(clientIdFile); - const clientId = uuidv4(undefined, undefined, 0); + const clientId = uuidv4(); await writeFile(clientIdFile, `test.property=555\nclient.id=${clientId}\n`, 'utf-8'); expect(await getClientId()).toEqual(clientId); }, diff --git a/__tests__/config.spec.js b/__tests__/config.spec.ts similarity index 93% rename from __tests__/config.spec.js rename to __tests__/config.spec.ts index d566182a..220398cf 100644 --- a/__tests__/config.spec.js +++ b/__tests__/config.spec.ts @@ -1,8 +1,8 @@ -const { getClientConfig, getRequiredOption, getApiKey } = require('../lib/commons/config'); -const { +import { getClientConfig, getRequiredOption, getApiKey } from '../lib/commons/config'; +import { ReportPortalRequiredOptionError, ReportPortalValidationError, -} = require('../lib/commons/errors'); +} from '../lib/commons/errors'; describe('Config commons test suite', () => { describe('getRequiredOption', () => { @@ -26,7 +26,7 @@ describe('Config commons test suite', () => { it('should throw ReportPortalRequiredOptionError in case of option not present in options', () => { let error; try { - getRequiredOption({ other: 1 }, 'project'); + getRequiredOption({ other: 1 } as any, 'project'); } catch (e) { error = e; } @@ -73,7 +73,7 @@ describe('Config commons test suite', () => { describe('getClientConfig', () => { it('should print ReportPortalValidationError error to the console in case of options is not an object type', () => { jest.spyOn(console, 'dir').mockImplementation(); - getClientConfig('options'); + getClientConfig('options' as any); expect(console.dir).toHaveBeenCalledWith( new ReportPortalValidationError('`options` must be an object.'), diff --git a/__tests__/helpers.spec.js b/__tests__/helpers.spec.ts similarity index 70% rename from __tests__/helpers.spec.js rename to __tests__/helpers.spec.ts index fe650891..36621d4b 100644 --- a/__tests__/helpers.spec.js +++ b/__tests__/helpers.spec.ts @@ -1,8 +1,8 @@ -const os = require('os'); -const fs = require('fs'); -const glob = require('glob'); -const helpers = require('../lib/helpers'); -const pjson = require('../package.json'); +import os from 'os'; +import fs from 'fs'; +import glob from 'glob'; +import * as helpers from '../lib/helpers'; +import pjson from '../package.json'; describe('Helpers', () => { describe('formatName', () => { @@ -22,7 +22,7 @@ describe('Helpers', () => { describe('now', () => { it('returns milliseconds from unix time', () => { - expect(new Date() - helpers.now()).toBeLessThan(100); // less than 100 miliseconds difference + expect(new Date().getTime() - helpers.now()).toBeLessThan(100); // less than 100 miliseconds difference }); }); @@ -44,13 +44,22 @@ describe('Helpers', () => { expect(fs.open).toHaveBeenCalledWith('rplaunch-fileOne.tmp', 'w', expect.any(Function)); }); + + it('should throw error when fs.open fails', () => { + const mockError = new Error('File system error'); + jest.spyOn(fs, 'open').mockImplementation(() => { + throw mockError; + }); + + expect(() => helpers.saveLaunchIdToFile('fileOne')).toThrow('File system error'); + }); }); describe('getSystemAttribute', () => { it('should return correct system attributes', () => { jest.spyOn(os, 'type').mockReturnValue('osType'); jest.spyOn(os, 'arch').mockReturnValue('osArchitecture'); - jest.spyOn(os, 'totalmem').mockReturnValue('1'); + jest.spyOn(os, 'totalmem').mockReturnValue(1); const nodeVersion = process.version; const expectedAttr = [ { @@ -83,7 +92,7 @@ describe('Helpers', () => { describe('generateTestCaseId', () => { it('should return undefined if there is no codeRef', () => { - const testCaseId = helpers.generateTestCaseId(); + const testCaseId = helpers.generateTestCaseId(''); expect(testCaseId).toEqual(undefined); }); @@ -101,7 +110,7 @@ describe('Helpers', () => { value: 'value', }, { value: 'valueTwo' }, - { key: 'keyTwo' }, + { key: 'keyTwo', value: '' }, { key: 'keyThree', value: 'valueThree', @@ -112,6 +121,19 @@ describe('Helpers', () => { expect(testCaseId).toEqual('codeRef[value,valueTwo,valueThree]'); }); + + it('should filter out parameters with falsy values', () => { + const parameters = [ + { value: 'value1' }, + { value: '' }, + { value: 'value2' }, + { value: 'value3' }, + ]; + + const testCaseId = helpers.generateTestCaseId('codeRef', parameters); + + expect(testCaseId).toEqual('codeRef[value1,value2,value3]'); + }); }); describe('saveLaunchUuidToFile', () => { @@ -122,5 +144,14 @@ describe('Helpers', () => { expect(fs.open).toHaveBeenCalledWith('rp-launch-uuid-fileOne.tmp', 'w', expect.any(Function)); }); + + it('should throw error when fs.open fails', () => { + const mockError = new Error('File system error'); + jest.spyOn(fs, 'open').mockImplementation(() => { + throw mockError; + }); + + expect(() => helpers.saveLaunchUuidToFile('fileOne')).toThrow('File system error'); + }); }); }); diff --git a/__tests__/outputs.spec.ts b/__tests__/outputs.spec.ts new file mode 100644 index 00000000..df46640a --- /dev/null +++ b/__tests__/outputs.spec.ts @@ -0,0 +1,53 @@ +import { OUTPUT_TYPES } from '../lib/constants/outputs'; + +describe('OUTPUT_TYPES', () => { + let consoleLogSpy: jest.SpyInstance; + let consoleErrorSpy: jest.SpyInstance; + + beforeEach(() => { + consoleLogSpy = jest.spyOn(console, 'log').mockImplementation(); + consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(); + process.env.RP_LAUNCH_UUID = ''; + }); + + afterEach(() => { + jest.restoreAllMocks(); + }); + + describe('STDOUT', () => { + it('should log launch UUID to console.log', () => { + const testUuid = 'test-launch-uuid-123'; + + OUTPUT_TYPES.STDOUT(testUuid); + + expect(consoleLogSpy).toHaveBeenCalledWith(`Report Portal Launch UUID: ${testUuid}`); + }); + }); + + describe('STDERR', () => { + it('should log launch UUID to console.error', () => { + const testUuid = 'test-launch-uuid-456'; + + OUTPUT_TYPES.STDERR(testUuid); + + expect(consoleErrorSpy).toHaveBeenCalledWith(`Report Portal Launch UUID: ${testUuid}`); + }); + }); + + describe('ENVIRONMENT', () => { + it('should set RP_LAUNCH_UUID environment variable', () => { + const testUuid = 'test-launch-uuid-789'; + + OUTPUT_TYPES.ENVIRONMENT(testUuid); + + expect(process.env.RP_LAUNCH_UUID).toBe(testUuid); + }); + }); + + describe('FILE', () => { + it('should be a function reference to helpers.saveLaunchUuidToFile', () => { + expect(typeof OUTPUT_TYPES.FILE).toBe('function'); + expect(OUTPUT_TYPES.FILE).toBeDefined(); + }); + }); +}); diff --git a/__tests__/publicReportingAPI.spec.js b/__tests__/publicReportingAPI.spec.ts similarity index 95% rename from __tests__/publicReportingAPI.spec.js rename to __tests__/publicReportingAPI.spec.ts index d7755b5c..7e6aa2c8 100644 --- a/__tests__/publicReportingAPI.spec.js +++ b/__tests__/publicReportingAPI.spec.ts @@ -1,5 +1,5 @@ -const PublicReportingAPI = require('../lib/publicReportingAPI'); -const { EVENTS } = require('../lib/constants/events'); +import PublicReportingAPI from '../lib/publicReportingAPI'; +import { EVENTS } from '../lib/constants/events'; describe('PublicReportingAPI', () => { it('setDescription should trigger process.emit with correct parameters', () => { diff --git a/__tests__/report-portal-client.spec.js b/__tests__/report-portal-client.spec.ts similarity index 95% rename from __tests__/report-portal-client.spec.js rename to __tests__/report-portal-client.spec.ts index b715aef6..d51883db 100644 --- a/__tests__/report-portal-client.spec.js +++ b/__tests__/report-portal-client.spec.ts @@ -1,7 +1,8 @@ -const process = require('process'); -const RPClient = require('../lib/report-portal-client'); -const helpers = require('../lib/helpers'); -const { OUTPUT_TYPES } = require('../lib/constants/outputs'); +// @ts-nocheck - Disabling TypeScript checking for test file to allow private property access +import process from 'process'; +import RPClient from '../lib/report-portal-client'; +import * as helpers from '../lib/helpers'; +import { OUTPUT_TYPES } from '../lib/constants/outputs'; describe('ReportPortal javascript client', () => { afterEach(() => { @@ -10,28 +11,38 @@ describe('ReportPortal javascript client', () => { describe('constructor', () => { it('creates the client instance without error', () => { - const client = new RPClient({ - apiKey: 'test', - project: 'test', - endpoint: 'https://abc.com', - }); + const client = new RPClient( + { + apiKey: 'test', + project: 'test', + endpoint: 'https://abc.com', + }, + { name: 'test-agent', version: '1.0.0' }, + ); + // @ts-ignore - accessing protected property for testing expect(client.config.apiKey).toBe('test'); + // @ts-ignore - accessing protected property for testing expect(client.config.project).toBe('test'); + // @ts-ignore - accessing protected property for testing expect(client.config.endpoint).toBe('https://abc.com'); }); }); describe('logDebug', () => { it('should call console.log with provided message if debug is true', () => { - const client = new RPClient({ - apiKey: 'test', - project: 'test', - endpoint: 'https://abc.com', - debug: true, - }); + const client = new RPClient( + { + apiKey: 'test', + project: 'test', + endpoint: 'https://abc.com', + debug: true, + }, + { name: 'test-agent', version: '1.0.0' }, + ); jest.spyOn(console, 'log').mockImplementation(); + // @ts-ignore - accessing private method for testing client.logDebug('message'); expect(console.log).toHaveBeenCalledWith('message', ''); @@ -100,10 +111,10 @@ describe('ReportPortal javascript client', () => { endpoint: 'https://abc.com', }); - const rejectAnswer = client.getRejectAnswer('tempId', 'error'); + const rejectAnswer = client.getRejectAnswer('tempId', new Error('error')); expect(rejectAnswer.tempId).toEqual('tempId'); - return expect(rejectAnswer.promise).rejects.toEqual('error'); + return expect(rejectAnswer.promise).rejects.toEqual(new Error('error')); }); }); @@ -158,6 +169,7 @@ describe('ReportPortal javascript client', () => { endpoint: 'https://rp.us/api/v1', project: 'tst', }); + // @ts-ignore - accessing private property for testing jest.spyOn(client.statistics, 'trackEvent').mockImplementation(); await client.triggerStatisticsEvent(); @@ -171,7 +183,7 @@ describe('ReportPortal javascript client', () => { endpoint: 'https://rp.us/api/v1', project: 'tst', }); - process.env.REPORTPORTAL_CLIENT_JS_NO_ANALYTICS = true; + process.env.REPORTPORTAL_CLIENT_JS_NO_ANALYTICS = 'true'; jest.spyOn(client.statistics, 'trackEvent').mockImplementation(); await client.triggerStatisticsEvent(); @@ -192,7 +204,7 @@ describe('ReportPortal javascript client', () => { }, agentParams, ); - process.env.REPORTPORTAL_CLIENT_JS_NO_ANALYTICS = false; + process.env.REPORTPORTAL_CLIENT_JS_NO_ANALYTICS = 'false'; expect(client.statistics.eventName).toEqual('start_launch'); expect(client.statistics.eventParams).toEqual( @@ -460,10 +472,10 @@ describe('ReportPortal javascript client', () => { id1: { children: ['child1'], promiseStart: Promise.resolve(), - resolveFinish: jest.fn().mockResolvedValue(), + resolveFinish: jest.fn().mockResolvedValue(undefined), }, child1: { - promiseFinish: jest.fn().mockResolvedValue(), + promiseFinish: jest.fn().mockResolvedValue(undefined), }, }; @@ -651,7 +663,7 @@ describe('ReportPortal javascript client', () => { promiseFinish: Promise.resolve(), }, }; - jest.spyOn(client.restClient, 'update').mockResolvedValue(); + jest.spyOn(client.restClient, 'update').mockResolvedValue(undefined); const result = client.updateLaunch('id1', { some: 'data' }); @@ -721,7 +733,7 @@ describe('ReportPortal javascript client', () => { jest.spyOn(client, 'getRejectAnswer').mockImplementation(); const error = new Error('Item with tempId "id3" not found'); - client.startTestItem({ testCaseId: 'testCaseId' }, 'id1', 'id3'); + client.startTestItem({ name: 'testCaseId', codeRef: 'ref1' }, 'id1', 'id3'); expect(client.getRejectAnswer).toHaveBeenCalledWith('id1', error); }); @@ -745,7 +757,7 @@ describe('ReportPortal javascript client', () => { promiseStart: Promise.resolve(), }, }; - jest.spyOn(client.itemRetriesChainMap, 'get').mockResolvedValue(); + jest.spyOn(client.itemRetriesChainMap, 'get').mockResolvedValue(undefined); jest.spyOn(client.restClient, 'create').mockResolvedValue({}); jest.spyOn(client, 'getUniqId').mockReturnValue('4n5pxq24kpiob12og9'); diff --git a/__tests__/rest.spec.js b/__tests__/rest.spec.js deleted file mode 100644 index 850b8e40..00000000 --- a/__tests__/rest.spec.js +++ /dev/null @@ -1,307 +0,0 @@ -const nock = require('nock'); -const isEqual = require('lodash/isEqual'); -const http = require('http'); -const RestClient = require('../lib/rest'); -const logger = require('../lib/logger'); - -describe('RestClient', () => { - const options = { - baseURL: 'http://report-portal-host:8080/api/v1', - headers: { - 'User-Agent': 'NodeJS', - Authorization: 'Bearer 00000000-0000-0000-0000-000000000000', - }, - restClientConfig: { - agent: { - rejectUnauthorized: false, - }, - timeout: 0, - }, - }; - const noOptions = {}; - const restClient = new RestClient(options); - - const unathorizedError = { - error: 'unauthorized', - error_description: 'Full authentication is required to access this resource', - }; - const unauthorizedErrorMessage = - 'Request failed with status code 403: ' + - '{"error":"unauthorized","error_description":"Full authentication is required to access this resource"}'; - const netErrConnectionResetError = { code: 'ECONNABORTED', message: 'connection reset' }; - - describe('constructor', () => { - it('creates object with correct properties', () => { - expect(restClient.baseURL).toBe(options.baseURL); - expect(restClient.headers).toEqual(options.headers); - expect(restClient.restClientConfig).toEqual(options.restClientConfig); - expect(restClient.axiosInstance).toBeDefined(); - }); - - it('adds Logger to axios instance if enabled', () => { - const spyLogger = jest.spyOn(logger, 'addLogger').mockReturnValue(); - const optionsWithLoggerEnabled = { - ...options, - restClientConfig: { - ...options.restClientConfig, - debug: true, - }, - }; - const client = new RestClient(optionsWithLoggerEnabled); - - expect(spyLogger).toHaveBeenCalledWith(client.axiosInstance); - }); - }); - - describe('buildPath', () => { - it('compose path basing on base', () => { - expect(restClient.buildPath('users')).toBe(`${options.baseURL}/users`); - expect(restClient.buildPath('users/123')).toBe(`${options.baseURL}/users/123`); - expect(restClient.buildPath()).toBe(`${options.baseURL}/`); - }); - }); - - describe('getRestConfig', () => { - it("return {} in case agent property is doesn't exist", () => { - restClient.restClientConfig = {}; - expect(restClient.getRestConfig()).toEqual({}); - }); - - it('creates object with correct properties with http(s) agent', () => { - restClient.restClientConfig = { - agent: { - rejectUnauthorized: false, - }, - timeout: 10000, - }; - expect(restClient.getRestConfig().httpAgent).toBeDefined(); - expect(restClient.getRestConfig().httpAgent).toBeInstanceOf(http.Agent); - expect(restClient.getRestConfig().timeout).toBe(10000); - expect(restClient.getRestConfig().agent).toBeUndefined(); - }); - }); - - describe('retrieve', () => { - it('performs GET request for resource', (done) => { - const listOfUsers = [{ id: 1 }, { id: 2 }, { id: 3 }]; - - const scope = nock(options.baseURL).get('/users').reply(200, listOfUsers); - - restClient.retrieve('users').then((result) => { - expect(result).toEqual(listOfUsers); - expect(scope.isDone()).toBeTruthy(); - - done(); - }); - }); - - it('catches NETWORK errors', (done) => { - const scope = nock(options.baseURL).get('/users').replyWithError(netErrConnectionResetError); - - restClient.retrieve('users', noOptions).catch((error) => { - expect(error instanceof Error).toBeTruthy(); - expect(error.message).toMatch(netErrConnectionResetError.message); - expect(scope.isDone()).toBeTruthy(); - - done(); - }); - }); - - it('catches API errors', (done) => { - const scope = nock(options.baseURL).get('/users').reply(403, unathorizedError); - - restClient.retrieve('users', noOptions).catch((error) => { - expect(error instanceof Error).toBeTruthy(); - expect(error.message).toMatch(unauthorizedErrorMessage); - expect(scope.isDone()).toBeTruthy(); - - done(); - }); - }); - }); - - describe('create', () => { - it('performs POST request to resource', (done) => { - const newUser = { username: 'John' }; - const userCreated = { id: 1 }; - - const scope = nock(options.baseURL) - .post('/users', (body) => isEqual(body, newUser)) - .reply(201, userCreated); - - restClient.create('users', newUser).then((result) => { - expect(result).toEqual(userCreated); - expect(scope.isDone()).toBeTruthy(); - - done(); - }); - }); - - it('catches NETWORK errors', (done) => { - const newUser = { username: 'John' }; - - const scope = nock(options.baseURL) - .post('/users', (body) => isEqual(body, newUser)) - .replyWithError(netErrConnectionResetError); - - restClient.create('users', newUser, noOptions).catch((error) => { - expect(error instanceof Error).toBeTruthy(); - expect(error.message).toMatch(netErrConnectionResetError.message); - expect(scope.isDone()).toBeTruthy(); - - done(); - }); - }); - - it('catches API errors', (done) => { - const newUser = { username: 'John' }; - - const scope = nock(options.baseURL) - .post('/users', (body) => isEqual(body, newUser)) - .reply(403, unathorizedError); - - restClient.create('users', newUser, noOptions).catch((error) => { - expect(error instanceof Error).toBeTruthy(); - expect(error.message).toMatch(unauthorizedErrorMessage); - expect(scope.isDone()).toBeTruthy(); - - done(); - }); - }); - }); - - describe('update', () => { - it('performs PUT request to resource', (done) => { - const newUserInfo = { username: 'Mike' }; - const userUpdated = { id: 1 }; - - const scope = nock(options.baseURL) - .put('/users/1', (body) => isEqual(body, newUserInfo)) - .reply(200, userUpdated); - - restClient.update('users/1', newUserInfo).then((result) => { - expect(result).toEqual(userUpdated); - expect(scope.isDone()).toBeTruthy(); - - done(); - }); - }); - - it('catches NETWORK errors', (done) => { - const newUserInfo = { username: 'Mike' }; - - const scope = nock(options.baseURL) - .put('/users/1', (body) => isEqual(body, newUserInfo)) - .replyWithError(netErrConnectionResetError); - - restClient.update('users/1', newUserInfo, noOptions).catch((error) => { - expect(error instanceof Error).toBeTruthy(); - expect(error.message).toMatch(netErrConnectionResetError.message); - expect(scope.isDone()).toBeTruthy(); - - done(); - }); - }); - - it('catches API errors', (done) => { - const newUserInfo = { username: 'Mike' }; - - const scope = nock(options.baseURL) - .put('/users/1', (body) => isEqual(body, newUserInfo)) - .reply(403, unathorizedError); - - restClient.update('users/1', newUserInfo, noOptions).catch((error) => { - expect(error instanceof Error).toBeTruthy(); - expect(error.message).toMatch(unauthorizedErrorMessage); - expect(scope.isDone()).toBeTruthy(); - - done(); - }); - }); - }); - - describe('delete', () => { - it('performs DELETE request to resource', (done) => { - const emptyBody = {}; - const userDeleted = {}; - - const scope = nock(options.baseURL).delete('/users/1').reply(200, userDeleted); - - restClient.delete('users/1', emptyBody).then((result) => { - expect(result).toEqual(userDeleted); - expect(scope.isDone()).toBeTruthy(); - - done(); - }); - }); - - it('catches NETWORK errors', (done) => { - const emptyBody = {}; - - const scope = nock(options.baseURL) - .delete('/users/1') - .replyWithError(netErrConnectionResetError); - - restClient.delete('users/1', emptyBody, noOptions).catch((error) => { - expect(error instanceof Error).toBeTruthy(); - expect(error.message).toMatch(netErrConnectionResetError.message); - expect(scope.isDone()).toBeTruthy(); - - done(); - }); - }); - - it('catches API errors', (done) => { - const emptyBody = {}; - - const scope = nock(options.baseURL).delete('/users/1').reply(403, unathorizedError); - - restClient.delete('users/1', emptyBody, noOptions).catch((error) => { - expect(error instanceof Error).toBeTruthy(); - expect(error.message).toMatch(unauthorizedErrorMessage); - expect(scope.isDone()).toBeTruthy(); - - done(); - }); - }); - }); - - describe('retrieveSyncAPI', () => { - it('should retrieve SyncAPI', (done) => { - const listOfUsers = [{ id: 1 }, { id: 2 }, { id: 3 }]; - - const scope = nock(options.baseURL).get('/users').reply(200, listOfUsers); - - restClient.retrieveSyncAPI('users').then((result) => { - expect(result).toEqual(listOfUsers); - expect(scope.isDone()).toBeTruthy(); - - done(); - }); - }); - - it('catches NETWORK errors', (done) => { - const scope = nock(options.baseURL).get('/users').replyWithError(netErrConnectionResetError); - - restClient.retrieveSyncAPI('users', noOptions).catch((error) => { - expect(error instanceof Error).toBeTruthy(); - expect(error.message).toMatch(netErrConnectionResetError.message); - expect(scope.isDone()).toBeTruthy(); - - done(); - }); - }); - - it('catches API errors', (done) => { - const scope = nock(options.baseURL).get('/users').reply(403, unathorizedError); - - restClient.retrieveSyncAPI('users', noOptions).catch((error) => { - expect(error instanceof Error).toBeTruthy(); - expect(error.message).toMatch(unauthorizedErrorMessage); - expect(scope.isDone()).toBeTruthy(); - - done(); - }); - }); - }); -}); diff --git a/__tests__/rest.spec.ts b/__tests__/rest.spec.ts new file mode 100644 index 00000000..612dffeb --- /dev/null +++ b/__tests__/rest.spec.ts @@ -0,0 +1,192 @@ +import nock from 'nock'; +import isEqual from 'lodash/isEqual'; +import http from 'http'; +import RestClient from '../lib/rest'; +import * as logger from '../lib/logger'; + +describe('RestClient', () => { + const options = { + baseURL: 'http://report-portal-host:8080/api/v1', + headers: { + 'User-Agent': 'NodeJS', + Authorization: 'Bearer 00000000-0000-0000-0000-000000000000', + }, + restClientConfig: { + agent: { + rejectUnauthorized: false, + }, + timeout: 0, + }, + }; + const restClient = new RestClient(options); + + const unathorizedError = { + error: 'unauthorized', + error_description: 'Full authentication is required to access this resource', + }; + const unauthorizedErrorMessage = + 'Request failed with status code 403: ' + + '{"error":"unauthorized","error_description":"Full authentication is required to access this resource"}'; + const netErrConnectionResetError = { code: 'ECONNABORTED', message: 'connection reset' }; + + describe('constructor', () => { + it('creates RestClient instance', () => { + expect(restClient).toBeInstanceOf(RestClient); + }); + + it('adds Logger to axios instance if enabled', () => { + const spyLogger = jest.spyOn(logger, 'addLogger').mockReturnValue(); + const optionsWithLoggerEnabled = { + ...options, + restClientConfig: { + ...options.restClientConfig, + debug: true, + }, + }; + const client = new RestClient(optionsWithLoggerEnabled); + + expect(spyLogger).toHaveBeenCalled(); + }); + + it('creates RestClient instance without restClientConfig', () => { + const optionsWithoutConfig = { + baseURL: 'http://report-portal-host:8080/api/v1', + headers: { + 'User-Agent': 'NodeJS', + Authorization: 'Bearer 00000000-0000-0000-0000-000000000000', + }, + }; + const client = new RestClient(optionsWithoutConfig); + + expect(client).toBeInstanceOf(RestClient); + }); + + it('creates RestClient instance with agent configuration', () => { + const optionsWithAgent = { + baseURL: 'https://report-portal-host:8080/api/v1', + headers: { + 'User-Agent': 'NodeJS', + Authorization: 'Bearer 00000000-0000-0000-0000-000000000000', + }, + restClientConfig: { + agent: { + rejectUnauthorized: false, + }, + }, + }; + const client = new RestClient(optionsWithAgent); + + expect(client).toBeInstanceOf(RestClient); + }); + }); + + describe('retrieve', () => { + it('performs GET request for resource', (done) => { + const listOfUsers = [{ id: 1 }, { id: 2 }, { id: 3 }]; + + const scope = nock(options.baseURL).get('/users').reply(200, listOfUsers); + + restClient.retrieve('users').then((result) => { + expect(result).toEqual(listOfUsers); + expect(scope.isDone()).toBeTruthy(); + + done(); + }); + }); + + it('catches NETWORK errors', (done) => { + const scope = nock(options.baseURL).get('/users').replyWithError(netErrConnectionResetError); + + restClient.retrieve('users').catch((error) => { + expect(error.message).toContain('connection reset'); + expect(scope.isDone()).toBeTruthy(); + + done(); + }); + }); + + it('catches HTTP errors', (done) => { + const scope = nock(options.baseURL).get('/users').reply(403, unathorizedError); + + restClient.retrieve('users').catch((error) => { + expect(error.message).toContain('unauthorized'); + expect(error.message).toContain('Full authentication is required to access this resource'); + expect(scope.isDone()).toBeTruthy(); + + done(); + }); + }); + }); + + describe('create', () => { + it('performs POST request for resource', (done) => { + const newUser = { name: 'John Doe', email: 'john@example.com' }; + const createdUser = { id: 1, ...newUser }; + + const scope = nock(options.baseURL).post('/users', newUser).reply(201, createdUser); + + restClient.create('users', newUser).then((result) => { + expect(result).toEqual(createdUser); + expect(scope.isDone()).toBeTruthy(); + + done(); + }); + }); + }); + + describe('update', () => { + it('performs PUT request for resource', (done) => { + const updatedUser = { name: 'Jane Doe', email: 'jane@example.com' }; + + const scope = nock(options.baseURL).put('/users/1', updatedUser).reply(200, updatedUser); + + restClient.update('users/1', updatedUser).then((result) => { + expect(result).toEqual(updatedUser); + expect(scope.isDone()).toBeTruthy(); + + done(); + }); + }); + }); + + describe('delete', () => { + it('performs DELETE request for resource', (done) => { + const scope = nock(options.baseURL).delete('/users/1').reply(204); + + restClient.delete('users/1').then((result) => { + expect(result).toBe(''); + expect(scope.isDone()).toBeTruthy(); + + done(); + }); + }); + }); + + describe('request', () => { + it('performs custom request with specified method', (done) => { + const userData = { name: 'John Doe' }; + const fullUrl = `${options.baseURL}/users/1`; + const scope = nock(options.baseURL).post('/users/1', userData).reply(200, userData); + + restClient.request('POST', fullUrl, userData).then((result) => { + expect(result).toEqual(userData); + expect(scope.isDone()).toBeTruthy(); + + done(); + }); + }); + + it('handles error with non-object response data', (done) => { + const scope = nock(options.baseURL).get('/users').reply(500, 'Internal Server Error'); + + restClient.request('GET', `${options.baseURL}/users`).catch((error) => { + expect(error.message).toContain('Request failed with status code 500'); + expect(error.message).toContain(`URL: ${options.baseURL}/users`); + expect(error.message).toContain('method: GET'); + expect(scope.isDone()).toBeTruthy(); + + done(); + }); + }); + }); +}); diff --git a/__tests__/statistics.spec.js b/__tests__/statistics.spec.ts similarity index 86% rename from __tests__/statistics.spec.js rename to __tests__/statistics.spec.ts index 12c4e957..4f517a8f 100644 --- a/__tests__/statistics.spec.js +++ b/__tests__/statistics.spec.ts @@ -1,6 +1,6 @@ -const axios = require('axios'); -const Statistics = require('../statistics/statistics'); -const { MEASUREMENT_ID, API_KEY } = require('../statistics/constants'); +import axios from 'axios'; +import { Statistics } from '../statistics/statistics'; +import { MEASUREMENT_ID, API_KEY } from '../statistics/constants'; const uuidv4Validation = /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i; @@ -48,9 +48,7 @@ describe('Statistics', () => { }); it('should send proper event to axios', async () => { - jest.spyOn(axios, 'post').mockReturnValue({ - send: () => {}, // eslint-disable-line - }); + jest.spyOn(axios, 'post').mockResolvedValue({} as any); const statistics = new Statistics(eventName, agentParams); await statistics.trackEvent(); @@ -63,14 +61,12 @@ describe('Statistics', () => { undefined, {}, { - name: null, - version: null, + name: undefined, + version: undefined, }, ].forEach((params) => { it(`should not fail if agent params: ${JSON.stringify(params)}`, async () => { - jest.spyOn(axios, 'post').mockReturnValue({ - send: () => {}, // eslint-disable-line - }); + jest.spyOn(axios, 'post').mockResolvedValue({} as any); const statistics = new Statistics(eventName, params); await statistics.trackEvent(); diff --git a/index.d.ts b/index.d.ts index fd974fe4..05235929 100644 --- a/index.d.ts +++ b/index.d.ts @@ -23,6 +23,7 @@ declare module '@reportportal/client-javascript' { launchUuidPrintOutput?: string; restClientConfig?: Record; token?: string; + skippedIssue?: boolean; } /** diff --git a/jest.config.js b/jest.config.js index 10700586..32ac0576 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,8 +1,8 @@ module.exports = { - moduleFileExtensions: ['js'], - testRegex: '/__tests__/.*\\.(test|spec).js$', + moduleFileExtensions: ['js', 'ts'], + testRegex: '/__tests__/.*\\.(test|spec).(js|ts)$', testEnvironment: 'node', - collectCoverageFrom: ['lib/**/*.js', '!lib/logger.js'], + collectCoverageFrom: ['lib/**/*.ts', '!lib/logger.ts'], coverageThreshold: { global: { branches: 80, @@ -12,4 +12,7 @@ module.exports = { }, }, bail: false, + transform: { + '^.+\\.ts$': 'ts-jest', + }, }; diff --git a/lib/.DS_Store b/lib/.DS_Store new file mode 100644 index 00000000..0a0db2a1 Binary files /dev/null and b/lib/.DS_Store differ diff --git a/lib/commons/config.js b/lib/commons/config.ts similarity index 51% rename from lib/commons/config.js rename to lib/commons/config.ts index a09b468f..5c404f7a 100644 --- a/lib/commons/config.js +++ b/lib/commons/config.ts @@ -1,60 +1,63 @@ -const { ReportPortalRequiredOptionError, ReportPortalValidationError } = require('./errors'); -const { OUTPUT_TYPES } = require('../constants/outputs'); +import { ReportPortalRequiredOptionError, ReportPortalValidationError } from './errors'; +import { OUTPUT_TYPES } from '../constants/outputs'; +import { ClientConfig } from '../types'; -const getOption = (options, optionName, defaultValue) => { +type OutputTypeKey = keyof typeof OUTPUT_TYPES; + +function getOption(options: T, optionName: K, defaultValue: T[K]): T[K] { if (!Object.prototype.hasOwnProperty.call(options, optionName) || !options[optionName]) { return defaultValue; } - return options[optionName]; -}; +} -const getRequiredOption = (options, optionName) => { +function getRequiredOption(options: T, optionName: K): T[K] { if (!Object.prototype.hasOwnProperty.call(options, optionName) || !options[optionName]) { - throw new ReportPortalRequiredOptionError(optionName); + throw new ReportPortalRequiredOptionError(optionName as string); } - return options[optionName]; -}; +} -const getApiKey = ({ apiKey, token }) => { - let calculatedApiKey = apiKey; +function getApiKey(options: { apiKey?: string; token?: string }): string { + let calculatedApiKey = options.apiKey; if (!calculatedApiKey) { - calculatedApiKey = token; + calculatedApiKey = options.token; if (!calculatedApiKey) { throw new ReportPortalRequiredOptionError('apiKey'); } else { + // eslint-disable-next-line no-console console.warn(`Option 'token' is deprecated. Use 'apiKey' instead.`); } } - return calculatedApiKey; -}; +} -const getClientConfig = (options) => { - let calculatedOptions = options; +function getClientConfig(options: Partial): ClientConfig { + let calculatedOptions: ClientConfig; try { - if (typeof options !== 'object') { + if (typeof options !== 'object' || options === null) { throw new ReportPortalValidationError('`options` must be an object.'); } const apiKey = getApiKey(options); const project = getRequiredOption(options, 'project'); const endpoint = getRequiredOption(options, 'endpoint'); - const launchUuidPrintOutputType = getOption(options, 'launchUuidPrintOutput', 'STDOUT') + const launchUuidPrintOutputType = ( + getOption(options, 'launchUuidPrintOutput', 'STDOUT') ?? 'STDOUT' + ) .toString() - .toUpperCase(); - const launchUuidPrintOutput = getOption( + .toUpperCase() as OutputTypeKey; + const launchUuidPrintOutput = getOption( OUTPUT_TYPES, launchUuidPrintOutputType, OUTPUT_TYPES.STDOUT, ); calculatedOptions = { - apiKey, - project, - endpoint, - launch: options.launch, + apiKey: apiKey as string, + project: project as string, + endpoint: endpoint as string, + launch: options.launch as string, debug: options.debug, isLaunchMergeRequired: options.isLaunchMergeRequired === undefined ? false : options.isLaunchMergeRequired, @@ -65,17 +68,16 @@ const getClientConfig = (options) => { description: options.description, launchUuidPrint: options.launchUuidPrint, launchUuidPrintOutput, + skippedIssue: options.skippedIssue, }; } catch (error) { // don't throw the error up to not break the entire process + // eslint-disable-next-line no-console console.dir(error); } + // @ts-ignore return calculatedOptions; -}; +} -module.exports = { - getClientConfig, - getRequiredOption, - getApiKey, -}; +export { getClientConfig, getRequiredOption, getApiKey }; diff --git a/lib/commons/errors.js b/lib/commons/errors.ts similarity index 56% rename from lib/commons/errors.js rename to lib/commons/errors.ts index a47a6a33..79125e57 100644 --- a/lib/commons/errors.js +++ b/lib/commons/errors.ts @@ -1,29 +1,23 @@ -class ReportPortalError extends Error { - constructor(message) { +export class ReportPortalError extends Error { + constructor(message: string) { const basicMessage = `\nReportPortal client error: ${message}`; super(basicMessage); this.name = 'ReportPortalError'; } } -class ReportPortalValidationError extends ReportPortalError { - constructor(message) { +export class ReportPortalValidationError extends ReportPortalError { + constructor(message: string) { const basicMessage = `\nValidation failed. Please, check the specified parameters: ${message}`; super(basicMessage); this.name = 'ReportPortalValidationError'; } } -class ReportPortalRequiredOptionError extends ReportPortalValidationError { - constructor(propertyName) { +export class ReportPortalRequiredOptionError extends ReportPortalValidationError { + constructor(propertyName: string) { const basicMessage = `\nProperty '${propertyName}' must not be empty.`; super(basicMessage); this.name = 'ReportPortalRequiredOptionError'; } } - -module.exports = { - ReportPortalError, - ReportPortalValidationError, - ReportPortalRequiredOptionError, -}; diff --git a/lib/constants/events.js b/lib/constants/events.ts similarity index 84% rename from lib/constants/events.js rename to lib/constants/events.ts index c9b5bd32..e62a1ed7 100644 --- a/lib/constants/events.js +++ b/lib/constants/events.ts @@ -1,4 +1,4 @@ -const EVENTS = { +export const EVENTS = { SET_DESCRIPTION: 'rp:setDescription', SET_TEST_CASE_ID: 'rp:setTestCaseId', SET_STATUS: 'rp:setStatus', @@ -7,5 +7,3 @@ const EVENTS = { ADD_LOG: 'rp:addLog', ADD_LAUNCH_LOG: 'rp:addLaunchLog', }; - -module.exports = { EVENTS }; diff --git a/lib/constants/outputs.js b/lib/constants/outputs.js deleted file mode 100644 index b5818e37..00000000 --- a/lib/constants/outputs.js +++ /dev/null @@ -1,13 +0,0 @@ -const helpers = require('../helpers'); - -const OUTPUT_TYPES = { - // eslint-disable-next-line no-console - STDOUT: (launchUuid) => console.log(`Report Portal Launch UUID: ${launchUuid}`), - // eslint-disable-next-line no-console - STDERR: (launchUuid) => console.error(`Report Portal Launch UUID: ${launchUuid}`), - // eslint-disable-next-line no-return-assign - ENVIRONMENT: (launchUuid) => (process.env.RP_LAUNCH_UUID = launchUuid), - FILE: helpers.saveLaunchUuidToFile, -}; - -module.exports = { OUTPUT_TYPES }; diff --git a/lib/constants/outputs.ts b/lib/constants/outputs.ts new file mode 100644 index 00000000..937a6194 --- /dev/null +++ b/lib/constants/outputs.ts @@ -0,0 +1,8 @@ +import * as helpers from '../helpers'; + +export const OUTPUT_TYPES = { + STDOUT: (launchUuid: string) => console.log(`Report Portal Launch UUID: ${launchUuid}`), + STDERR: (launchUuid: string) => console.error(`Report Portal Launch UUID: ${launchUuid}`), + ENVIRONMENT: (launchUuid: string) => (process.env.RP_LAUNCH_UUID = launchUuid), + FILE: helpers.saveLaunchUuidToFile, +}; diff --git a/lib/constants/statuses.js b/lib/constants/statuses.js deleted file mode 100644 index a7a7e789..00000000 --- a/lib/constants/statuses.js +++ /dev/null @@ -1,12 +0,0 @@ -const RP_STATUSES = { - PASSED: 'passed', - FAILED: 'failed', - SKIPPED: 'skipped', - STOPPED: 'stopped', - INTERRUPTED: 'interrupted', - CANCELLED: 'cancelled', - INFO: 'info', - WARN: 'warn', -}; - -module.exports = { RP_STATUSES }; diff --git a/lib/constants/statuses.ts b/lib/constants/statuses.ts new file mode 100644 index 00000000..255d1e1d --- /dev/null +++ b/lib/constants/statuses.ts @@ -0,0 +1,10 @@ +export enum RP_STATUSES { + PASSED = 'passed', + FAILED = 'failed', + SKIPPED = 'skipped', + STOPPED = 'stopped', + INTERRUPTED = 'interrupted', + CANCELLED = 'cancelled', + INFO = 'info', + WARN = 'warn', +} diff --git a/lib/helpers.js b/lib/helpers.ts similarity index 51% rename from lib/helpers.js rename to lib/helpers.ts index 4a7dcac9..2bdb4a3d 100644 --- a/lib/helpers.js +++ b/lib/helpers.ts @@ -1,53 +1,61 @@ -const fs = require('fs'); -const glob = require('glob'); -const os = require('os'); -const RestClient = require('./rest'); -const pjson = require('../package.json'); +import * as fs from 'fs'; +import * as glob from 'glob'; +import * as os from 'os'; +import RestClient, { RequestMethod } from './rest'; +import pjson from '../package.json'; +import { Attribute } from './types'; const MIN = 3; const MAX = 256; -const PJSON_VERSION = pjson.version; -const PJSON_NAME = pjson.name; +const PJSON_VERSION: string = pjson.version; +const PJSON_NAME: string = pjson.name; -const getUUIDFromFileName = (filename) => filename.match(/rplaunch-(.*)\.tmp/)[1]; +const getUUIDFromFileName = (filename: string): string | undefined => { + return filename.match(/rplaunch-(.*)\.tmp/)?.[1]; +}; -const formatName = (name) => { - const len = name.length; - // eslint-disable-next-line no-mixed-operators +const formatName = (name: string): string => { + const len: number = name.length; return (len < MIN ? name + new Array(MIN - len + 1).join('.') : name).slice(-MAX); }; -const now = () => { +const now = (): number => { return new Date().valueOf(); }; // TODO: deprecate and remove -const getServerResult = (url, request, options, method) => { +const getServerResult = ( + url: string, + request: any, + options: any, + method: RequestMethod, +): Promise => { return new RestClient(options).request(method, url, request, options); }; -const readLaunchesFromFile = () => { +const readLaunchesFromFile = (): Array => { const files = glob.sync('rplaunch-*.tmp'); const ids = files.map(getUUIDFromFileName); + const validIds = ids.filter((id: string | undefined) => id !== undefined) ?? []; - return ids; + return validIds as Array; }; -const saveLaunchIdToFile = (launchId) => { +const saveLaunchIdToFile = (launchId: string): void => { const filename = `rplaunch-${launchId}.tmp`; - fs.open(filename, 'w', (err) => { + fs.open(filename, 'w', (err: NodeJS.ErrnoException | null) => { if (err) { throw err; } }); }; -const getSystemAttribute = () => { +const getSystemAttribute = (): Attribute[] => { const osType = os.type(); const osArchitecture = os.arch(); const RAMSize = os.totalmem(); const nodeVersion = process.version; - const systemAttr = [ + return [ { key: 'client', value: `${PJSON_NAME}|${PJSON_VERSION}`, @@ -60,7 +68,7 @@ const getSystemAttribute = () => { }, { key: 'RAMSize', - value: RAMSize, + value: `${RAMSize}`, system: true, }, { @@ -69,11 +77,9 @@ const getSystemAttribute = () => { system: true, }, ]; - - return systemAttr; }; -const generateTestCaseId = (codeRef, params) => { +const generateTestCaseId = (codeRef: string, params?: Attribute[]): string | undefined => { if (!codeRef) { return; } @@ -82,7 +88,7 @@ const generateTestCaseId = (codeRef, params) => { return codeRef; } - const parameters = params.reduce( + const parameters = params.reduce( (result, item) => (item.value ? result.concat(item.value) : result), [], ); @@ -90,16 +96,16 @@ const generateTestCaseId = (codeRef, params) => { return `${codeRef}[${parameters}]`; }; -const saveLaunchUuidToFile = (launchUuid) => { +const saveLaunchUuidToFile = (launchUuid: string): void => { const filename = `rp-launch-uuid-${launchUuid}.tmp`; - fs.open(filename, 'w', (err) => { + fs.open(filename, 'w', (err: NodeJS.ErrnoException | null) => { if (err) { throw err; } }); }; -module.exports = { +export { formatName, now, getServerResult, diff --git a/lib/logger.js b/lib/logger.js deleted file mode 100644 index 9eb54e69..00000000 --- a/lib/logger.js +++ /dev/null @@ -1,41 +0,0 @@ -const addLogger = (axiosInstance) => { - axiosInstance.interceptors.request.use((config) => { - const startDate = new Date(); - // eslint-disable-next-line no-param-reassign - config.startTime = startDate.valueOf(); - - console.log(`Request method=${config.method} url=${config.url} [${startDate.toISOString()}]`); - - return config; - }); - - axiosInstance.interceptors.response.use( - (response) => { - const date = new Date(); - const { status, config } = response; - - console.log( - `Response status=${status} url=${config.url} time=${ - date.valueOf() - config.startTime - }ms [${date.toISOString()}]`, - ); - - return response; - }, - (error) => { - const date = new Date(); - const { response, config } = error; - const status = response ? response.status : null; - - console.log( - `Response ${status ? `status=${status}` : `message='${error.message}'`} url=${ - config.url - } time=${date.valueOf() - config.startTime}ms [${date.toISOString()}]`, - ); - - return Promise.reject(error); - }, - ); -}; - -module.exports = { addLogger }; diff --git a/lib/logger.ts b/lib/logger.ts new file mode 100644 index 00000000..94715571 --- /dev/null +++ b/lib/logger.ts @@ -0,0 +1,43 @@ +// eslint-disable-next-line import/named +import { AxiosInstance, AxiosResponse, AxiosError, InternalAxiosRequestConfig } from 'axios'; + +export const addLogger = (axiosInstance: AxiosInstance): void => { + axiosInstance.interceptors.request.use((config: InternalAxiosRequestConfig) => { + const startDate = new Date(); + (config as any).startTime = startDate.valueOf(); + + console.log(`Request method=${config.method} url=${config.url} [${startDate.toISOString()}]`); + + return config; + }); + + axiosInstance.interceptors.response.use( + (response: AxiosResponse) => { + const date = new Date(); + const { status, config } = response as AxiosResponse & { config: InternalAxiosRequestConfig }; + + console.log( + `Response status=${status} url=${config.url} time=${ + date.valueOf() - ((config as any).startTime ?? 0) + }ms [${date.toISOString()}]`, + ); + + return response; + }, + (error: AxiosError) => { + const date = new Date(); + const { response, config } = error as AxiosError & { config: InternalAxiosRequestConfig }; + const status = response ? response.status : null; + + console.log( + `Response ${status ? `status=${status}` : `message='${error.message}'`} url=${ + config && config.url + } time=${ + date.valueOf() - ((config && (config as any).startTime) ?? 0) + }ms [${date.toISOString()}]`, + ); + + return Promise.reject(error); + }, + ); +}; diff --git a/lib/publicReportingAPI.js b/lib/publicReportingAPI.js deleted file mode 100644 index cdca715d..00000000 --- a/lib/publicReportingAPI.js +++ /dev/null @@ -1,92 +0,0 @@ -const { EVENTS } = require('./constants/events'); - -/** - * Public API to emit additional events to RP JS agents. - */ -class PublicReportingAPI { - /** - * Emit set description event. - * @param {String} text - description of current test/suite. - * @param {String} suite - suite description, optional. - */ - static setDescription(text, suite) { - process.emit(EVENTS.SET_DESCRIPTION, { text, suite }); - } - - /** - * Emit add attributes event. - * @param {Array} attributes - array of attributes, should looks like this: - * [{ - * key: "attrKey", - * value: "attrValue", - * }] - * - * @param {String} suite - suite description, optional. - */ - static addAttributes(attributes, suite) { - process.emit(EVENTS.ADD_ATTRIBUTES, { attributes, suite }); - } - - /** - * Emit send log to test item event. - * @param {Object} log - log object should looks like this: - * { - * level: "INFO", - * message: "log message", - * file: { - * name: "filename", - * type: "image/png", // media type - * content: data, // file content represented as 64base string - * }, - * } - * @param {String} suite - suite description, optional. - */ - static addLog(log, suite) { - process.emit(EVENTS.ADD_LOG, { log, suite }); - } - - /** - * Emit send log to current launch event. - * @param {Object} log - log object should looks like this: - * { - * level: "INFO", - * message: "log message", - * file: { - * name: "filename", - * type: "image/png", // media type - * content: data, // file content represented as 64base string - * }, - * } - */ - static addLaunchLog(log) { - process.emit(EVENTS.ADD_LAUNCH_LOG, log); - } - - /** - * Emit set testCaseId event. - * @param {String} testCaseId - testCaseId of current test/suite. - * @param {String} suite - suite description, optional. - */ - static setTestCaseId(testCaseId, suite) { - process.emit(EVENTS.SET_TEST_CASE_ID, { testCaseId, suite }); - } - - /** - * Emit set status to current launch event. - * @param {String} status - status of current launch. - */ - static setLaunchStatus(status) { - process.emit(EVENTS.SET_LAUNCH_STATUS, status); - } - - /** - * Emit set status event. - * @param {String} status - status of current test/suite. - * @param {String} suite - suite description, optional. - */ - static setStatus(status, suite) { - process.emit(EVENTS.SET_STATUS, { status, suite }); - } -} - -module.exports = PublicReportingAPI; diff --git a/lib/publicReportingAPI.ts b/lib/publicReportingAPI.ts new file mode 100644 index 00000000..d554a947 --- /dev/null +++ b/lib/publicReportingAPI.ts @@ -0,0 +1,83 @@ +import { EVENTS } from './constants/events'; + +type Attribute = { + key?: string; + value: string; +}; + +type LogFile = { + name: string; + type: string; + content: string; +}; + +type Log = { + level?: string; + message?: string; + file?: LogFile; +}; + +export class PublicReportingAPI { + /** + * Emit set description event. + * @param text - description of current test/suite. + * @param suite - suite description, optional. + */ + static setDescription(text: string, suite?: string): void { + process.emit(EVENTS.SET_DESCRIPTION as any, { text, suite } as any); + } + + /** + * Emit add attributes event. + * @param attributes - array of attributes. + * @param suite - suite description, optional. + */ + static addAttributes(attributes: Attribute[], suite?: string): void { + process.emit(EVENTS.ADD_ATTRIBUTES as any, { attributes, suite } as any); + } + + /** + * Emit send log to test item event. + * @param log - log object. + * @param suite - suite description, optional. + */ + static addLog(log: Log, suite?: string): void { + process.emit(EVENTS.ADD_LOG as any, { log, suite } as any); + } + + /** + * Emit send log to current launch event. + * @param log - log object. + */ + static addLaunchLog(log: Log): void { + process.emit(EVENTS.ADD_LAUNCH_LOG as any, log as any); + } + + /** + * Emit set testCaseId event. + * @param testCaseId - testCaseId of current test/suite. + * @param suite - suite description, optional. + */ + static setTestCaseId(testCaseId: string, suite?: string): void { + process.emit(EVENTS.SET_TEST_CASE_ID as any, { testCaseId, suite } as any); + } + + /** + * Emit set status to current launch event. + * @param status - status of current launch. + */ + static setLaunchStatus(status: string): void { + process.emit(EVENTS.SET_LAUNCH_STATUS as any, status as any); + } + + /** + * Emit set status event. + * @param status - status of current test/suite. + * @param suite - suite description, optional. + */ + static setStatus(status: string, suite?: string): void { + process.emit(EVENTS.SET_STATUS as any, { status, suite } as any); + } +} + +export default PublicReportingAPI; diff --git a/lib/report-portal-client.js b/lib/report-portal-client.ts similarity index 62% rename from lib/report-portal-client.js rename to lib/report-portal-client.ts index 9a2cdb9b..e58525a6 100644 --- a/lib/report-portal-client.js +++ b/lib/report-portal-client.ts @@ -1,38 +1,49 @@ /* eslint-disable quotes,no-console,class-methods-use-this */ -const UniqId = require('uniqid'); -const { URLSearchParams } = require('url'); -const helpers = require('./helpers'); -const RestClient = require('./rest'); -const { getClientConfig } = require('./commons/config'); -const Statistics = require('../statistics/statistics'); -const { EVENT_NAME } = require('../statistics/constants'); -const { RP_STATUSES } = require('./constants/statuses'); +import UniqId from 'uniqid'; +import { URLSearchParams } from 'url'; +import * as helpers from './helpers'; +import RestClient from './rest'; +import { getClientConfig } from './commons/config'; +import { Statistics } from '../statistics/statistics'; +import { EVENT_NAME } from '../statistics/constants'; +import { RP_STATUSES } from './constants/statuses'; +import { + AgentParams, + Attribute, + ClientConfig, + FileObj, + FinishExecutionRQ, + FinishTestItemRQ, + ItemObj, + LaunchDataRQ, MapType, + MergeOptions, + SaveLogRQ, + TestItemDataRQ, + TempIdPromise, +} from './types'; const MULTIPART_BOUNDARY = Math.floor(Math.random() * 10000000000).toString(); class RPClient { - /** - * Create a client for RP. - * @param {Object} options - config object. - * options should look like this - * { - * apiKey: "reportportalApiKey", - * endpoint: "http://localhost:8080/api/v1", - * launch: "YOUR LAUNCH NAME", - * project: "PROJECT NAME", - * } - * - * @param {Object} agentParams - agent's info object. - * agentParams should look like this - * { - * name: "AGENT NAME", - * version: "AGENT VERSION", - * } - */ - constructor(options, agentParams) { + protected config: ClientConfig; + protected debug: boolean; + protected isLaunchMergeRequired: boolean; + protected apiKey: string; + private token: string; + private map: MapType; + private baseURL: string; + private headers: Record; + private helpers: typeof helpers; + private restClient: RestClient; + private statistics: Statistics; + private launchUuid: string; + private itemRetriesChainMap: Map>; + private itemRetriesChainKeyMapByTempId: Map; + + constructor(options: Partial, agentParams?: AgentParams) { this.config = getClientConfig(options); - this.debug = this.config.debug; - this.isLaunchMergeRequired = this.config.isLaunchMergeRequired; + this.debug = Boolean(this.config.debug); + this.isLaunchMergeRequired = Boolean(this.config.isLaunchMergeRequired); this.apiKey = this.config.apiKey; // deprecated this.token = this.apiKey; @@ -57,27 +68,31 @@ class RPClient { this.itemRetriesChainKeyMapByTempId = new Map(); } - // eslint-disable-next-line valid-jsdoc /** * * @Private */ - logDebug(msg, dataMsg = '') { + private logDebug(msg: string, dataMsg: any = ''): void { if (this.debug) { + // eslint-disable-next-line no-console console.log(msg, dataMsg); } } - calculateItemRetriesChainMapKey(launchId, parentId, name, itemId = '') { + calculateItemRetriesChainMapKey( + launchId: string, + parentId: string | undefined, + name: string, + itemId: string = '', + ): string { return `${launchId}__${parentId}__${name}__${itemId}`; } - // eslint-disable-next-line valid-jsdoc /** * * @Private */ - cleanItemRetriesChain(tempIds) { + private cleanItemRetriesChain(tempIds: string[]): void { tempIds.forEach((id) => { const key = this.itemRetriesChainKeyMapByTempId.get(id); @@ -89,21 +104,23 @@ class RPClient { }); } - getUniqId() { + getUniqId(): string { return UniqId(); } - getRejectAnswer(tempId, error) { + getRejectAnswer(tempId: string, error: Error): TempIdPromise { return { tempId, promise: Promise.reject(error), }; } - getNewItemObj(startPromiseFunc) { - let resolveFinish; - let rejectFinish; - const obj = { + getNewItemObj( + startPromiseFunc: (resolve: (value?: any) => void, reject: (reason?: any) => void) => void, + ): ItemObj { + let resolveFinish: (value?: any) => void; + let rejectFinish: (reason?: any) => void; + const obj: Partial = { promiseStart: new Promise(startPromiseFunc), realId: '', children: [], @@ -113,76 +130,39 @@ class RPClient { rejectFinish = reject; }), }; - obj.resolveFinish = resolveFinish; - obj.rejectFinish = rejectFinish; - return obj; + obj.resolveFinish = resolveFinish!; + obj.rejectFinish = rejectFinish!; + return obj as ItemObj; } - // eslint-disable-next-line valid-jsdoc /** * * @Private */ - cleanMap(ids) { + private cleanMap(ids: string[]): void { ids.forEach((id) => { delete this.map[id]; }); } - checkConnect() { + checkConnect(): Promise { const url = [this.config.endpoint.replace('/v2', '/v1'), this.config.project, 'launch'] .join('/') .concat('?page.page=1&page.size=1'); return this.restClient.request('GET', url, {}); } - async triggerStatisticsEvent() { - if (process.env.REPORTPORTAL_CLIENT_JS_NO_ANALYTICS) { + async triggerStatisticsEvent(): Promise { + if (process.env.REPORTPORTAL_CLIENT_JS_NO_ANALYTICS === 'true') { return; } await this.statistics.trackEvent(); } /** - * Start launch and report it. - * @param {Object} launchDataRQ - request object. - * launchDataRQ should look like this - * { - "description": "string" (support markdown), - "mode": "DEFAULT" or "DEBUG", - "name": "string", - "startTime": this.helper.now(), - "attributes": [ - { - "key": "string", - "value": "string" - }, - { - "value": "string" - } - ] - * } - * @Returns an object which contains a tempID and a promise - * - * As system attributes, this method sends the following data (these data are not for public use): - * client name, version; - * agent name, version (if given); - * browser name, version (if given); - * OS type, architecture; - * RAMSize; - * nodeJS version; - * - * This method works in two ways: - * First - If launchDataRQ object doesn't contain ID field, - * it would create a new Launch instance at the Report Portal with it ID. - * Second - If launchDataRQ would contain ID field, - * client would connect to the existing Launch which ID - * has been sent , and would send all data to it. - * Notice that Launch which ID has been sent must be 'IN PROGRESS' state at the Report Portal - * or it would throw an error. - * @Returns {Object} - an object which contains a tempID and a promise - */ - startLaunch(launchDataRQ) { + * Start launch and report it. + */ + startLaunch(launchDataRQ: LaunchDataRQ): { tempId: string; promise: Promise } { const tempId = this.getUniqId(); if (launchDataRQ.id) { @@ -205,10 +185,13 @@ class RPClient { const url = 'launch'; this.logDebug(`Start launch with tempId ${tempId}`, launchDataRQ); this.restClient.create(url, launchData).then( - (response) => { + (response: any) => { this.map[tempId].realId = response.id; this.launchUuid = response.id; - if (this.config.launchUuidPrint) { + if ( + this.config.launchUuidPrint && + typeof this.config.launchUuidPrintOutput === 'function' + ) { this.config.launchUuidPrintOutput(this.launchUuid); } @@ -219,8 +202,9 @@ class RPClient { this.logDebug(`Success start launch with tempId ${tempId}`, response); resolve(response); }, - (error) => { + (error: any) => { this.logDebug(`Error start launch with tempId ${tempId}`, error); + // eslint-disable-next-line no-console console.dir(error); reject(error); }, @@ -236,16 +220,11 @@ class RPClient { /** * Finish launch. - * @param {string} launchTempId - temp launch id (returned in the query "startLaunch"). - * @param {Object} finishExecutionRQ - finish launch info should include time and status. - * finishExecutionRQ should look like this - * { - * "endTime": this.helper.now(), - * "status": "passed" or one of ‘passed’, ‘failed’, ‘stopped’, ‘skipped’, ‘interrupted’, ‘cancelled’ - * } - * @Returns {Object} - an object which contains a tempID and a promise */ - finishLaunch(launchTempId, finishExecutionRQ) { + finishLaunch( + launchTempId: string, + finishExecutionRQ: FinishExecutionRQ, + ): { tempId: string; promise: Promise } { const launchObj = this.map[launchTempId]; if (!launchObj) { return this.getRejectAnswer( @@ -264,25 +243,29 @@ class RPClient { this.logDebug(`Finish launch with tempId ${launchTempId}`, finishExecutionData); const url = ['launch', launchObj.realId, 'finish'].join('/'); this.restClient.update(url, finishExecutionData).then( - (response) => { + (response: any) => { this.logDebug(`Success finish launch with tempId ${launchTempId}`, response); + // eslint-disable-next-line no-console console.log(`\nReportPortal Launch Link: ${response.link}`); launchObj.resolveFinish(response); }, - (error) => { + (error: any) => { this.logDebug(`Error finish launch with tempId ${launchTempId}`, error); + // eslint-disable-next-line no-console console.dir(error); launchObj.rejectFinish(error); }, ); }, - (error) => { + (error: any) => { + // eslint-disable-next-line no-console console.dir(error); launchObj.rejectFinish(error); }, ); }, - (error) => { + (error: any) => { + // eslint-disable-next-line no-console console.dir(error); launchObj.rejectFinish(error); }, @@ -296,10 +279,8 @@ class RPClient { /* * This method is used to create data object for merge request to ReportPortal. - * - * @Returns {Object} - an object which contains a data for merge launches in ReportPortal. */ - getMergeLaunchesRequest(launchIds, mergeOptions = {}) { + getMergeLaunchesRequest(launchIds: string[], mergeOptions: MergeOptions = {}): any { return { launches: launchIds, mergeType: 'BASIC', @@ -315,25 +296,13 @@ class RPClient { /** * This method is used for merge launches in ReportPortal. - * @param {Object} mergeOptions - options for merge request, can override default options. - * mergeOptions should look like this - * { - * "extendSuitesDescription": boolean, - * "description": string, - * "mergeType": 'BASIC' | 'DEEP', - * "name": string - * } - * Please, keep in mind that this method is work only in case - * the option isLaunchMergeRequired is true. - * - * @returns {Promise} - action promise */ - mergeLaunches(mergeOptions = {}) { + mergeLaunches(mergeOptions: MergeOptions = {}): Promise | void { if (this.isLaunchMergeRequired) { const launchUUIds = helpers.readLaunchesFromFile(); const params = new URLSearchParams({ 'filter.in.uuid': launchUUIds, - 'page.size': launchUUIds.length, + 'page.size': launchUUIds.length.toString(), }); const launchSearchUrl = this.config.mode === 'DEBUG' @@ -343,30 +312,38 @@ class RPClient { return this.restClient .retrieveSyncAPI(launchSearchUrl) .then( - (response) => { - const launchIds = response.content.map((launch) => launch.id); + (response: any) => { + const launchIds = response.content.map((launch: any) => launch.id); this.logDebug(`Found launches: ${launchIds}`, response.content); return launchIds; }, - (error) => { + (error: any) => { this.logDebug(`Error during launches search with UUIDs: ${launchUUIds}`, error); + // eslint-disable-next-line no-console console.dir(error); }, ) - .then((launchIds) => { + .then((launchIds: string[]) => { const request = this.getMergeLaunchesRequest(launchIds, mergeOptions); this.logDebug(`Merge launches with ids: ${launchIds}`, request); const mergeURL = 'launch/merge'; return this.restClient.create(mergeURL, request); }) - .then((response) => { + .then((response: any) => { this.logDebug(`Launches with UUIDs: ${launchUUIds} were successfully merged!`); - if (this.config.launchUuidPrint) { - this.config.launchUuidPrintOutput(response.uuid); + if ( + this.config.launchUuidPrint && + this.config.launchUuidPrintOutput && + typeof (this.config.launchUuidPrintOutput === 'function') + ) { + const uuid = response.uuid || 'STDOUT'; + // @ts-ignore + this.config.launchUuidPrintOutput(uuid); } }) - .catch((error) => { + .catch((error: any) => { this.logDebug(`Error merging launches with UUIDs: ${launchUUIds}`, error); + // eslint-disable-next-line no-console console.dir(error); }); } @@ -379,35 +356,16 @@ class RPClient { * This method is used for frameworks as Jasmine. There is problem when * it doesn't wait for promise resolve and stop the process. So it better to call * this method at the spec's function as @afterAll() and manually resolve this promise. - * - * @return Promise */ - getPromiseFinishAllItems(launchTempId) { + getPromiseFinishAllItems(launchTempId: string) { const launchObj = this.map[launchTempId]; return Promise.all(launchObj.children.map((itemId) => this.map[itemId].promiseFinish)); } /** - * Update launch. - * @param {string} launchTempId - temp launch id (returned in the query "startLaunch"). - * @param {Object} launchData - new launch data - * launchData should look like this - * { - "description": "string" (support markdown), - "mode": "DEFAULT" or "DEBUG", - "attributes": [ - { - "key": "string", - "value": "string" - }, - { - "value": "string" - } - ] - } - * @Returns {Object} - an object which contains a tempId and a promise - */ - updateLaunch(launchTempId, launchData) { + * Update launch. + */ + updateLaunch(launchTempId: string, launchData: any): { tempId: string; promise: Promise } { const launchObj = this.map[launchTempId]; if (!launchObj) { return this.getRejectAnswer( @@ -415,8 +373,8 @@ class RPClient { new Error(`Launch with tempId "${launchTempId}" not found`), ); } - let resolvePromise; - let rejectPromise; + let resolvePromise: (value?: any) => void; + let rejectPromise: (reason?: any) => void; const promise = new Promise((resolve, reject) => { resolvePromise = resolve; rejectPromise = reject; @@ -427,18 +385,19 @@ class RPClient { const url = ['launch', launchObj.realId, 'update'].join('/'); this.logDebug(`Update launch with tempId ${launchTempId}`, launchData); this.restClient.update(url, launchData).then( - (response) => { + (response: any) => { this.logDebug(`Launch with tempId ${launchTempId} were successfully updated`, response); resolvePromise(response); }, - (error) => { + (error: any) => { this.logDebug(`Error when updating launch with tempId ${launchTempId}`, error); + // eslint-disable-next-line no-console console.dir(error); rejectPromise(error); }, ); }, - (error) => { + (error: any) => { rejectPromise(error); }, ); @@ -449,33 +408,13 @@ class RPClient { } /** - * If there is no parentItemId starts Suite, else starts test or item. - * @param {Object} testItemDataRQ - object with item parameters - * testItemDataRQ should look like this - * { - "description": "string" (support markdown), - "name": "string", - "startTime": this.helper.now(), - "attributes": [ - { - "key": "string", - "value": "string" - }, - { - "value": "string" - } - ], - "type": 'SUITE' or one of 'SUITE', 'STORY', 'TEST', - 'SCENARIO', 'STEP', 'BEFORE_CLASS', 'BEFORE_GROUPS', - 'BEFORE_METHOD', 'BEFORE_SUITE', 'BEFORE_TEST', - 'AFTER_CLASS', 'AFTER_GROUPS', 'AFTER_METHOD', - 'AFTER_SUITE', 'AFTER_TEST' - } - * @param {string} launchTempId - temp launch id (returned in the query "startLaunch"). - * @param {string} parentTempId (optional) - temp item id (returned in the query "startTestItem"). - * @Returns {Object} - an object which contains a tempId and a promise - */ - startTestItem(testItemDataRQ, launchTempId, parentTempId) { + * If there is no parentItemId starts Suite, else starts test or item. + */ + startTestItem( + testItemDataRQ: TestItemDataRQ, + launchTempId: string, + parentTempId?: string, + ): TempIdPromise { let parentMapId = launchTempId; const launchObj = this.map[launchTempId]; if (!launchObj) { @@ -532,22 +471,23 @@ class RPClient { const realParentId = this.map[parentTempId].realId; url += `${realParentId}`; } - testItemData.launchUuid = realLaunchId; + (testItemData as any).launchUuid = realLaunchId; this.logDebug(`Start test item with tempId ${tempId}`, testItemData); this.restClient.create(url, testItemData).then( - (response) => { + (response: any) => { this.logDebug(`Success start item with tempId ${tempId}`, response); this.map[tempId].realId = response.id; resolve(response); }, - (error) => { + (error: any) => { this.logDebug(`Error start item with tempId ${tempId}`, error); + // eslint-disable-next-line no-console console.dir(error); reject(error); }, ); }, - (error) => { + (error: any) => { reject(error); }, ); @@ -563,30 +503,12 @@ class RPClient { } /** - * Finish Suite or Step level. - * @param {string} itemTempId - temp item id (returned in the query "startTestItem"). - * @param {Object} finishTestItemRQ - object with item parameters. - * finishTestItemRQ should look like this - { - "endTime": this.helper.now(), - "issue": { - "comment": "string", - "externalSystemIssues": [ - { - "submitDate": 0, - "submitter": "string", - "systemId": "string", - "ticketId": "string", - "url": "string" - } - ], - "issueType": "string" - }, - "status": "passed" or one of 'passed', 'failed', 'stopped', 'skipped', 'interrupted', 'cancelled' - } - * @Returns {Object} - an object which contains a tempId and a promise - */ - finishTestItem(itemTempId, finishTestItemRQ) { + * Finish Suite or Step level. + */ + finishTestItem( + itemTempId: string, + finishTestItemRQ: FinishTestItemRQ, + ): TempIdPromise { const itemObj = this.map[itemTempId]; if (!itemObj) { return this.getRejectAnswer( @@ -601,6 +523,10 @@ class RPClient { ...finishTestItemRQ, }; + if (finishTestItemData.status === RP_STATUSES.SKIPPED && this.config.skippedIssue === false) { + finishTestItemData.issue = { issueType: 'NOT_ISSUE' }; + } + itemObj.finishSend = true; this.logDebug(`Finish all children for test item with tempId ${itemTempId}`); Promise.allSettled( @@ -609,7 +535,7 @@ class RPClient { .then((results) => { if (this.debug) { results.forEach((result, index) => { - if (result.status === 'fulfilled') { + if ((result as PromiseFulfilledResult).status === 'fulfilled') { this.logDebug( `Successfully finish child with tempId ${itemObj.children[index]} of test item with tempId ${itemTempId}`, @@ -642,25 +568,29 @@ class RPClient { }; } - saveLog(itemObj, requestPromiseFunc) { + saveLog( + itemObj: ItemObj, + requestPromiseFunc: (itemUuid: string, launchUuid: string) => Promise, + ): { tempId: string; promise: Promise } { const tempId = this.getUniqId(); this.map[tempId] = this.getNewItemObj((resolve, reject) => { itemObj.promiseStart.then( () => { this.logDebug(`Save log with tempId ${tempId}`, itemObj); requestPromiseFunc(itemObj.realId, this.launchUuid).then( - (response) => { + (response: any) => { this.logDebug(`Successfully save log with tempId ${tempId}`, response); resolve(response); }, - (error) => { + (error: any) => { this.logDebug(`Error save log with tempId ${tempId}`, error); + // eslint-disable-next-line no-console console.dir(error); reject(error); }, ); }, - (error) => { + (error: any) => { reject(error); }, ); @@ -670,8 +600,8 @@ class RPClient { const logObj = this.map[tempId]; logObj.finishSend = true; logObj.promiseStart.then( - (response) => logObj.resolveFinish(response), - (error) => logObj.rejectFinish(error), + (response: any) => logObj.resolveFinish(response), + (error: any) => logObj.rejectFinish(error), ); return { @@ -680,7 +610,11 @@ class RPClient { }; } - sendLog(itemTempId, saveLogRQ, fileObj) { + sendLog( + itemTempId: string, + saveLogRQ: SaveLogRQ, + fileObj?: FileObj, + ): { tempId: string; promise: Promise } { const saveLogData = { time: this.helpers.now(), message: '', @@ -696,17 +630,11 @@ class RPClient { /** * Send log of test results. - * @param {string} itemTempId - temp item id (returned in the query "startTestItem"). - * @param {Object} saveLogRQ - object with data of test result. - * saveLogRQ should look like this - * { - * level: 'error' or one of 'trace', 'debug', 'info', 'warn', 'error', '', - * message: 'string' (support markdown), - * time: this.helpers.now() - * } - * @Returns {Object} - an object which contains a tempId and a promise */ - sendLogWithoutFile(itemTempId, saveLogRQ) { + sendLogWithoutFile( + itemTempId: string, + saveLogRQ: SaveLogRQ, + ): { tempId: string; promise: Promise } { const itemObj = this.map[itemTempId]; if (!itemObj) { return this.getRejectAnswer( @@ -715,7 +643,7 @@ class RPClient { ); } - const requestPromise = (itemUuid, launchUuid) => { + const requestPromise = (itemUuid: string, launchUuid: string) => { const url = 'log'; const isItemUuid = itemUuid !== launchUuid; return this.restClient.create( @@ -727,27 +655,13 @@ class RPClient { } /** - * Send log of test results with file. - * @param {string} itemTempId - temp item id (returned in the query "startTestItem"). - * @param {Object} saveLogRQ - object with data of test result. - * saveLogRQ should look like this - * { - * level: 'error' or one of 'trace', 'debug', 'info', 'warn', 'error', '', - * message: 'string' (support markdown), - * time: this.helpers.now() - * } - * @param {Object} fileObj - object with file data. - * fileObj should look like this - * { - name: 'string', - type: "image/png" or your file mimeType - (supported types: 'image/*', application/ ['xml', 'javascript', 'json', 'css', 'php'], - another format will be opened in a new browser tab ), - content: file - * } - * @Returns {Object} - an object which contains a tempId and a promise - */ - sendLogWithFile(itemTempId, saveLogRQ, fileObj) { + * Send log of test results with file. + */ + sendLogWithFile( + itemTempId: string, + saveLogRQ: SaveLogRQ, + fileObj: FileObj, + ): { tempId: string; promise: Promise } { const itemObj = this.map[itemTempId]; if (!itemObj) { return this.getRejectAnswer( @@ -756,7 +670,7 @@ class RPClient { ); } - const requestPromise = (itemUuid, launchUuid) => { + const requestPromise = (itemUuid: string, launchUuid: string) => { const isItemUuid = itemUuid !== launchUuid; return this.getRequestLogWithFile( @@ -768,10 +682,10 @@ class RPClient { return this.saveLog(itemObj, requestPromise); } - getRequestLogWithFile(saveLogRQ, fileObj) { + getRequestLogWithFile(saveLogRQ: SaveLogRQ, fileObj: FileObj): Promise { const url = 'log'; // eslint-disable-next-line no-param-reassign - saveLogRQ.file = { name: fileObj.name }; + (saveLogRQ as any).file = { name: fileObj.name }; this.logDebug(`Save log with file: ${fileObj.name}`, saveLogRQ); return this.restClient .create(url, this.buildMultiPartStream([saveLogRQ], fileObj, MULTIPART_BOUNDARY), { @@ -779,28 +693,26 @@ class RPClient { 'Content-Type': `multipart/form-data; boundary=${MULTIPART_BOUNDARY}`, }, }) - .then((response) => { + .then((response: any) => { this.logDebug(`Success save log with file: ${fileObj.name}`, response); return response; }) - .catch((error) => { + .catch((error: any) => { this.logDebug(`Error save log with file: ${fileObj.name}`, error); + // eslint-disable-next-line no-console console.dir(error); }); } - // eslint-disable-next-line valid-jsdoc /** * * @Private */ - buildMultiPartStream(jsonPart, filePart, boundary) { + buildMultiPartStream(jsonPart: any, filePart: FileObj, boundary: string): Buffer { const eol = '\r\n'; const bx = `--${boundary}`; const buffers = [ - // eslint-disable-next-line function-paren-newline Buffer.from( - // eslint-disable-next-line prefer-template bx + eol + 'Content-Disposition: form-data; name="json_request_part"' + @@ -812,9 +724,7 @@ class RPClient { JSON.stringify(jsonPart) + eol, ), - // eslint-disable-next-line function-paren-newline Buffer.from( - // eslint-disable-next-line prefer-template bx + eol + 'Content-Disposition: form-data; name="file"; filename="' + @@ -832,7 +742,7 @@ class RPClient { return Buffer.concat(buffers); } - finishTestItemPromiseStart(itemObj, itemTempId, finishTestItemData) { + finishTestItemPromiseStart(itemObj: ItemObj, itemTempId: string, finishTestItemData: any): void { itemObj.promiseStart.then( () => { const url = ['item', itemObj.realId].join('/'); @@ -840,22 +750,23 @@ class RPClient { this.restClient .update(url, Object.assign(finishTestItemData, { launchUuid: this.launchUuid })) .then( - (response) => { + (response: any) => { this.logDebug(`Success finish item with tempId ${itemTempId}`, response); itemObj.resolveFinish(response); }, - (error) => { + (error: any) => { this.logDebug(`Error finish test item with tempId ${itemTempId}`, error); + // eslint-disable-next-line no-console console.dir(error); itemObj.rejectFinish(error); }, ); }, - (error) => { + (error: any) => { itemObj.rejectFinish(error); }, ); } } -module.exports = RPClient; +export default RPClient; diff --git a/lib/rest.js b/lib/rest.ts similarity index 52% rename from lib/rest.js rename to lib/rest.ts index 3528329f..7262e4a1 100644 --- a/lib/rest.js +++ b/lib/rest.ts @@ -1,8 +1,8 @@ -const axios = require('axios'); -const axiosRetry = require('axios-retry').default; -const http = require('http'); -const https = require('https'); -const logger = require('./logger'); +import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'; +import axiosRetry from 'axios-retry'; +import * as http from 'http'; +import * as https from 'https'; +import { addLogger } from './logger'; const DEFAULT_MAX_CONNECTION_TIME_MS = 30000; @@ -12,8 +12,28 @@ axiosRetry(axios, { retryCondition: axiosRetry.isRetryableError, }); -class RestClient { - constructor(options) { +export interface RestClientOptions { + baseURL: string; + headers?: Record; + restClientConfig?: { + [key: string]: any; + agent?: http.AgentOptions | https.AgentOptions; + debug?: boolean; + }; +} + +export type RequestMethod = 'GET' | 'POST' | 'PUT' | 'DELETE'; + +export default class RestClient { + private baseURL: string; + + private headers?: Record; + + private restClientConfig?: { [key: string]: any }; + + private axiosInstance: AxiosInstance; + + constructor(options: RestClientOptions) { this.baseURL = options.baseURL; this.headers = options.headers; this.restClientConfig = options.restClientConfig; @@ -21,23 +41,28 @@ class RestClient { this.axiosInstance = axios.create({ timeout: DEFAULT_MAX_CONNECTION_TIME_MS, headers: this.headers, - ...this.getRestConfig(this.restClientConfig), + ...this.getRestConfig(), }); if (this.restClientConfig?.debug) { - logger.addLogger(this.axiosInstance); + addLogger(this.axiosInstance); } } - buildPath(path) { + private buildPath(path: string): string { return [this.baseURL, path].join('/'); } - buildPathToSyncAPI(path) { + private buildPathToSyncAPI(path: string): string { return [this.baseURL.replace('/v2', '/v1'), path].join('/'); } - request(method, url, data, options = {}) { + request( + method: RequestMethod, + url: string, + data?: any, + options: AxiosRequestConfig = {}, + ): Promise { return this.axiosInstance .request({ method, @@ -46,11 +71,11 @@ class RestClient { ...options, headers: { HOST: new URL(url).host, - ...options.headers, + ...(options.headers || {}), }, }) - .then((response) => response.data) - .catch((error) => { + .then((response: AxiosResponse) => response.data) + .catch((error: any) => { const errorMessage = error.message; const responseData = error.response && error.response.data; throw new Error( @@ -65,15 +90,18 @@ method: ${method}`, }); } - getRestConfig() { + private getRestConfig(): Record { if (!this.restClientConfig) return {}; - const config = Object.keys(this.restClientConfig).reduce((acc, key) => { - if (key !== 'agent') { - acc[key] = this.restClientConfig[key]; - } - return acc; - }, {}); + const config: Record = Object.keys(this.restClientConfig).reduce( + (acc: Record, key: string) => { + if (key !== 'agent') { + acc[key] = this.restClientConfig![key]; + } + return acc; + }, + {}, + ); if ('agent' in this.restClientConfig) { const { protocol } = new URL(this.baseURL); @@ -87,13 +115,13 @@ method: ${method}`, return config; } - create(path, data, options = {}) { + create(path: string, data?: any, options: AxiosRequestConfig = {}): Promise { return this.request('POST', this.buildPath(path), data, { ...options, }); } - retrieve(path, options = {}) { + retrieve(path: string, options: AxiosRequestConfig = {}): Promise { return this.request( 'GET', this.buildPath(path), @@ -104,19 +132,19 @@ method: ${method}`, ); } - update(path, data, options = {}) { + update(path: string, data?: any, options: AxiosRequestConfig = {}): Promise { return this.request('PUT', this.buildPath(path), data, { ...options, }); } - delete(path, data, options = {}) { + delete(path: string, data?: any, options: AxiosRequestConfig = {}): Promise { return this.request('DELETE', this.buildPath(path), data, { ...options, }); } - retrieveSyncAPI(path, options = {}) { + retrieveSyncAPI(path: string, options: AxiosRequestConfig = {}): Promise { return this.request( 'GET', this.buildPathToSyncAPI(path), @@ -127,5 +155,3 @@ method: ${method}`, ); } } - -module.exports = RestClient; diff --git a/lib/types.ts b/lib/types.ts new file mode 100644 index 00000000..3c9890eb --- /dev/null +++ b/lib/types.ts @@ -0,0 +1,111 @@ +export interface Attribute { + value: string; + key?: string; + system?: boolean; +} + +export interface ClientConfig { + apiKey: string; + endpoint: string; + launch: string; + project: string; + + headers?: Record; + debug?: boolean; + isLaunchMergeRequired?: boolean; + launchUuidPrint?: boolean; + + launchUuidPrintOutput?: string | ((param: string) => void); + restClientConfig?: Record; + token?: string; + // + attributes?: Attribute[]; + mode?: string; + description?: string; + skippedIssue?: boolean; +} + +export type AgentParams = { + name: string; + version: string; +}; + +export type LaunchDataRQ = { + id?: string; + description?: string; + mode?: string; + name?: string; + startTime?: number; + attributes?: Attribute[]; +}; + +export type FinishExecutionRQ = { + endTime?: number; + status?: string; +}; + +export type MergeOptions = { + extendSuitesDescription?: boolean; + description?: string; + mergeType?: 'BASIC' | 'DEEP'; + name?: string; +}; + +export type TestItemDataRQ = { + description?: string; + name: string; + startTime?: number; + attributes?: Attribute[]; + type?: string; + testCaseId?: string; + codeRef: string; + parameters?: any[]; + uniqueId?: string; + retry?: boolean; +}; + +export type FinishTestItemRQ = { + endTime?: number; + issue?: { + comment?: string; + externalSystemIssues?: Array<{ + submitDate?: number; + submitter?: string; + systemId?: string; + ticketId?: string; + url?: string; + }>; + issueType?: string; + }; + status?: string; +}; + +export type FileObj = { + name: string; + type: string; + content: string; +}; + +export type SaveLogRQ = { + level?: string; + message?: string; + time?: number; +}; + +export type ItemObj = { + promiseStart: Promise; + realId: string; + children: string[]; + finishSend: boolean; + promiseFinish: Promise; + resolveFinish: (value?: any) => void; + rejectFinish: (reason?: any) => void; +}; + +export type MapType = { [tempId: string]: ItemObj }; + + +export type TempIdPromise = { + tempId: string; + promise: Promise; +}; diff --git a/package-lock.json b/package-lock.json index 81d3d8c7..8775aec6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "@reportportal/client-javascript", - "version": "5.3.1", + "version": "5.4.0", "license": "Apache-2.0", "dependencies": { "axios": "^1.8.4", @@ -17,8 +17,13 @@ "uuid": "^9.0.1" }, "devDependencies": { - "@types/jest": "^29.5.12", - "@types/node": "^18.19.8", + "@types/glob": "^8.1.0", + "@types/ini": "^4.1.1", + "@types/jest": "^29.5.14", + "@types/lodash": "^4.17.20", + "@types/node": "^18.19.112", + "@types/uniqid": "^5.3.4", + "@types/uuid": "^10.0.0", "@typescript-eslint/eslint-plugin": "5.62.0", "@typescript-eslint/parser": "^5.62.0", "eslint": "^7.32.0", @@ -33,25 +38,12 @@ "nock": "^13.5.0", "prettier": "^2.8.8", "rimraf": "^3.0.2", - "ts-jest": "^29.1.5", + "ts-jest": "^29.4.1", "ts-node": "^10.9.2", "typescript": "^4.9.5" }, "engines": { - "node": ">=14.x" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" + "node": ">=16.x" } }, "node_modules/@babel/code-frame": { @@ -64,30 +56,32 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", - "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz", + "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", - "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helpers": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz", + "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.4", + "@babel/types": "^7.28.4", + "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -103,57 +97,57 @@ } }, "node_modules/@babel/core/node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/core/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", - "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", + "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "@babel/parser": "^7.28.3", + "@babel/types": "^7.28.2", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", - "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -166,71 +160,45 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", - "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", - "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "dev": true, - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", - "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", - "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" }, "engines": { "node": ">=6.9.0" @@ -240,74 +208,54 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", - "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", - "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", - "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz", - "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.27.0", - "@babel/types": "^7.27.0" + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" }, "engines": { "node": ">=6.9.0" @@ -400,12 +348,13 @@ } }, "node_modules/@babel/parser": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz", - "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", + "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.27.0" + "@babel/types": "^7.28.4" }, "bin": { "parser": "bin/babel-parser.js" @@ -419,6 +368,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -431,6 +381,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -443,6 +394,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, @@ -450,11 +402,44 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", + "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -467,6 +452,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -475,12 +461,13 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", - "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", + "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -494,6 +481,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -506,6 +494,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -518,6 +507,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -530,6 +520,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -542,6 +533,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -554,6 +546,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -561,11 +554,28 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -577,12 +587,13 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", - "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", + "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -592,84 +603,78 @@ } }, "node_modules/@babel/template": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz", - "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.26.2", - "@babel/parser": "^7.27.0", - "@babel/types": "^7.27.0" + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template/node_modules/@babel/code-frame": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", - "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.25.9", + "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", - "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz", + "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7", - "debug": "^4.3.1", - "globals": "^11.1.0" + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4", + "debug": "^4.3.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse/node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/types": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz", - "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", + "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -679,7 +684,8 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", @@ -781,6 +787,7 @@ "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, + "license": "ISC", "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", @@ -797,6 +804,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -806,6 +814,7 @@ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -815,6 +824,7 @@ "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", @@ -832,6 +842,7 @@ "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", "dev": true, + "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", "@jest/reporters": "^29.7.0", @@ -879,6 +890,7 @@ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/fake-timers": "^29.7.0", "@jest/types": "^29.6.3", @@ -894,6 +906,7 @@ "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", "dev": true, + "license": "MIT", "dependencies": { "expect": "^29.7.0", "jest-snapshot": "^29.7.0" @@ -907,6 +920,7 @@ "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", "dev": true, + "license": "MIT", "dependencies": { "jest-get-type": "^29.6.3" }, @@ -919,6 +933,7 @@ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@sinonjs/fake-timers": "^10.0.2", @@ -936,6 +951,7 @@ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", "@jest/expect": "^29.7.0", @@ -951,6 +967,7 @@ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", "dev": true, + "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", "@jest/console": "^29.7.0", @@ -995,6 +1012,7 @@ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -1015,6 +1033,7 @@ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, + "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.27.8" }, @@ -1027,6 +1046,7 @@ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.18", "callsites": "^3.0.0", @@ -1041,6 +1061,7 @@ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", "dev": true, + "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", "@jest/types": "^29.6.3", @@ -1056,6 +1077,7 @@ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/test-result": "^29.7.0", "graceful-fs": "^4.2.9", @@ -1071,6 +1093,7 @@ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", "@jest/types": "^29.6.3", @@ -1092,30 +1115,12 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/transform/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "node_modules/@jest/transform/node_modules/write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, "node_modules/@jest/types": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", @@ -1129,17 +1134,25 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { @@ -1151,26 +1164,19 @@ "node": ">=6.0.0" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.30", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz", + "integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -1215,13 +1221,15 @@ "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@sinonjs/commons": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" } @@ -1231,6 +1239,7 @@ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.0" } @@ -1264,6 +1273,7 @@ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", @@ -1273,10 +1283,11 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.0.0" } @@ -1286,18 +1297,31 @@ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, + "license": "MIT", "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__traverse": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", - "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.20.7" + "@types/minimatch": "^5.1.2", + "@types/node": "*" } }, "node_modules/@types/graceful-fs": { @@ -1305,21 +1329,31 @@ "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, + "node_modules/@types/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@types/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-MIyNUZipBTbyUNnhvuXJTY7B6qNI78meck9Jbv3wk0OgNwRyOOVEKDutAkOs1snB/tx0FafyR6/SN4Ps0hZPeg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/istanbul-lib-report": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" } @@ -1329,15 +1363,17 @@ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" } }, "node_modules/@types/jest": { - "version": "29.5.12", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", - "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", + "version": "29.5.14", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", + "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", "dev": true, + "license": "MIT", "dependencies": { "expect": "^29.0.0", "pretty-format": "^29.0.0" @@ -1355,11 +1391,26 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "node_modules/@types/lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { - "version": "18.19.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.8.tgz", - "integrity": "sha512-g1pZtPhsvGVTwmeVoexWZLTQaOvXwoSq//pTL0DHeNzUDrFnir4fgETdhjhIxjVnN+hKOuh98+E1eMLnUXstFg==", + "version": "18.19.112", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.112.tgz", + "integrity": "sha512-i+Vukt9POdS/MBI7YrrkkI5fMfwFtOjphSmt4WXYLfwqsfr6z/HdCx7LqT9M7JktGob8WNgj8nFB4TbGNE4Cog==", "dev": true, + "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } @@ -1374,13 +1425,29 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/@types/uniqid": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/@types/uniqid/-/uniqid-5.3.4.tgz", + "integrity": "sha512-AgC+o3/8/QEHuU3w5w2jZ8auQtjSJ/s8G8RfEk9CYLogK1RGXqxhHH0wOEAu8uHXjvj8oh/dRtfgok4IHKxh/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", + "dev": true, + "license": "MIT" }, "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", "dev": true, + "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } @@ -1389,7 +1456,8 @@ "version": "21.0.3", "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "5.62.0", @@ -1639,6 +1707,7 @@ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.21.3" }, @@ -1654,6 +1723,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -1690,6 +1760,7 @@ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -1882,6 +1953,7 @@ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, + "license": "MIT", "dependencies": { "@jest/transform": "^29.7.0", "@types/babel__core": "^7.1.14", @@ -1903,6 +1975,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", @@ -1919,6 +1992,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", @@ -1935,6 +2009,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -1944,6 +2019,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", @@ -1955,26 +2031,30 @@ } }, "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", + "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@babel/core": "^7.0.0 || ^8.0.0-0" } }, "node_modules/babel-preset-jest": { @@ -1982,6 +2062,7 @@ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", "dev": true, + "license": "MIT", "dependencies": { "babel-plugin-jest-hoist": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0" @@ -2021,9 +2102,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", - "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", + "version": "4.25.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.4.tgz", + "integrity": "sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg==", "dev": true, "funding": [ { @@ -2039,11 +2120,12 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001629", - "electron-to-chromium": "^1.4.796", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.16" + "caniuse-lite": "^1.0.30001737", + "electron-to-chromium": "^1.5.211", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" @@ -2069,6 +2151,7 @@ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "node-int64": "^0.4.0" } @@ -2077,7 +2160,8 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/call-bind": { "version": "1.0.5", @@ -2107,14 +2191,15 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001636", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001636.tgz", - "integrity": "sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==", + "version": "1.0.30001741", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001741.tgz", + "integrity": "sha512-QGUGitqsc8ARjLdgAfxETDhRbJ0REsP6O3I96TAth/mVjh2cYzN2u+3AzPP3aVSm2FehEItaJw1xd+IGBXWeSw==", "dev": true, "funding": [ { @@ -2129,7 +2214,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chalk": { "version": "4.1.2", @@ -2152,6 +2238,7 @@ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } @@ -2167,21 +2254,24 @@ "url": "https://github.com/sponsors/sibiraj-s" } ], + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/cjs-module-lexer": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", - "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", - "dev": true + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "dev": true, + "license": "MIT" }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -2196,6 +2286,7 @@ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true, + "license": "MIT", "engines": { "iojs": ">= 1.0.0", "node": ">= 0.12.0" @@ -2205,7 +2296,8 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/color-convert": { "version": "2.0.1", @@ -2248,11 +2340,19 @@ "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", "dev": true }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "chalk": "^4.0.0", @@ -2307,10 +2407,11 @@ } }, "node_modules/dedent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", - "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.0.tgz", + "integrity": "sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==", "dev": true, + "license": "MIT", "peerDependencies": { "babel-plugin-macros": "^3.1.0" }, @@ -2331,6 +2432,7 @@ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2378,6 +2480,7 @@ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -2396,6 +2499,7 @@ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } @@ -2425,16 +2529,18 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.811", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.811.tgz", - "integrity": "sha512-CDyzcJ5XW78SHzsIOdn27z8J4ist8eaFLhdto2hSMSJQgsiwvbv2fbizcKUICryw1Wii1TI/FEkvzvJsR3awrA==", - "dev": true + "version": "1.5.215", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.215.tgz", + "integrity": "sha512-TIvGp57UpeNetj/wV/xpFNpWGb0b/ROw372lHPx5Aafx02gjTBtWnEEcaSX3W2dLM3OSdGGyHX/cHl01JQsLaQ==", + "dev": true, + "license": "ISC" }, "node_modules/emittery": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -2465,6 +2571,7 @@ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, + "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } @@ -2563,10 +2670,11 @@ } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -3039,6 +3147,7 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -3071,6 +3180,7 @@ "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/expect-utils": "^29.7.0", "jest-get-type": "^29.6.3", @@ -3136,6 +3246,7 @@ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "bser": "2.1.1" } @@ -3169,6 +3280,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -3248,6 +3360,7 @@ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -3303,6 +3416,7 @@ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -3312,6 +3426,7 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -3336,6 +3451,7 @@ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.0.0" } @@ -3345,6 +3461,7 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -3483,7 +3600,8 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/graphemer": { "version": "1.4.0", @@ -3491,6 +3609,28 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -3588,13 +3728,15 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=10.17.0" } @@ -3625,10 +3767,11 @@ } }, "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "dev": true, + "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" @@ -3706,7 +3849,8 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-bigint": { "version": "1.0.4", @@ -3798,6 +3942,7 @@ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -3894,6 +4039,7 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -3971,19 +4117,21 @@ "dev": true }, "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=8" } }, "node_modules/istanbul-lib-instrument": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz", - "integrity": "sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.23.9", "@babel/parser": "^7.23.9", @@ -3996,17 +4144,18 @@ } }, "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", + "make-dir": "^4.0.0", "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/istanbul-lib-source-maps": { @@ -4014,6 +4163,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", @@ -4024,10 +4174,11 @@ } }, "node_modules/istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -4041,6 +4192,7 @@ "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -4067,6 +4219,7 @@ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", "dev": true, + "license": "MIT", "dependencies": { "execa": "^5.0.0", "jest-util": "^29.7.0", @@ -4076,26 +4229,12 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-changed-files/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/jest-circus": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", "@jest/expect": "^29.7.0", @@ -4122,26 +4261,12 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-circus/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/jest-cli": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", "dev": true, + "license": "MIT", "dependencies": { "@jest/core": "^29.7.0", "@jest/test-result": "^29.7.0", @@ -4175,6 +4300,7 @@ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", "@jest/test-sequencer": "^29.7.0", @@ -4221,6 +4347,7 @@ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4241,6 +4368,7 @@ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "diff-sequences": "^29.6.3", @@ -4256,6 +4384,7 @@ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", "dev": true, + "license": "MIT", "dependencies": { "detect-newline": "^3.0.0" }, @@ -4268,6 +4397,7 @@ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "chalk": "^4.0.0", @@ -4284,6 +4414,7 @@ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", "@jest/fake-timers": "^29.7.0", @@ -4301,6 +4432,7 @@ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } @@ -4310,6 +4442,7 @@ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@types/graceful-fs": "^4.1.3", @@ -4335,6 +4468,7 @@ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", "dev": true, + "license": "MIT", "dependencies": { "jest-get-type": "^29.6.3", "pretty-format": "^29.7.0" @@ -4348,6 +4482,7 @@ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "jest-diff": "^29.7.0", @@ -4363,6 +4498,7 @@ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.13", "@jest/types": "^29.6.3", @@ -4379,13 +4515,15 @@ } }, "node_modules/jest-message-util/node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" @@ -4396,6 +4534,7 @@ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", @@ -4410,6 +4549,7 @@ "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" }, @@ -4427,6 +4567,7 @@ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } @@ -4436,6 +4577,7 @@ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", @@ -4456,6 +4598,7 @@ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", "dev": true, + "license": "MIT", "dependencies": { "jest-regex-util": "^29.6.3", "jest-snapshot": "^29.7.0" @@ -4469,6 +4612,7 @@ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", "@jest/environment": "^29.7.0", @@ -4496,26 +4640,12 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-runner/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/jest-runtime": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", "@jest/fake-timers": "^29.7.0", @@ -4550,6 +4680,7 @@ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4570,6 +4701,7 @@ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", "@babel/generator": "^7.7.2", @@ -4601,6 +4733,7 @@ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", @@ -4618,6 +4751,7 @@ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "camelcase": "^6.2.0", @@ -4635,6 +4769,7 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4647,6 +4782,7 @@ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", "dev": true, + "license": "MIT", "dependencies": { "@jest/test-result": "^29.7.0", "@jest/types": "^29.6.3", @@ -4666,6 +4802,7 @@ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "jest-util": "^29.7.0", @@ -4681,6 +4818,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -4711,22 +4849,24 @@ } }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", @@ -4751,6 +4891,7 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, + "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -4763,6 +4904,7 @@ "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -4772,6 +4914,7 @@ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -4793,13 +4936,15 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -4836,34 +4981,27 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^3.0.2" } }, "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, + "license": "MIT", "dependencies": { - "semver": "^6.0.0" + "semver": "^7.5.3" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -4875,6 +5013,7 @@ "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "tmpl": "1.0.5" } @@ -4883,7 +5022,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", @@ -4931,6 +5071,7 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -4974,6 +5115,13 @@ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, "node_modules/nock": { "version": "13.5.0", "resolved": "https://registry.npmjs.org/nock/-/nock-13.5.0.tgz", @@ -4992,19 +5140,22 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.20.tgz", + "integrity": "sha512-7gK6zSXEH6neM212JgfYFXe+GmZQM+fia5SsusuBIUgnPheLFBmIPhtFoAQRj8/7wASYQnbDlHPVwY0BefoFgA==", + "dev": true, + "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -5014,6 +5165,7 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.0.0" }, @@ -5130,6 +5282,7 @@ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -5158,15 +5311,16 @@ } }, "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { - "p-try": "^2.0.0" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">=6" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5177,6 +5331,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -5184,11 +5339,28 @@ "node": ">=8" } }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -5210,6 +5382,7 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -5228,6 +5401,7 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5266,10 +5440,11 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", @@ -5284,10 +5459,11 @@ } }, "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } @@ -5297,6 +5473,7 @@ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^4.0.0" }, @@ -5345,6 +5522,7 @@ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -5359,6 +5537,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -5380,6 +5559,7 @@ "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, + "license": "MIT", "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" @@ -5425,7 +5605,8 @@ "type": "opencollective", "url": "https://opencollective.com/fast-check" } - ] + ], + "license": "MIT" }, "node_modules/queue-microtask": { "version": "1.2.3", @@ -5451,7 +5632,8 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/regexp.prototype.flags": { "version": "1.5.1", @@ -5487,6 +5669,7 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -5522,6 +5705,7 @@ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, + "license": "MIT", "dependencies": { "resolve-from": "^5.0.0" }, @@ -5534,6 +5718,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5548,10 +5733,11 @@ } }, "node_modules/resolve.exports": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", - "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", + "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } @@ -5758,13 +5944,15 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/slash": { "version": "3.0.0", @@ -5797,6 +5985,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -5806,6 +5995,7 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -5822,6 +6012,7 @@ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, + "license": "MIT", "dependencies": { "escape-string-regexp": "^2.0.0" }, @@ -5834,6 +6025,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5843,6 +6035,7 @@ "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, + "license": "MIT", "dependencies": { "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" @@ -5927,6 +6120,7 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5936,6 +6130,7 @@ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -6019,6 +6214,7 @@ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, + "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", @@ -6032,7 +6228,9 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -6058,7 +6256,8 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/to-regex-range": { "version": "5.0.1", @@ -6073,19 +6272,21 @@ } }, "node_modules/ts-jest": { - "version": "29.1.5", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.5.tgz", - "integrity": "sha512-UuClSYxM7byvvYfyWdFI+/2UxMmwNyJb0NPkZPQE2hew3RurV7l7zURgOHAd/1I1ZdPpe3GUsXNXAcN8TFKSIg==", + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.1.tgz", + "integrity": "sha512-SaeUtjfpg9Uqu8IbeDKtdaS0g8lS6FT6OzM3ezrDfErPJPHNDo/Ey+VFGP1bQIDfagYDLyRpd7O15XpG1Es2Uw==", "dev": true, + "license": "MIT", "dependencies": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^29.0.0", + "bs-logger": "^0.2.6", + "fast-json-stable-stringify": "^2.1.0", + "handlebars": "^4.7.8", "json5": "^2.2.3", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "^7.5.3", - "yargs-parser": "^21.0.1" + "lodash.memoize": "^4.1.2", + "make-error": "^1.3.6", + "semver": "^7.7.2", + "type-fest": "^4.41.0", + "yargs-parser": "^21.1.1" }, "bin": { "ts-jest": "cli.js" @@ -6095,10 +6296,11 @@ }, "peerDependencies": { "@babel/core": ">=7.0.0-beta.0 <8", - "@jest/transform": "^29.0.0", - "@jest/types": "^29.0.0", - "babel-jest": "^29.0.0", - "jest": "^29.0.0", + "@jest/transform": "^29.0.0 || ^30.0.0", + "@jest/types": "^29.0.0 || ^30.0.0", + "babel-jest": "^29.0.0 || ^30.0.0", + "jest": "^29.0.0 || ^30.0.0", + "jest-util": "^29.0.0 || ^30.0.0", "typescript": ">=4.3 <6" }, "peerDependenciesMeta": { @@ -6116,9 +6318,38 @@ }, "esbuild": { "optional": true + }, + "jest-util": { + "optional": true } } }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", @@ -6245,6 +6476,7 @@ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -6331,6 +6563,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -6339,6 +6572,20 @@ "node": ">=4.2.0" } }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -6366,9 +6613,9 @@ "integrity": "sha512-38JRbJ4Fj94VmnC7G/J/5n5SC7Ab46OM5iNtSstB/ko3l1b5g7ALt4qzHFgGciFkyiRNtDXtLNb+VsxtMSE77A==" }, "node_modules/update-browserslist-db": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", - "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", "dev": true, "funding": [ { @@ -6384,9 +6631,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -6433,6 +6681,7 @@ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", "dev": true, + "license": "ISC", "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", @@ -6442,17 +6691,12 @@ "node": ">=10.12.0" } }, - "node_modules/v8-to-istanbul/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "makeerror": "1.0.12" } @@ -6516,11 +6760,19 @@ "node": ">=0.10.0" } }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -6538,11 +6790,26 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } @@ -6551,13 +6818,15 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -6594,6 +6863,7 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, diff --git a/package.json b/package.json index 431da884..22fdef1e 100644 --- a/package.json +++ b/package.json @@ -15,14 +15,72 @@ "lib": "./lib" }, "files": [ - "/lib", + "/build", "/statistics", "/VERSION" ], - "main": "./lib/report-portal-client", - "types": "./index.d.ts", + "main": "build/lib/report-portal-client", + "types": "build/lib/report-portal-client.d.ts", + "exports": { + ".": { + "node": "./build/lib/report-portal-client.js", + "default": "./build/lib/report-portal-client.js", + "require": "./build/lib/report-portal-client.js", + "import": "./build/lib/report-portal-client.js" + }, + "./helpers": { + "node": "./build/lib/helpers.js", + "default": "./build/lib/helpers.js", + "require": "./build/lib/helpers.js", + "import": "./build/lib/helpers.js" + }, + "./lib/helpers": { + "node": "./build/lib/helpers.js", + "default": "./build/lib/helpers.js", + "require": "./build/lib/helpers.js", + "import": "./build/lib/helpers.js" + }, + "./lib/constants/events": { + "node": "./build/lib/constants/events.js", + "default": "./build/lib/constants/events.js", + "require": "./build/lib/constants/events.js", + "import": "./build/lib/constants/events.js" + }, + "./lib/constants/statuses": { + "node": "./build/lib/constants/statuses.js", + "default": "./build/lib/constants/statuses.js", + "require": "./build/lib/constants/statuses.js", + "import": "./build/lib/constants/statuses.js" + }, + "./lib/publicReportingAPI": { + "node": "./build/lib/publicReportingAPI.js", + "default": "./build/lib/publicReportingAPI.js", + "require": "./build/lib/publicReportingAPI.js", + "import": "./build/lib/publicReportingAPI.js" + } + }, + "typesVersions": { + "*": { + "helpers": [ + "./build/lib/helpers.d.ts" + ], + "lib/helpers": [ + "./build/lib/helpers.d.ts" + ], + "lib/constants/events": [ + "./build/lib/constants/events.d.ts" + ], + "lib/constants/statuses": [ + "./build/lib/constants/statuses.d.ts" + ], + "lib/publicReportingAPI": [ + "./build/lib/publicReportingAPI.d.ts" + ] + } + }, + "type": "commonjs", "engines": { - "node": ">=14.x" + "node": ">=16.x" }, "dependencies": { "axios": "^1.8.4", @@ -34,8 +92,13 @@ }, "license": "Apache-2.0", "devDependencies": { - "@types/jest": "^29.5.12", - "@types/node": "^18.19.8", + "@types/glob": "^8.1.0", + "@types/ini": "^4.1.1", + "@types/jest": "^29.5.14", + "@types/lodash": "^4.17.20", + "@types/node": "^18.19.112", + "@types/uniqid": "^5.3.4", + "@types/uuid": "^10.0.0", "@typescript-eslint/eslint-plugin": "5.62.0", "@typescript-eslint/parser": "^5.62.0", "eslint": "^7.32.0", @@ -50,7 +113,7 @@ "nock": "^13.5.0", "prettier": "^2.8.8", "rimraf": "^3.0.2", - "ts-jest": "^29.1.5", + "ts-jest": "^29.4.1", "ts-node": "^10.9.2", "typescript": "^4.9.5" }, diff --git a/statistics/client-id.js b/statistics/client-id.ts similarity index 72% rename from statistics/client-id.js rename to statistics/client-id.ts index 23949c0f..9ca04758 100644 --- a/statistics/client-id.js +++ b/statistics/client-id.ts @@ -1,8 +1,8 @@ -const fs = require('fs'); -const util = require('util'); -const ini = require('ini'); -const { v4: uuidv4 } = require('uuid'); -const { ENCODING, CLIENT_ID_KEY, RP_FOLDER_PATH, RP_PROPERTIES_FILE_PATH } = require('./constants'); +import * as fs from 'fs'; +import * as util from 'util'; +import * as ini from 'ini'; +import { v4 as uuidv4 } from 'uuid'; +import { ENCODING, CLIENT_ID_KEY, RP_FOLDER_PATH, RP_PROPERTIES_FILE_PATH } from './constants'; const exists = util.promisify(fs.exists); const readFile = util.promisify(fs.readFile); @@ -18,8 +18,8 @@ async function readClientId() { return null; } -async function storeClientId(clientId) { - const properties = {}; +async function storeClientId(clientId: string) { + const properties: Record = {}; if (await exists(RP_PROPERTIES_FILE_PATH)) { const propertiesContent = await readFile(RP_PROPERTIES_FILE_PATH, ENCODING); Object.assign(properties, ini.parse(propertiesContent)); @@ -30,10 +30,10 @@ async function storeClientId(clientId) { await writeFile(RP_PROPERTIES_FILE_PATH, propertiesContent, ENCODING); } -async function getClientId() { +export async function getClientId() { let clientId = await readClientId(); if (!clientId) { - clientId = uuidv4(undefined, undefined, 0); + clientId = uuidv4(); try { await storeClientId(clientId); } catch (ignore) { @@ -42,5 +42,3 @@ async function getClientId() { } return clientId; } - -module.exports = { getClientId }; diff --git a/statistics/constants.js b/statistics/constants.ts similarity index 88% rename from statistics/constants.js rename to statistics/constants.ts index 0fbc6004..ef24aef8 100644 --- a/statistics/constants.js +++ b/statistics/constants.ts @@ -1,6 +1,6 @@ -const os = require('os'); -const path = require('path'); -const pjson = require('../package.json'); +import * as os from 'os'; +import * as path from 'path'; +import pjson from '../package.json'; const ENCODING = 'utf-8'; const PJSON_VERSION = pjson.version; @@ -17,7 +17,7 @@ const CLIENT_INFO = Buffer.from( const [MEASUREMENT_ID, API_KEY] = CLIENT_INFO.split(':'); const EVENT_NAME = 'start_launch'; -function getNodeVersion() { +function getNodeVersion(): string | null { // A workaround to avoid reference error in case this is not a Node.js application if (typeof process !== 'undefined') { if (process.versions) { @@ -32,7 +32,7 @@ function getNodeVersion() { const INTERPRETER = getNodeVersion(); -module.exports = { +export { ENCODING, EVENT_NAME, PJSON_VERSION, diff --git a/statistics/statistics.js b/statistics/statistics.ts similarity index 57% rename from statistics/statistics.js rename to statistics/statistics.ts index 56042ee0..75653e4b 100644 --- a/statistics/statistics.js +++ b/statistics/statistics.ts @@ -1,20 +1,29 @@ -const axios = require('axios'); -const { MEASUREMENT_ID, API_KEY, PJSON_NAME, PJSON_VERSION, INTERPRETER } = require('./constants'); -const { getClientId } = require('./client-id'); +import axios from 'axios'; +import { MEASUREMENT_ID, API_KEY, PJSON_NAME, PJSON_VERSION, INTERPRETER } from './constants'; +import { getClientId } from './client-id'; -const hasOption = (options, optionName) => { +interface AgentParams { + name?: string; + version?: string; +} + +const hasOption = (options: any, optionName: string): boolean => { return Object.prototype.hasOwnProperty.call(options, optionName); }; -class Statistics { - constructor(eventName, agentParams) { +export class Statistics { + public eventName: string; + + public eventParams: Record; + + constructor(eventName: string, agentParams?: AgentParams) { this.eventName = eventName; this.eventParams = this.getEventParams(agentParams); } - getEventParams(agentParams) { - const params = { - interpreter: INTERPRETER, + private getEventParams(agentParams?: AgentParams): Record { + const params: Record = { + interpreter: INTERPRETER || '', client_name: PJSON_NAME, client_version: PJSON_VERSION, }; @@ -27,7 +36,7 @@ class Statistics { return params; } - async trackEvent() { + async trackEvent(): Promise { try { const requestBody = { client_id: await getClientId(), @@ -44,9 +53,7 @@ class Statistics { requestBody, ); } catch (error) { - console.error(error.message); + console.error((error as Error).message); } } } - -module.exports = Statistics; diff --git a/tsconfig.json b/tsconfig.json index b655f001..46a83b8b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,11 +7,13 @@ "moduleResolution": "node", "strictNullChecks": true, "downlevelIteration": true, +// "declarationMap": true, "declaration": true, "lib": ["es2016", "es2016.array.include"], "module": "commonjs", "target": "ES2015", "baseUrl": ".", + "resolveJsonModule": true, "paths": { "*": ["node_modules/*"] },