NAME

Net::API::CPAN - Meta CPAN API

SYNOPSIS

use Net::API::CPAN;
my $cpan = Net::API::CPAN->new(
    api_version => 1,
    ua => HTTP::Promise->new( %options ),
    debug => 4,
) || die( Net::API::CPAN->error, "\n" );
$cpan->api_uri( 'https://api.example.org' );
my $uri = $cpan->api_uri;
$cpan->api_version(1);
my $version = $cpan->api_version;

VERSION

v0.1.0

DESCRIPTION

Net::API::CPAN is a client to issue queries to the MetaCPAN REST API.

Make sure to check out the "TERMINOLOGY" section for the exact meaning of key words used in this documentation.

CONSTRUCTOR

new

This instantiates a new Net::API::CPAN object. This accepts the following options, which can later also be set using their associated method.

METHODS

api_uri

Sets or gets the CPAN API URI to use. This defaults to the Net::API::CPAN constant API_URI followed by the API version, such as:

https://fastapi.metacpan.org/v1

This returns an URI object.

api_version

Sets or gets the CPAN API version. As of 2023-09-01, this can only 1

This returns a scalar object

cache_file

Sets or gets a cache file path to use instead of issuing the HTTP request. This affects how "fetch" works since it does not issue an actual HTTP request, but does not change the rest of the workflow.

Returns a file object or undef if nothing was set.

fetch

This takes an object type, such as author, release, file, etc, and the following options and performs an HttP request to the remote MetaCPAN REST API and return the appropriate data or object.

If an error occurs, this set an error object and return undef in scalar context, and an empty list in list context.

http_request

The latest HTTP::Promise::Request issued to the remote MetaCPAN API server.

http_response

The latest HTTP::Promise::Response received from the remote MetaCPAN API server.

json

Returns a new JSON object.

new_filter

This instantiates a new Net::API::CPAN::Filter, passing whatever arguments were received, and setting the debugging mode too.

API METHODS

activity

# Get all the release activity for author OALDERS in the last 24 months
my $activity_obj = $cpan->activity(
    author => 'OALDERS',
    # distribution => 'HTTP-Message',
    # module => 'HTTP::Message',
    interval => '1M',
) || die( "Error with code: ", $cpan->error->code, " and message: ", $cpan->error->message );

# Get all the release activity that depend on HTTP::Message in the last 24 months
my $activity_obj = $cpan->activity(
    # author => 'OALDERS',
    # distribution => 'HTTP-Message',
    module => 'HTTP::Message',
    interval => '1M',
) || die( "Error with code: ", $cpan->error->code, " and message: ", $cpan->error->message );

This method is used to query the CPAN REST API for the release activity for all, or for a given author, or a given distribution, or a given module dependency. An optional aggregation interval can be stipulated with res and it defaults to 1w (set by the API).

Upon failure, an error will be set and undef will be returned in scalar context, or an empty list in list context.

author

# Retrieves the information details for the specified author
my $author_obj = $cpan->author( 'OALDERS' ) ||
    die( "Error with code: ", $cpan->error->code, " and message: ", $cpan->error->message );

# Retrieves author information details for the specified pause IDs
my $list_obj = $cpan->author( [qw( OALDERS NEILB )] ) ||
    die( "Error with code: ", $cpan->error->code, " and message: ", $cpan->error->message );

# Queries authors information details
my $list_obj = $cpan->author(
    query => 'Olaf',
    from => 10,
    size => 20,
) || die( $cpan->error );

# Queries authors information details using ElasticSearch format
my $list_obj = $cpan->author( $filter_object ) ||
    die( $cpan->error );

# Queries authors information using a prefix
my $list_obj = $cpan->author( prefix => 'O' ) || 
    die( $cpan->error );

# Retrieves authors information using their specified IDs
my $list_obj = $cpan->author( user => [qw( FepgBJBZQ8u92eG_TcyIGQ 6ZuVfdMpQzy75_Mazx2_nw )] ) || 
    die( $cpan->error );

This method is used to query the CPAN REST API for a specific author, a list of authors, or search an author using a query. It takes a string, an array reference, an hash or alternatively an hash reference as possible parameters.

Upon failure, an error will be set and undef will be returned in scalar context, or an empty list in list context.

autocomplete

This takes a string and will issue a query to the endpoint /search/autocomplete to retrieve the result set based on the autocomplete search query specified, such as:

