Skip to content

Commit

Permalink
feat(ts): use jsdelivr to check for d.ts (#645)
Browse files Browse the repository at this point in the history
  • Loading branch information
Samuel Bodin committed Jul 5, 2021
1 parent dd386d2 commit fbe2e97
Show file tree
Hide file tree
Showing 13 changed files with 183 additions and 281 deletions.
2 changes: 1 addition & 1 deletion src/@types/pkg.ts
Expand Up @@ -25,7 +25,7 @@ export interface GithubRepo {

export type TsType =
| {
ts: 'included' | false | { possible: true; dtsMain: string };
ts: 'included' | false | { possible: true };
}
| {
ts: 'definitely-typed';
Expand Down
7 changes: 0 additions & 7 deletions src/__tests__/__snapshots__/formatPkg.test.ts.snap
Expand Up @@ -65,7 +65,6 @@ Object {
},
"types": Object {
"ts": Object {
"dtsMain": "index.d.ts",
"possible": true,
},
},
Expand Down Expand Up @@ -881,7 +880,6 @@ Are you in trouble? Read through our [contribution guidelines](https://bitbucket
},
"types": Object {
"ts": Object {
"dtsMain": "dist/bundle.d.ts",
"possible": true,
},
},
Expand Down Expand Up @@ -1022,7 +1020,6 @@ Object {
},
"types": Object {
"ts": Object {
"dtsMain": "dist/atomic-package.tab.d.ts",
"possible": true,
},
},
Expand Down Expand Up @@ -1154,7 +1151,6 @@ Object {
},
"types": Object {
"ts": Object {
"dtsMain": "index.d.ts",
"possible": true,
},
},
Expand Down Expand Up @@ -1242,7 +1238,6 @@ index(arr, obj);
},
"types": Object {
"ts": Object {
"dtsMain": "index.d.ts",
"possible": true,
},
},
Expand Down Expand Up @@ -1418,7 +1413,6 @@ Thank you so much for contributing!!
},
"types": Object {
"ts": Object {
"dtsMain": "prism.d.ts",
"possible": true,
},
},
Expand Down Expand Up @@ -1520,7 +1514,6 @@ Object {
"tags": undefined,
"types": Object {
"ts": Object {
"dtsMain": "index.d.ts",
"possible": true,
},
},
Expand Down
119 changes: 54 additions & 65 deletions src/__tests__/changelog.test.ts
@@ -1,5 +1,4 @@
import { getChangelogs, baseUrlMap, getChangelog } from '../changelog';
import * as jsDelivr from '../jsDelivr';

jest.mock('got', () => {
const gotSnapshotUrls = new Set([
Expand All @@ -17,12 +16,6 @@ jest.mock('got', () => {
};
});

const spy = jest
.spyOn(jsDelivr, 'getFilesList')
.mockImplementation((): Promise<any[]> => {
return Promise.resolve([]);
});

describe('should test baseUrlMap', () => {
it('should work with paths', () => {
const bitbucketRepo = {
Expand Down Expand Up @@ -116,7 +109,7 @@ it('should handle not found changelog for github', async () => {
},
};

const [{ changelogFilename }] = await getChangelogs([pkg]);
const [{ changelogFilename }] = await getChangelogs([pkg], []);
expect(changelogFilename).toBe(null);
});

Expand All @@ -135,7 +128,7 @@ it('should get changelog for github', async () => {
},
};

const [{ changelogFilename }] = await getChangelogs([pkg]);
const [{ changelogFilename }] = await getChangelogs([pkg], []);
expect(changelogFilename).toBe(
'https://raw.githubusercontent.com/algolia/algoliasearch-netlify/master/CHANGELOG.md'
);
Expand All @@ -148,7 +141,7 @@ it('should get changelog from unpkg if there is no repository field', async () =
repository: null,
};

const [{ changelogFilename }] = await getChangelogs([pkg]);
const [{ changelogFilename }] = await getChangelogs([pkg], []);

expect(changelogFilename).toBe(
'https://unpkg.com/@atlaskit/button@13.3.7/CHANGELOG.md'
Expand All @@ -170,7 +163,7 @@ it('should get changelog for gitlab', async () => {
},
};

const [{ changelogFilename }] = await getChangelogs([pkg]);
const [{ changelogFilename }] = await getChangelogs([pkg], []);
expect(changelogFilename).toBe(
'https://gitlab.com/janslow/gitlab-fetch/raw/master/CHANGELOG.md'
);
Expand All @@ -191,7 +184,7 @@ it('should get changelog for bitbucket', async () => {
},
};

const [{ changelogFilename }] = await getChangelogs([pkg]);
const [{ changelogFilename }] = await getChangelogs([pkg], []);
expect(changelogFilename).toBe(
'https://bitbucket.org/atlassian/aui/raw/master/changelog.md'
);
Expand All @@ -212,81 +205,77 @@ it('should work with HISTORY.md', async () => {
},
};

const [{ changelogFilename }] = await getChangelogs([pkg]);
const [{ changelogFilename }] = await getChangelogs([pkg], []);
expect(changelogFilename).toBe(
'https://raw.githubusercontent.com/expressjs/body-parser/master/HISTORY.md'
);
});

describe('jsDelivr', () => {
it('should early return when finding changelog', async () => {
spy.mockResolvedValue([
{ name: '/package.json', hash: '', time: '1', size: 1 },
{ name: '/CHANGELOG.md', hash: '', time: '1', size: 1 },
]);

const { changelogFilename } = await getChangelog({
name: 'foo',
version: '1.0.0',
repository: {
url: '',
host: 'github.com',
user: 'expressjs',
project: 'body-parser',
path: '',
head: 'master',
branch: 'master',
const { changelogFilename } = await getChangelog(
{
name: 'foo',
version: '1.0.0',
repository: {
url: '',
host: 'github.com',
user: 'expressjs',
project: 'body-parser',
path: '',
head: 'master',
branch: 'master',
},
},
});
expect(jsDelivr.getFilesList).toHaveBeenCalled();
[
{ name: '/package.json', hash: '', time: '1', size: 1 },
{ name: '/CHANGELOG.md', hash: '', time: '1', size: 1 },
]
);
expect(changelogFilename).toEqual(
'https://cdn.jsdelivr.net/npm/foo@1.0.0/CHANGELOG.md'
);
});

it('should early return when finding changelog in nested file', async () => {
spy.mockResolvedValue([
{ name: '/pkg/CHANGELOG.md', hash: '', time: '1', size: 1 },
]);

const { changelogFilename } = await getChangelog({
name: 'foo',
version: '1.0.0',
repository: {
url: '',
host: 'github.com',
user: 'expressjs',
project: 'body-parser',
path: '',
head: 'master',
branch: 'master',
const { changelogFilename } = await getChangelog(
{
name: 'foo',
version: '1.0.0',
repository: {
url: '',
host: 'github.com',
user: 'expressjs',
project: 'body-parser',
path: '',
head: 'master',
branch: 'master',
},
},
});
expect(jsDelivr.getFilesList).toHaveBeenCalled();
[{ name: '/pkg/CHANGELOG.md', hash: '', time: '1', size: 1 }]
);
expect(changelogFilename).toEqual(
'https://cdn.jsdelivr.net/npm/foo@1.0.0/pkg/CHANGELOG.md'
);
});

it('should not register a file looking like a changelog', async () => {
spy.mockResolvedValue([
{ name: '/dist/changelog.js', hash: '', time: '1', size: 1 },
]);

const { changelogFilename } = await getChangelog({
name: 'foo',
version: '1.0.0',
repository: {
url: '',
host: 'github.com',
user: 'hello',
project: 'foo',
path: '',
head: 'master',
branch: 'master',
const { changelogFilename } = await getChangelog(
{
name: 'foo',
version: '1.0.0',
repository: {
url: '',
host: 'github.com',
user: 'hello',
project: 'foo',
path: '',
head: 'master',
branch: 'master',
},
},
});
expect(jsDelivr.getFilesList).toHaveBeenCalled();
[{ name: '/dist/changelog.js', hash: '', time: '1', size: 1 }]
);
expect(changelogFilename).toEqual(null);
});
});
35 changes: 0 additions & 35 deletions src/__tests__/formatPkg.test.ts
Expand Up @@ -245,41 +245,6 @@ describe('adds TypeScript information', () => {
})
).toEqual(expect.objectContaining({ types: { ts: 'included' } }));
});

it('adds types possible if we can find a main file', () => {
expect(
formatPkg({
...BASE,
name: 'xxx',
main: 'main.js',
})
).toEqual(
expect.objectContaining({
types: { ts: { possible: true, dtsMain: 'main.d.ts' } },
})
);

expect(
formatPkg({
...BASE,
name: 'xxx',
})
).toEqual(
expect.objectContaining({
types: { ts: { possible: true, dtsMain: 'index.d.ts' } },
})
);
});

it('gives up when no main is not js', () => {
expect(
formatPkg({
...BASE,
name: 'xxx',
main: 'shell-script.sh',
})
).toEqual(expect.objectContaining({ types: { ts: false } }));
});
});

describe('getRepositoryInfo', () => {
Expand Down
29 changes: 18 additions & 11 deletions src/changelog.ts
Expand Up @@ -95,23 +95,25 @@ async function raceFromPaths(files: string[]): Promise<{
}

export async function getChangelog(
pkg: Pick<RawPkg, 'repository' | 'name' | 'version'>
pkg: Pick<RawPkg, 'repository' | 'name' | 'version'>,
filelist: jsDelivr.File[]
): Promise<{
changelogFilename: string | null;
}> {
// Do a quick call to jsDelivr
// Only work if the package has published their changelog along with the code
const filesList = await jsDelivr.getFilesList(pkg);
for (const file of filesList) {
for (const file of filelist) {
const name = path.basename(file.name);
if (!fileRegex.test(name)) {
// eslint-disable-next-line no-continue
continue;
}

datadog.increment('jsdelivr.getChangelog.hit');

return { changelogFilename: jsDelivr.getFullURL(pkg, file) };
}

datadog.increment('jsdelivr.getChangelog.miss');

const { repository, name, version } = pkg;

// Rollback to brute-force the source code
Expand All @@ -120,19 +122,19 @@ export async function getChangelog(
);

if (repository === null) {
return raceFromPaths(unpkgFiles);
return await raceFromPaths(unpkgFiles);
}

const user = repository.user || '';
const project = repository.project || '';
const host = repository.host || '';
if (user.length < 1 || project.length < 1) {
return raceFromPaths(unpkgFiles);
return await raceFromPaths(unpkgFiles);
}

// Check if we know how to handle this host
if (!baseUrlMap.has(host)) {
return raceFromPaths(unpkgFiles);
return await raceFromPaths(unpkgFiles);
}

const baseUrl = baseUrlMap.get(host)!(repository);
Expand All @@ -141,19 +143,24 @@ export async function getChangelog(
[baseUrl.replace(/\/$/, ''), file].join('/')
);

return raceFromPaths([...files, ...unpkgFiles]);
return await raceFromPaths([...files, ...unpkgFiles]);
}

export async function getChangelogs(
pkgs: Array<Pick<RawPkg, 'repository' | 'name' | 'version'>>
pkgs: Array<Pick<RawPkg, 'repository' | 'name' | 'version'>>,
filelists: jsDelivr.File[][]
): Promise<
Array<{
changelogFilename: string | null;
}>
> {
const start = Date.now();

const all = await Promise.all(pkgs.map(getChangelog));
const all = await Promise.all(
pkgs.map((pkg, index) => {
return getChangelog(pkg, filelists[index] || []);
})
);

datadog.timing('changelogs.getChangelogs', Date.now() - start);
return all;
Expand Down

0 comments on commit fbe2e97

Please sign in to comment.