Ryuno-Ki / eleventy-filter-npm-package-downloads

Filter for 11ty to show the number of downloads of a npm package

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Tweak package so the user can provide a URL and fetch data from an API

alex-page opened this issue · comments

This package is really great but it could be more flexible to allow the user to get any data from an API. The user could provide a url:

https://api.npmjs.org/downloads/point/last-week/a11ycolor
https://api.github.com/repos/alex-page/alex-page

The function would then return the body, they can then take the data out that they need.

Below is two examples of fetching data from two different sources. This could be one function to simplify the process:

/**
 * Get the npm package downloads
 */
eleventyConfig.addNunjucksAsyncFilter( "packageDownloads", async( packageName, callback ) => {
	try {
		const url = `https://api.npmjs.org/downloads/point/last-week/${ packageName }`;
		const { body } = await Got( url );
		const downloads = JSON.parse( body ).downloads;
		callback( null, downloads );
	}
	catch( error ){
		callback( error );
	}
});

/**
 * Get the GitHub stars
 */
eleventyConfig.addNunjucksAsyncFilter( "githubStars", async( repoName, callback ) => {
	try {
		const url = `https://api.github.com/repos/${ repoName }`;
		const { body } = await Got( url );
		const totalStars = JSON.parse( body ).stargazers_count;
		callback( null, totalStars );
	}
	catch( error ){
		callback( error );
	}
});

Example function, you would need to use something like lodash got to get the nested data from the body object using the keypath:

/**
 * Fetch from URL
 */
eleventyConfig.addNunjucksAsyncFilter( "fetch", async( url, keypath, callback ) => {
	try {
		const { body } = await Got( url );
		callback( null, body );
	}
	catch( error ){
		callback( error );
	}
});

The user could then access the data like so:

{{ 'https://api.npmjs.org/downloads/point/last-week/a11ycolor' | fetch( 'stargazers_count' ) }}
{{ 'https://api.github.com/repos/alex-page/alex-page' | fetch( 'downloads' ) }}
{{ 'https://api.github.com/repos/alex-page/alex-page' | fetch( 'license.name' ) }}

@Ryuno-Ki i have updated the issue, let me know if you have questions.

Hi @alex-page,
thanks for your interest.

I'd suggest to move the GitHub API functionality into a separate package and use @octokit/rest:

{{ 'alex-page/alex-page' | github('downloads') }}
{{ 'alex-page/alex-page' | github('license.name') }}

Looking at nunjucks async filter doc the .eleventy.js would be configured like so:

module.exports = function(eleventyConfig) {
  eleventyConfig.addNunjucksAsyncFilter("github", function(orgAndRepo, apiPart, callback) {
    callToOctokit().then((results) => callback(null, results));
  });
};

(I already have something with @octokit running on my own website)
I feel that this will get unmaintainable quite fast. Just think about it. Next request would be about CPAN, then crates.io or rubygems.org or pypi.org or …
Better to keep those separated IMHO.

What that work for you?

Sounds good to me