/search/autocomplete?q=HTTP

For example:

my $list_obj = $cpan->autocomplete( 'HTTP' ) || die( $cpan->error );

This would, upon success, return a Net::API::CPAN::List object of Net::API::CPAN::File objects.

You can try it out on CPAN Explorer to see the data returned by the CPAN REST API.

Upon failure, an error will be set and undef will be returned in scalar context, or an empty list in list context.

changes

# Retrieves the specified distribution Changes file content
my $change_obj = $cpan->changes( distribution => 'HTTP-Message' ) ||
    die( $cpan->error );

# Retrieves one or more distribution Changes file details using author and release information
my $change_obj = $cpan->changes(
    author => 'OALDERS',
    release => 'HTTP-Message-6.36'
) || die( $cpan->error );

# Same:
my $change_obj = $cpan->changes( release => 'OALDERS/HTTP-Message-6.36' ) ||
    die( $cpan->error );

# With multiple author and releases
my $list_obj = $cpan->changes(
    author => [qw( OALDERS NEILB )],
    release => [qw( HTTP-Message-6.36 Data-HexDump-0.04 )]
) || die( $cpan->error );

# Same:
my $list_obj = $cpan->changes( release => [qw( OALDERS/HTTP-Message-6.36 NEILB/Data-HexDump-0.04 )] ) ||
    die( $cpan->error );

This method is used to query the CPAN REST API for one or more particular release's Changes (or CHANGES depending on the release) file content.

Upon failure, an error will be set and undef will be returned in scalar context, or an empty list in list context.

clientinfo

This issue a query to the endpoint https://clientinfo.metacpan.org and retrieves the information of the various base URL.

It returns an hash reference with the following structure:

{
    future => {
        domain => "https://fastapi.metacpan.org/",
        url => "https://fastapi.metacpan.org/v1/",
        version => "v1",
    },
    production => {
        domain => "https://fastapi.metacpan.org/",
        url => "https://fastapi.metacpan.org/v1/",
        version => "v1",
    },
    testing => {
        domain => "https://fastapi.metacpan.org/",
        url => "https://fastapi.metacpan.org/v1/",
        version => "v1",
    },
}

Each of the URL is an URL object.

contributor

# Retrieves a list of module contributed to by the specified PauseID
my $list_obj = $cpan->contributor( author => 'OALDERS' ) ||
    die( $cpan->error );

# Retrieves a list of module contributors details
my $list_obj = $cpan->contributor(
    author => 'OALDERS'
    release => 'HTTP-Message-6.37'
) || die( $cpan->error );

This method is used to query the CPAN REST API for either the list of releases a CPAN account has contributed to, or to get the list of contributors for a specified release.

Upon failure, an error will be set and undef will be returned in scalar context, or an empty list in list context.

cover

This method is used to query the CPAN REST API to the endpoint /v1/cover/{release} to get the cover information including distribution name, release name, version and download URL, such as:

/cover/HTTP-Message-6.37

For example:

my $cover_obj = $cpan->cover(
    release => 'HTTP-Message-6.37',
) || die( $cpan->error );

It returns, upon success, a Net::API::CPAN::Cover object.

Upon failure, an error will be set and undef will be returned in scalar context, or an empty list in list context.

diff

# Retrieves a diff of two files with output as JSON
my $diff_obj = $cpan->diff(
    file1 => 'AcREzFgg3ExIrFTURa0QJfn8nto',
    file2 => 'Ies7Ysw0GjCxUU6Wj_WzI9s8ysU',
    # Default
    accept => 'application/json',
) || die( $cpan->error );

# Retrieves a diff of two files with output as plain text
my $diff_text = $cpan->diff(
    file1 => 'AcREzFgg3ExIrFTURa0QJfn8nto',
    file2 => 'Ies7Ysw0GjCxUU6Wj_WzI9s8ysU',
    # Default
    accept => 'text/plain',
) || die( $cpan->error );

# Retrieves a diff of two releases with output as JSON
my $diff_obj = $cpan->diff(
    author1 => 'OALDERS',
    # This is optional if it is the same
    author2 => 'OALDERS',
    release1 => 'HTTP-Message-6.35'
    release2 => 'HTTP-Message-6.36'
    # Default
    accept => 'application/json',
) || die( $cpan->error );

