Skip to content

Commit

Permalink
feat(clerk-js,shared): Custom logger to enable logging once per sessi…
Browse files Browse the repository at this point in the history
…on (#3383)
  • Loading branch information
desiprisg authored May 22, 2024
1 parent 7fca4a5 commit ff31f72
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 6 deletions.
6 changes: 6 additions & 0 deletions .changeset/clean-kings-brake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@clerk/clerk-js': patch
'@clerk/shared': patch
---

Add a custom logger to allow logging a message or warning to the console once per session, in order to avoid consecutive identical logs due to component rerenders.
3 changes: 2 additions & 1 deletion packages/clerk-js/src/utils/__tests__/url.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { logger } from '@clerk/shared/logger';
import type { SignUpResource } from '@clerk/types';

import {
Expand Down Expand Up @@ -473,7 +474,7 @@ describe('isAllowedRedirectOrigin', () => {
['https://test.clerk.com/foo?hello=1', [/https:\/\/www\.clerk\.com/], false],
];

const warnMock = jest.spyOn(global.console, 'warn').mockImplementation();
const warnMock = jest.spyOn(logger, 'warnOnce');

beforeEach(() => warnMock.mockClear());
afterAll(() => warnMock.mockRestore());
Expand Down
6 changes: 4 additions & 2 deletions packages/clerk-js/src/utils/assertNoLegacyProp.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { logger } from '@clerk/shared/logger';

export function assertNoLegacyProp(props: Record<string, any>) {
const legacyProps = ['redirectUrl', 'afterSignInUrl', 'afterSignUpUrl', 'after_sign_in_url', 'after_sign_up_url'];
const legacyProp = Object.keys(props).find(key => legacyProps.includes(key));

if (legacyProp && props[legacyProp]) {
// TODO: @nikos update with the docs link
console.warn(
logger.warnOnce(
`Clerk: The prop "${legacyProp}" is deprecated and should be replaced with the new "fallbackRedirectUrl" or "forceRedirectUrl" props instead.`,
);
}
Expand All @@ -18,7 +20,7 @@ export function warnForNewPropShadowingLegacyProp(
) {
if (newValue && legacyValue) {
// TODO: @nikos update with the docs link
console.warn(
logger.warnOnce(
`Clerk: The "${newKey}" prop ("${newValue}") has priority over the legacy "${legacyKey}" (or "redirectUrl") ("${legacyValue}"), which will be completely ignored in this case. "${legacyKey}" (or "redirectUrl" prop) should be replaced with the new "fallbackRedirectUrl" or "forceRedirectUrl" props instead.`,
);
}
Expand Down
5 changes: 3 additions & 2 deletions packages/clerk-js/src/utils/url.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { globs } from '@clerk/shared/globs';
import { createDevOrStagingUrlCache } from '@clerk/shared/keys';
import { logger } from '@clerk/shared/logger';
import { camelToSnake } from '@clerk/shared/underscore';
import { isCurrentDevAccountPortalOrigin, isLegacyDevAccountPortalOrigin } from '@clerk/shared/url';
import type { SignUpResource } from '@clerk/types';
Expand Down Expand Up @@ -116,7 +117,7 @@ export function buildURL(params: BuildURLParams, options: BuildURLOptions<boolea
// Merge search params from hashSearch string
const searchParamsFromHashSearchString = getQueryParams(hashSearch || '');
for (const [key, val] of Object.entries(searchParamsFromHashSearchString)) {
dummyUrlForHash.searchParams.append(key, val as string);
dummyUrlForHash.searchParams.append(key, val);
}

// Merge search params from the hashSearchParams object
Expand Down Expand Up @@ -354,7 +355,7 @@ export const isAllowedRedirectOrigin =
.some(origin => origin.test(trimTrailingSlash(url.origin)));

if (!isAllowed) {
console.warn(
logger.warnOnce(
`Clerk: Redirect URL ${url} is not on one of the allowedRedirectOrigins, falling back to the default redirect URL.`,
);
}
Expand Down
3 changes: 2 additions & 1 deletion packages/shared/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@
"constants",
"apiUrlFromPublishableKey",
"scripts",
"telemetry"
"telemetry",
"logger"
],
"scripts": {
"build": "tsup",
Expand Down
33 changes: 33 additions & 0 deletions packages/shared/src/__tests__/logger.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { logger } from '../logger';

describe('logger', () => {
describe('warnOnce', () => {
const warnMock = jest.spyOn(global.console, 'warn').mockImplementation();

beforeEach(() => warnMock.mockClear());
afterAll(() => warnMock.mockRestore());

test('warns only once per session', () => {
logger.warnOnce('testwarn');
logger.warnOnce('testwarn');
logger.warnOnce('testwarn');

expect(warnMock).toHaveBeenCalledTimes(1);
});
});

describe('logOnce', () => {
const logMock = jest.spyOn(global.console, 'log').mockImplementation();

beforeEach(() => logMock.mockClear());
afterAll(() => logMock.mockRestore());

test('logs only once per session', () => {
logger.logOnce('testlog');
logger.logOnce('testlog');
logger.logOnce('testlog');

expect(logMock).toHaveBeenCalledTimes(1);
});
});
});
1 change: 1 addition & 0 deletions packages/shared/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ export * from './proxy';
export * from './underscore';
export * from './url';
export * from './object';
export * from './logger';
export { createWorkerTimers } from './workerTimers';
export { DEV_BROWSER_JWT_KEY, extractDevBrowserJWTFromURL, setDevBrowserJWTInURL } from './devBrowser';
24 changes: 24 additions & 0 deletions packages/shared/src/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const loggedMessages: Set<string> = new Set();

export const logger = {
/**
* A custom logger that ensures messages are logged only once.
* Reduces noise and duplicated messages when logs are in a hot codepath.
*/
warnOnce: (msg: string) => {
if (loggedMessages.has(msg)) {
return;
}

loggedMessages.add(msg);
console.warn(msg);
},
logOnce: (msg: string) => {
if (loggedMessages.has(msg)) {
return;
}

console.log(msg);
loggedMessages.add(msg);
},
};
1 change: 1 addition & 0 deletions packages/shared/subpaths.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const subpathNames = [
'constants',
'apiUrlFromPublishableKey',
'telemetry',
'logger',
];

export const subpathFoldersBarrel = ['react'];
Expand Down

0 comments on commit ff31f72

Please sign in to comment.