Skip to content

feat(javascript): add logger-console package from v4 #3823

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,14 +1,35 @@
import { test, expect } from 'vitest';
/* eslint no-console: 0 */

import { algoliasearch, apiClientVersion } from '../builds/browser';
import { vi, test, expect } from 'vitest';

const client = algoliasearch('APP_ID', 'API_KEY');
import { LogLevelEnum } from '../../client-common/src/types';
import { createConsoleLogger } from '../../logger-console/src/logger';
import { algoliasearch, apiClientVersion } from '../builds/browser';

test('sets the ua', () => {
const client = algoliasearch('APP_ID', 'API_KEY');

expect(client.transporter.algoliaAgent).toEqual({
add: expect.any(Function),
value: expect.stringContaining(
`Algolia for JavaScript (${apiClientVersion}); Search (${apiClientVersion}); Browser`,
),
});
});

test('with logger', () => {
vi.spyOn(console, 'debug');
vi.spyOn(console, 'info');
vi.spyOn(console, 'error');

const client = algoliasearch('APP_ID', 'API_KEY', {
logger: createConsoleLogger(LogLevelEnum.Debug),
});

expect(async () => {
await client.setSettings({ indexName: 'foo', indexSettings: {} });
expect(console.debug).toHaveBeenCalledTimes(1);
expect(console.info).toHaveBeenCalledTimes(1);
expect(console.error).toHaveBeenCalledTimes(1);
}).not.toThrow();
});
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ describe('api', () => {
url: 'APP_ID-2.algolianet.com',
},
]),
logger: {
debug: expect.any(Function),
error: expect.any(Function),
info: expect.any(Function),
},
hostsCache: {
clear: expect.any(Function),
delete: expect.any(Function),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,42 @@
import { test, expect } from 'vitest';
/* eslint no-console: 0 */

import { algoliasearch, apiClientVersion } from '../builds/fetch';
import { vi, test, expect } from 'vitest';

const client = algoliasearch('APP_ID', 'API_KEY');
import { LogLevelEnum } from '../../client-common/src/types';
import { createConsoleLogger } from '../../logger-console/src/logger';
import { algoliasearch, apiClientVersion } from '../builds/fetch';

test('sets the ua', () => {
const client = algoliasearch('APP_ID', 'API_KEY');
expect(client.transporter.algoliaAgent).toEqual({
add: expect.any(Function),
value: expect.stringContaining(`Algolia for JavaScript (${apiClientVersion}); Search (${apiClientVersion}); Fetch`),
});
});

test('forwards node search helpers', () => {
const client = algoliasearch('APP_ID', 'API_KEY');
expect(client.generateSecuredApiKey).not.toBeUndefined();
expect(client.getSecuredApiKeyRemainingValidity).not.toBeUndefined();
expect(() => {
const resp = client.generateSecuredApiKey({ parentApiKey: 'foo', restrictions: { validUntil: 200 } });
client.getSecuredApiKeyRemainingValidity({ securedApiKey: resp });
}).not.toThrow();
});

test('with logger', () => {
vi.spyOn(console, 'debug');
vi.spyOn(console, 'info');
vi.spyOn(console, 'error');

const client = algoliasearch('APP_ID', 'API_KEY', {
logger: createConsoleLogger(LogLevelEnum.Debug),
});

expect(async () => {
await client.setSettings({ indexName: 'foo', indexSettings: {} });
expect(console.debug).toHaveBeenCalledTimes(1);
expect(console.info).toHaveBeenCalledTimes(1);
expect(console.error).toHaveBeenCalledTimes(1);
}).not.toThrow();
});
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { test, expect } from 'vitest';
/* eslint no-console: 0 */

import { algoliasearch, apiClientVersion } from '../builds/node';
import { vi, test, expect } from 'vitest';

const client = algoliasearch('APP_ID', 'API_KEY');
import { LogLevelEnum } from '../../client-common/src/types';
import { createConsoleLogger } from '../../logger-console/src/logger';
import { algoliasearch, apiClientVersion } from '../builds/node';

test('sets the ua', () => {
const client = algoliasearch('APP_ID', 'API_KEY');
expect(client.transporter.algoliaAgent).toEqual({
add: expect.any(Function),
value: expect.stringContaining(
Expand All @@ -14,10 +17,28 @@ test('sets the ua', () => {
});

test('forwards node search helpers', () => {
const client = algoliasearch('APP_ID', 'API_KEY');
expect(client.generateSecuredApiKey).not.toBeUndefined();
expect(client.getSecuredApiKeyRemainingValidity).not.toBeUndefined();
expect(() => {
const resp = client.generateSecuredApiKey({ parentApiKey: 'foo', restrictions: { validUntil: 200 } });
client.getSecuredApiKeyRemainingValidity({ securedApiKey: resp });
}).not.toThrow();
});

test('with logger', () => {
vi.spyOn(console, 'debug');
vi.spyOn(console, 'info');
vi.spyOn(console, 'error');

const client = algoliasearch('APP_ID', 'API_KEY', {
logger: createConsoleLogger(LogLevelEnum.Debug),
});

expect(async () => {
await client.setSettings({ indexName: 'foo', indexSettings: {} });
expect(console.debug).toHaveBeenCalledTimes(1);
expect(console.info).toHaveBeenCalledTimes(1);
expect(console.error).toHaveBeenCalledTimes(1);
}).not.toThrow();
});
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
export * from './src/createAuth';
export * from './src/createIterablePromise';
export * from './src/cache';
export * from './src/transporter';
export * from './src/constants';
export * from './src/createAlgoliaAgent';
export * from './src/createAuth';
export * from './src/createIterablePromise';
export * from './src/getAlgoliaAgent';
export * from './src/logger';
export * from './src/transporter';
export * from './src/types';
export * from './src/constants';
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* eslint no-console: 0 */

import { vi, describe, test, expect } from 'vitest';

import { createNullLogger } from '../../logger';

describe('null logger', () => {
test('has a null behavior', async () => {
vi.resetAllMocks();
vi.spyOn(console, 'debug');
vi.spyOn(console, 'info');
vi.spyOn(console, 'error');

const logger = createNullLogger();

await logger.debug('foo', {});
await logger.info('foo', {});
await logger.error('foo', {});

expect(console.debug).toHaveBeenCalledTimes(0);
expect(console.info).toHaveBeenCalledTimes(0);
expect(console.error).toHaveBeenCalledTimes(0);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { Logger } from '../types/logger';

export function createNullLogger(): Logger {
return {
debug(_message: string, _args?: any): Promise<void> {
return Promise.resolve();
},
info(_message: string, _args?: any): Promise<void> {
return Promise.resolve();
},
error(_message: string, _args?: any): Promise<void> {
return Promise.resolve();
},
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './createNullLogger';
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export function createTransporter({
hosts,
hostsCache,
baseHeaders,
logger,
baseQueryParameters,
algoliaAgent,
timeouts,
Expand Down Expand Up @@ -174,8 +175,7 @@ export function createTransporter({
* the end user to debug / store stack frames even
* when a retry error does not happen.
*/
// eslint-disable-next-line no-console -- this will be fixed by exposing a `logger` to the transporter
console.log('Retryable failure', stackFrameWithoutCredentials(stackFrame));
logger.info('Retryable failure', stackFrameWithoutCredentials(stackFrame));

/**
* We also store the state of the host in failure cases. If the host, is
Expand Down Expand Up @@ -304,6 +304,7 @@ export function createTransporter({
hostsCache,
requester,
timeouts,
logger,
algoliaAgent,
baseHeaders,
baseQueryParameters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ export * from './cache';
export * from './createClient';
export * from './createIterablePromise';
export * from './host';
export * from './logger';
export * from './requester';
export * from './transporter';
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export const LogLevelEnum: Readonly<Record<string, LogLevelType>> = {
Debug: 1,
Info: 2,
Error: 3,
};

export type LogLevelType = 1 | 2 | 3;

export type Logger = {
/**
* Logs debug messages.
*/
debug: (message: string, args?: any) => Promise<void>;

/**
* Logs info messages.
*/
info: (message: string, args?: any) => Promise<void>;

/**
* Logs error messages.
*/
error: (message: string, args?: any) => Promise<void>;
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Cache } from './cache';
import type { Host } from './host';
import type { Logger } from './logger';
import type { Request, Requester, EndRequest, Response } from './requester';

export type Headers = Record<string, string>;
Expand Down Expand Up @@ -87,6 +88,11 @@ export type TransporterOptions = {
*/
hostsCache: Cache;

/**
* The logger instance to send events of the transporter.
*/
logger: Logger;

/**
* The underlying requester used. Should differ
* depending of the environment where the client
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export default defineWorkspace([
'src/__tests__/cache/null-cache.test.ts',
'src/__tests__/cache/memory-cache.test.ts',
'src/__tests__/create-iterable-promise.test.ts',
'src/__tests__/logger/null-logger.test.ts',
],
name: 'node',
environment: 'node',
Expand All @@ -20,6 +21,7 @@ export default defineWorkspace([
'src/__tests__/cache/fallbackable-cache.test.ts',
'src/__tests__/cache/null-cache.test.ts',
'src/__tests__/create-iterable-promise.test.ts',
'src/__tests__/logger/null-logger.test.ts',
],
name: 'jsdom',
environment: 'jsdom',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './src/logger';
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"name": "@algolia/logger-console",
"version": "5.5.3",
"description": "Promise-based log library using console log.",
"repository": {
"type": "git",
"url": "git://github.com/algolia/algoliasearch-client-javascript.git"
},
"license": "MIT",
"author": "Algolia",
"type": "module",
"files": [
"dist",
"src",
"index.ts"
],
"exports": {
".": {
"types": {
"import": "./dist/logger.d.ts",
"module": "./dist/logger.d.ts",
"require": "./dist/logger.d.cts"
},
"import": "./dist/logger.js",
"module": "./dist/logger.js",
"require": "./dist/logger.cjs"
},
"./src/*": "./src/*.ts"
},
"scripts": {
"build": "yarn clean && yarn tsup",
"clean": "rm -rf ./dist || true",
"test": "vitest --run",
"test:bundle": "publint . && attw --pack ."
},
"devDependencies": {
"@arethetypeswrong/cli": "0.16.4",
"@types/node": "22.5.5",
"jsdom": "25.0.0",
"publint": "0.2.11",
"ts-node": "10.9.2",
"tsup": "8.3.0",
"typescript": "5.6.2",
"vitest": "2.1.1"
},
"dependencies": {
"@algolia/client-common": "5.5.3"
},
"engines": {
"node": ">= 14.0.0"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* eslint no-console: 0 */

import { LogLevelEnum } from '@algolia/client-common';
import { vi, beforeEach, describe, test, expect } from 'vitest';

import { createConsoleLogger } from '../logger';

describe('console logger', () => {
beforeEach(() => {
vi.resetAllMocks();
vi.spyOn(console, 'debug');
vi.spyOn(console, 'info');
vi.spyOn(console, 'error');
});

test('respects log level type debug', async () => {
const logger = createConsoleLogger(LogLevelEnum.Debug);

await logger.debug('foo', {});
await logger.info('foo', {});
await logger.error('foo', {});

expect(console.debug).toHaveBeenCalledTimes(1);
expect(console.info).toHaveBeenCalledTimes(1);
expect(console.error).toHaveBeenCalledTimes(1);
});

test('respects log level type info', async () => {
const logger = createConsoleLogger(LogLevelEnum.Info);

await logger.debug('foo', {});
await logger.info('foo', {});
await logger.error('foo', {});

expect(console.debug).toHaveBeenCalledTimes(0);
expect(console.info).toHaveBeenCalledTimes(1);
expect(console.error).toHaveBeenCalledTimes(1);
});

test('respects log level type error', async () => {
const logger = createConsoleLogger(LogLevelEnum.Error);

await logger.debug('foo', {});
await logger.info('foo', {});
await logger.error('foo', {});

expect(console.debug).toHaveBeenCalledTimes(0);
expect(console.info).toHaveBeenCalledTimes(0);
expect(console.error).toHaveBeenCalledTimes(1);
});
});
Loading
Loading