# Retrieves a diff of two releases with output as plain text
my $diff_text = $cpan->diff(
    author1 => 'OALDERS',
    # This is optional if it is the same
    author2 => 'OALDERS',
    release1 => 'HTTP-Message-6.35'
    release2 => 'HTTP-Message-6.36'
    # Default
    accept => 'text/plain',
) || die( $cpan->error );

# Retrieves a diff of the latest release and its previous version with output as JSON
my $diff_obj = $cpan->diff(
    distribution => 'HTTP-Message',
    # Default
    accept => 'application/json',
) || die( $cpan->error );

# Retrieves a diff of the latest release and its previous version with output as plain text
my $diff_text = $cpan->diff(
    distribution => 'HTTP-Message',
    # Default
    accept => 'text/plain',
) || die( $cpan->error );

This method is used to query the CPAN REST API to get the diff output between 2 files, or 2 releases.

Upon failure, an error will be set and undef will be returned in scalar context, or an empty list in list context.

distribution

# Retrieves a distribution information details
my $dist_obj = $cpan->distribution( 'HTTP-Message' ) ||
    die( $cpan->error );

# Queries distribution information details using simple search
my $list_obj = $cpan->distribution(
    query => 'HTTP',
    from => 10,
    size => 10,
) || die( $cpan->error );

# Queries distribution information details using advanced search with ElasticSearch
my $list_obj = $cpan->distribution( $filter_object ) ||
    die( $cpan->error );

This method is used to query the CPAN REST API to retrieve distribution information.

Upon failure, an error will be set and undef will be returned in scalar context, or an empty list in list context.

download_url

# Retrieve the latest release download URL information details
my $dl_obj = $cpan->download_url( 'HTTP::Message' ) ||
    die( $cpan->error );

This method is used to query the CPAN REST API to retrieve the specified module latest release download_url information.

Upon failure, an error will be set and undef will be returned in scalar context, or an empty list in list context.

favorite

# Queries favorites using a simple search
my $list_obj = $cpan->favorite(
    query => 'HTTP',
    from => 10,
    size => 10,
) || die( $cpan->error );

# Queries favorites using a advanced search with ElasticSearch format
my $list_obj = $cpan->favorite( $filter_object ) ||
    die( $cpan->error );

# Retrieves favorites agregate by distributions as an hash reference
# e.g.: HTTP-Message => 63
my $hash_ref = $cpan->favorite( aggregate => 'HTTP-Message' ) ||
    die( $cpan->error );

# Same
my $hash_ref = $cpan->favorite( agg => 'HTTP-Message' ) ||
    die( $cpan->error );

# Same with multiple distributions
my $hash_ref = $cpan->favorite( aggregate => [qw( HTTP-Message Data-HexDump)] ) ||
    die( $cpan->error );

# Same
my $hash_ref = $cpan->favorite( agg => [qw( HTTP-Message Data-HexDump)] ) ||
    die( $cpan->error );

# Retrieves list of users who favorited a distribution as an array reference
# e.g. [ '9nGbVdZ4QhO4Ia5ZhNpjtg', 'c4QLX0YORN6-quL15MGwqg', ... ]
my $array_ref = $cpan->favorite( distribution => 'HTTP-Message' ) ||
    die( $cpan->error );

# Retrieves user favorites information details
my $list_obj = $cpan->favorite( user => 'q_15sjOkRminDY93g9DuZQ' ) ||
    die( $cpan->error );

# Retrieves top favorite distributions a.k.a. leaderboard as an array reference
my $array_ref = $cpan->favorite( leaderboard => 1 ) ||
    die( $cpan->error );

# Retrieves list of recent favorite distribution
my $list_obj = $cpan->favorite( recent => 1 ) ||
    die( $cpan->error );

This method is used to query the CPAN REST API to retrieve favorite information.

Upon failure, an error will be set and undef will be returned in scalar context, or an empty list in list context.

file

# Queries files using simple search
my $list_obj = $cpan->file(
    query => 'HTTP',
    from => 10,
    size => 10,
) || die( $cpan->error );

# Queries files with advanced search using ElasticSearch
my $list_obj = $cpan->file( $filter_object ) ||
    die( $cpan->error );

# Retrieves a directory content
my $list_obj = $cpan->file(
    author => 'OALDERS',
    release => 'HTTP-Message-6.36',
    dir => 'lib/HTTP',
) || die( $cpan->error );

# Retrieves a file information details
my $file_obj = $cpan->file(
    author => 'OALDERS',
    release => 'HTTP-Message-6.36',
    path => 'lib/HTTP/Message.pm',
) || die( $cpan->error );

