Skip to content

Commit

Permalink
Merge branch 'main' into chore/dotnet8-support
Browse files Browse the repository at this point in the history
  • Loading branch information
AndriiAndreiev authored Nov 15, 2024
2 parents 749b349 + 42a610e commit 31c6be4
Show file tree
Hide file tree
Showing 11 changed files with 485 additions and 619 deletions.
208 changes: 107 additions & 101 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"dependencies": {
"content-type": "^1.0.5",
"find-cache-dir": "^3.3.2",
"flat-cache": "^3.0.4",
"flat-cache": "^6.1.1",
"lodash": "^4.17.15",
"ssri": "^12.0.0",
"timeout-signal": "^1.1.0",
Expand Down
12 changes: 7 additions & 5 deletions packages/node/src/lib/get-project-base-url.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import crypto from 'crypto';

import findCacheDir from 'find-cache-dir';
import flatCache from 'flat-cache';
import { FlatCache } from 'flat-cache';
import timeoutSignal from 'timeout-signal';

import pkg from '../../package.json';
import config from '../config';

import { logger } from './logger';

export const cache = new FlatCache();

export function getCache(readmeApiKey: string) {
const encodedApiKey = Buffer.from(`${readmeApiKey}:`).toString('base64');
const cacheDir = findCacheDir({ name: pkg.name, create: true });
Expand All @@ -18,16 +20,16 @@ export function getCache(readmeApiKey: string) {
// automatically get refreshed when the package is updated/installed.
const cacheKey = `${pkg.name}-${pkg.version}-${fsSafeApikey}`;

return flatCache.load(cacheKey, cacheDir);
return cache.load(cacheKey, cacheDir);
}

export async function getProjectBaseUrl(readmeApiKey: string, requestTimeout = config.timeout): Promise<string> {
const encodedApiKey = Buffer.from(`${readmeApiKey}:`).toString('base64');

const cache = getCache(readmeApiKey);
getCache(readmeApiKey);
// Does the cache exist? If it doesn't, let's fill it. If it does, let's see if it's stale. Caches should have a TTL
// of 1 day.
const lastUpdated = cache.getKey('lastUpdated');
const lastUpdated = cache.getKey<number>('lastUpdated');

if (
lastUpdated === undefined ||
Expand Down Expand Up @@ -76,7 +78,7 @@ export async function getProjectBaseUrl(readmeApiKey: string, requestTimeout = c

return baseUrl;
}
const cachedBaseUrl = cache.getKey('baseUrl');
const cachedBaseUrl = cache.getKey<string>('baseUrl');
logger.verbose({ message: 'Retrieved baseUrl from cache.', args: { baseUrl: cachedBaseUrl } });
return cachedBaseUrl;
}
10 changes: 5 additions & 5 deletions packages/node/test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { describe, afterAll, beforeEach, afterEach, expect, it } from 'vitest';
import pkg from '../package.json';
import * as readmeio from '../src';
import config from '../src/config';
import { getCache } from '../src/lib/get-project-base-url';
import { getCache, cache } from '../src/lib/get-project-base-url';
import { setBackoff } from '../src/lib/metrics-log';

import getReadMeApiMock from './helpers/getReadMeApiMock';
Expand Down Expand Up @@ -60,7 +60,7 @@ function doMetricsHeadersMatch(headers: Headers) {
describe('#metrics', function () {
beforeEach(function () {
server.listen();
const cache = getCache(apiKey);
getCache(apiKey);

cache.setKey('lastUpdated', Date.now());
cache.setKey('baseUrl', 'https://docs.example.com');
Expand All @@ -69,7 +69,7 @@ describe('#metrics', function () {

afterEach(function () {
server.resetHandlers();
getCache(apiKey).destroy();
cache.destroy();
});

// Close server after all tests
Expand Down Expand Up @@ -146,7 +146,7 @@ describe('#metrics', function () {
app = express();
app.use((req, res, next) => {
const logId = readmeio.log(apiKey, req, res, incomingGroup, { logger: mockLogger });
res.setHeader('x-log-id', logId);
res.setHeader('x-log-id', logId!);
return next();
});
app.get('/test', (req, res) => res.sendStatus(200));
Expand Down Expand Up @@ -531,7 +531,7 @@ describe('#metrics', function () {
it('should fetch the `baseLogUrl` if not passed', function () {
expect.assertions(1);
// Invalidating the cache so we do a fetch from the API
const cache = getCache(apiKey);
getCache(apiKey);
const lastUpdated = new Date();
lastUpdated.setDate(lastUpdated.getDate() - 2);
cache.setKey('lastUpdated', lastUpdated.getTime());
Expand Down
25 changes: 13 additions & 12 deletions packages/node/test/lib/get-project-base-url.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { describe, beforeAll, afterAll, afterEach, expect, it } from 'vitest';

import { getProjectBaseUrl } from '../../src';
import config from '../../src/config';
import { getCache } from '../../src/lib/get-project-base-url';
import { getCache, cache } from '../../src/lib/get-project-base-url';
import getReadMeApiMock from '../helpers/getReadMeApiMock';

const apiKey = 'mockReadMeApiKey';
Expand All @@ -15,7 +15,7 @@ const restHandlers = [getReadMeApiMock(baseLogUrl)];
const server = setupServer(...restHandlers);

function hydrateCache(lastUpdated: number) {
const cache = getCache(apiKey);
getCache(apiKey);

cache.setKey('lastUpdated', lastUpdated);
cache.setKey('baseUrl', baseLogUrl);
Expand All @@ -30,7 +30,8 @@ describe('get-project-base-url', function () {
afterEach(function () {
server.resetHandlers();

getCache(apiKey).destroy();
getCache(apiKey);
cache.destroy();
});

// Close server after all tests
Expand All @@ -40,26 +41,26 @@ describe('get-project-base-url', function () {

it('should not call the API for project data if the cache is fresh', async function () {
await getProjectBaseUrl(apiKey, 2000);
expect(getCache(apiKey).getKey('baseUrl')).toStrictEqual(baseLogUrl);
const lastUpdated = getCache(apiKey).getKey('lastUpdated');
expect(cache.getKey('baseUrl')).toStrictEqual(baseLogUrl);
const lastUpdated = cache.getKey('lastUpdated');
await getProjectBaseUrl(apiKey, 2000);
expect(getCache(apiKey).getKey('lastUpdated')).toStrictEqual(lastUpdated);
expect(cache.getKey('lastUpdated')).toStrictEqual(lastUpdated);
});

it('should populate the cache if not present', async function () {
await getProjectBaseUrl(apiKey, 2000);
expect(getCache(apiKey).getKey('baseUrl')).toStrictEqual(baseLogUrl);
expect(cache.getKey('baseUrl')).toStrictEqual(baseLogUrl);
});

it('should refresh the cache if stale', async function () {
// Hydrate and postdate the cache to two days ago so it'll be seen as stale.
hydrateCache(Math.round(Date.now() / 1000 - 86400 * 2));
expect(getCache(apiKey).getKey('baseUrl')).toStrictEqual(baseLogUrl);
expect(cache.getKey('baseUrl')).toStrictEqual(baseLogUrl);

const lastUpdated = getCache(apiKey).getKey('lastUpdated');
const lastUpdated = cache.getKey('lastUpdated');
await getProjectBaseUrl(apiKey, 2000);
expect(getCache(apiKey).getKey('baseUrl')).toStrictEqual(baseLogUrl);
expect(getCache(apiKey).getKey('lastUpdated')).not.toStrictEqual(lastUpdated);
expect(cache.getKey('baseUrl')).toStrictEqual(baseLogUrl);
expect(cache.getKey('lastUpdated')).not.toStrictEqual(lastUpdated);
});

it('should temporarily set baseUrl to null if the call to the ReadMe API fails for whatever reason', async function () {
Expand All @@ -80,6 +81,6 @@ describe('get-project-base-url', function () {
);

await getProjectBaseUrl(apiKey, 2000);
expect(getCache(apiKey).getKey('baseUrl')).toBeNull();
expect(cache.getKey('baseUrl')).toBeNull();
});
});
Loading

0 comments on commit 31c6be4

Please sign in to comment.