This method is used to query the CPAN REST API to retrieve file information.

Upon failure, an error will be set and undef will be returned in scalar context, or an empty list in list context.

first

This takes a string and will issue a query to the endpoint /search/first to retrieve the first result found based on the search query specified, such as:

/search/first?q=HTTP

For example:

my $list_obj = $cpan->first( 'HTTP' ) || die( $cpan->error );

This would, upon success, return a Net::API::CPAN::Module object.

You can try it out on CPAN Explorer to see the data returned by the CPAN REST API.

history

# Retrieves the history of a given module
my $list_obj = $cpan->history(
    type => 'module',
    module => 'HTTP::Message',
    path => 'lib/HTTP/Message.pm',
) || die( $cpan->error );

# Retrieves the history of a given distribution file
my $list_obj = $cpan->history(
    type => 'file',
    distribution => 'HTTP-Message',
    path => 'lib/HTTP/Message.pm',
) || die( $cpan->error );

# Retrieves the history of a given module documentation
my $list_obj = $cpan->history(
    type => 'documentation',
    module => 'HTTP::Message',
    path => 'lib/HTTP/Message.pm',
) || die( $cpan->error );

This method is used to query the CPAN REST API to retrieve file history information.

mirror

my $list_obj = $cpan->mirror;

This would return, upon success, a Net::API::CPAN::List object.

Actually there is no mirroring anymore, because for some time now CPAN runs on a CDN (Content Distributed Network) which performs the same result, but transparently.

See more on this here

This endpoint also has search capability, but given there is now only one entry, it is completely useless.

You can try it out on CPAN Explorer to see the data returned by the CPAN REST API.

Upon failure, an error will be set and undef will be returned in scalar context, or an empty list in list context.

module

# Queries modules with a simple search
my $list_obj = $cpan->module(
    query => 'HTTP',
    from => 10,
    size => 10,
) || die( $cpan->error );

# Queries modules with an advanced search using ElasticSearch
my $list_obj = $cpan->module( $filter_object ) ||
    die( $cpan->error );

# Retrieves the specified module information details
my $module_obj = $cpan->module(
    module => 'HTTP::Message',
) || die( $cpan->error );

# And if you want to join with other object types
my $module_obj = $cpan->module(
    module => 'HTTP::Message',
    join => [qw( release author )],
) || die( $cpan->error );

This method is used to query the CPAN REST API to retrieve module information.

Upon failure, an error will be set and undef will be returned in scalar context, or an empty list in list context.

package

# Queries packages with a simple search
my $list_obj = $cpan->package(
    query => 'HTTP',
    from => 10,
    size => 10,
) || die( $cpan->error );

# Queries packages with an advanced search using ElasticSearch
my $list_obj = $cpan->package( $filter_object ) ||
    die( $cpan->error );

# Retrieves the list of a distribution packages
my $list_obj = $cpan->package( distribution => 'HTTP-Message' ) ||
    die( $cpan->error );

# Retrieves the latest release and package information for the specified module
my $package_obj = $cpan->package( 'HTTP::Message' ) ||
    die( $cpan->error );

This method is used to query the CPAN REST API to retrieve package information.

Upon failure, an error will be set and undef will be returned in scalar context, or an empty list in list context.

permission

# Queries permissions with a simple search
my $list_obj = $cpan->permission(
    query => 'HTTP',
    from => 10,
    size => 10,
) || die( $cpan->error );

# Queries permissions with an advanced search using ElasticSearch
my $list_obj = $cpan->permission( $filter_object ) ||
    die( $cpan->error );

# Retrieves permission information details for the specified author
my $list_obj = $cpan->permission(
    author => 'OALDERS',
    from => 40,
    size => 20,
) || die( $cpan->error );

# Retrieves permission information details for the specified module
my $list_obj = $cpan->permission(
    module => 'HTTP::Message',
) || die( $cpan->error );

# Retrieves permission information details for the specified modules
my $list_obj = $cpan->permission(
    module => [qw( HTTP::Message Data::HexDump )],
) || die( $cpan->error );

This method is used to query the CPAN REST API to retrieve package information.

Upon failure, an error will be set and undef will be returned in scalar context, or an empty list in list context.

pod

# Returns the POD of the given module in the 
# specified release in markdown format
my $string = $cpan->pod(
    author => 'OALDERS',
    release => 'HTTP-Message-6.36',
    path => 'lib/HTTP/Message.pm',
    accept => 'text/x-markdown',
) || die( $cpan->error );

# Returns the POD of the given module in 
# markdown format
my $string = $cpan->pod(
    module => 'HTTP::Message',
    accept => 'text/x-markdown',
) || die( $cpan->error );

# Renders the specified POD code into HTML
my $html = $cpan->pod(
    render => qq{=encoding utf-8\n\n=head1 Hello World\n\nSomething here\n\n=oops\n\n=cut\n}
) || die( $cpan->error );

This method is used to query the CPAN REST API to retrieve pod documentation from specified modules and to render pod into HTML data.

Upon failure, an error will be set and undef will be returned in scalar context, or an empty list in list context.

rating

# Queries permissions with a simple search
my $list_obj = $cpan->rating(
    query => 'HTTP',
    from => 10,
    size => 10,
) || die( $cpan->error );

# Queries permissions with an advanced search using ElasticSearch format
my $list_obj = $cpan->rating( $filter_object ) ||
    die( $cpan->error );

# Retrieves rating information details of the specified distribution
my $list_obj = $cpan->rating(
    distribution => 'HTTP-Tiny',
) || die( $cpan->error );

This method is used to query the CPAN REST API to retrieve rating historical data for the specified search query or distribution.

It is worth mentioning that although this endpoint still works, CPAN Ratings has been decommissioned some time ago, and thus its usefulness is questionable.

Upon failure, an error will be set and undef will be returned in scalar context, or an empty list in list context.

release

# Perform a simple query
my $list_obj = $cpan->release(
    query => 'HTTP',
    from => 10,
    size => 10,
) || die( $cpan->error );

# Perform an advanced query using ElasticSearch format
my $list_obj = $cpan->release( $filter_object ) ||
    die( $cpan->error );

# Retrieves a list of all releases for a given author
my $list_obj = $cpan->release(
    all => 'OALDERS',
    page => 2,
    size => 100,
) || die( $cpan->error );

# Retrieves a shorter list of all releases for a given author
my $list_obj = $cpan->release( author => 'OALDERS' ) ||
    die( $cpan->error );

# Retrieve a release information details
my $release_obj = $cpan->release(
    author => 'OALDERS',
    release => 'HTTP-Message-6.36',
) || die( $cpan->error );

# Retrieves the latest distribution release information details
my $release_obj = $cpan->release(
    distribution => 'HTTP-Message',
) || die( $cpan->error );

# Retrieves the list of contributors for the specified distributions
my $list_obj = $cpan->release(
    author => 'OALDERS',
    release => 'HTTP-Message-6.36',
    contributors => 1,
) || die( $cpan->error );

# Retrieves the list of release key files by category
my $hash_ref = $cpan->release(
    author => 'OALDERS',
    release => 'HTTP-Message-6.36',
    files => 1,
) || die( $cpan->error );

# Retrieves the list of interesting files for the given release
my $list_obj = $cpan->release(
    author => 'OALDERS',
    release => 'HTTP-Message-6.36',
    # You can also use just 'interesting'
    interesting_files => 1,
) || die( $cpan->error );

# Get latest releases by the specified author
my $list_obj = $cpan->release(
    author => 'OALDERS',
    latest => 1,
) || die( $cpan->error );

# Get the latest releases for the specified distribution
my $release_obj = $cpan->release(
    distribution => 'HTTP-Message',
    latest => 1,
) || die( $cpan->error );

# Retrieves the list of modules in the specified release
my $list_obj = $cpan->release(
    author => 'OALDERS',
    release => 'HTTP-Message-6.36',
    modules => 1,
) || die( $cpan->error );

# Get the list of recent releases
my $list_obj = $cpan->release(
    recent => 1,
) || die( $cpan->error );

# get all releases by versions for the specified distribution
my $list_obj = $cpan->release(
    versions => 'HTTP-Message',
) || die( $cpan->error );

This method is used to query the CPAN REST API to retrieve release information.

Upon failure, an error will be set and undef will be returned in scalar context, or an empty list in list context.

reverse

# Returns a list of all the modules who depend on the specified distribution
my $list_obj = $cpan->reverse( distribution => 'HTTP-Message' ) ||
    die( $cpan->error );

# Returns a list of all the modules who depend on the specified module
my $list_obj = $cpan->reverse( module => 'HTTP::Message' ) ||
    die( $cpan->error );

This method is used to query the CPAN REST API to retrieve reverse dependencies, i.e. releases on CPAN that depend on the specified distribution or module.

Upon failure, an error will be set and undef will be returned in scalar context, or an empty list in list context.

reverse_dependencies

This is an alias for "reverse"

Provided with an hash or hash reference of options and this performs a search query and returns a Net::API::CPAN::List object, or an Net::API::CPAN::Scroll depending on the type of search query requested.

There are 3 types of search query:

source

# Retrieves the source code of the given module path within the specified release
my $string = $cpan->source(
    author => 'OALDERS',
    release => 'HTTP-Message-6.36',
    path => 'lib/HTTP/Message.pm',
) || die( $cpan->error );

# Retrieves the full source of the latest, authorized version of the specified module
my $string = $cpan->source( module => 'HTTP::Message' ) ||
    die( $cpan->error );

This method is used to query the CPAN REST API to retrieve the source code or data of the specified release element or module.

Upon failure, an error will be set and undef will be returned in scalar context, or an empty list in list context.

suggest

This takes a string and will issue a query to the endpoint /search/autocomplete/suggest to retrieve the suggested result set based on the autocomplete search query, such as:

/search/autocomplete/suggest?q=HTTP

For example:

my $list_obj = $cpan->suggest( query => 'HTTP' ) || die( $cpan->error );

This would, upon success, return a Net::API::CPAN::List object of Net::API::CPAN::Release::Suggest objects.

You can try it out on CPAN Explorer to see the data returned by the CPAN REST API.

top_uploaders

This will issue a query to the endpoint /release/top_uploaders to retrieve an hash object of the top uploading authors with the total as the key's value, such as:

/release/top_uploaders

For example:

my $hash_ref = $cpan->top_uploaders || die( $cpan->error );

This would return, upon success, an hash object of author and their recent total number of release upload on CPAN

For example:

{
    OALDERS => 12,
    NEILB => 7,
}

The following options are also supported:

You can try it out on CPAN Explorer to see the data returned by the CPAN REST API.

Upon failure, an error will be set and undef will be returned in scalar context, or an empty list in list context.

web

This takes a string and will issue a query to the endpoint /search/web to retrieve the result set based on the search query specified similar to the one on the MetaCPAN website, such as:

/search/web?q=HTTP

For example:

my $list_obj = $cpan->web(
    query => 'HTTP',
    from => 0,
    size => 10,
) || die( $cpan->error );

This would, upon success, return a Net::API::CPAN::List object of Net::API::CPAN::Module objects.

Search terms can be:

The following options are also supported:

You can try it out on CPAN Explorer to see the data returned by the CPAN REST API.

Upon failure, an error will be set and undef will be returned in scalar context, or an empty list in list context.

TERMINOLOGY

The MetaCPAN REST API has quite a few endpoints returning sets of data containing properties. Below are the meanings of some of those keywords:

ERRORS

This module does not die or croak, but instead set an error object using "error" in Module::Generic and returns undef in scalar context, or an empty list in list context.

You can retrieve the latest error object set by calling error inherited from Module::Generic

Errors issued by this distributions are all instances of class Net::API::CPAN::Exception

METACPAN OPENAPI SPECIFICATIONS

From the information I could gather, I have produced the specifications for Open API v3.0.0 for your reference. You can also find it here in JSON format.

AUTHOR

Jacques Deguest <jack@deguest.jp>

SEE ALSO

Meta CPAN API documentation

https://metacpan.org/, https://www.cpan.org/

Net::API::CPAN::Activity, Net::API::CPAN::Author, Net::API::CPAN::Changes, Net::API::CPAN::Changes::Release, Net::API::CPAN::Contributor, Net::API::CPAN::Cover, Net::API::CPAN::Diff, Net::API::CPAN::Distribution, Net::API::CPAN::DownloadUrl, Net::API::CPAN::Favorite, Net::API::CPAN::File, Net::API::CPAN::Module, Net::API::CPAN::Package, Net::API::CPAN::Permission, Net::API::CPAN::Rating, Net::API::CPAN::Release

Net::API::CPAN::Filter, Net::API::CPAN::List, Net::API::CPAN::Scroll

Net::API::CPAN::Mock

COPYRIGHT & LICENSE

Copyright(c) 2023 DEGUEST Pte. Ltd.

All rights reserved

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.