npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

wenova-address

v1.1.0

Published

WENOVA Link Address Plugin SDK for provinces, districts, and villages

Downloads

181

Readme

wenova-address

Address plugin SDK for WENOVA Link (Province, District, Village).

Use this package to connect your app to WENOVA Link Address data.

If you want to start using this service, please visit https://microservices.wenova.fun/.

Full interactive docs (including SMS OTP): https://microservices.wenova.fun/documentation — section wenova-address.

Note: pluginKey is required on every call. It is sent to the API as query parameter key.

Accepted pluginKey values

  • Address plugin activationKey — from Dashboard → Plugin after buying the Address plugin (plugin.key must be address)
  • API token or script token — from Dashboard → Key (same values used for SMS integration)

Installation

npm i wenova-address

Usage

const {
  getProvinces,
  getProvinceById,
  getDistrictsByProvince,
  getDistrictById,
  getVillagesByDistrict,
  getVillageById,
} = require('wenova-address');

async function run() {
  const pluginKey = 'your-key';

  try {
    const provinces = await getProvinces({ pluginKey, kw: 'vien' });
    const province = await getProvinceById(1, { pluginKey });
    console.log(provinces.length, province?.name);
  } catch (err) {
    console.error(err.code ? `[${err.code}] ${err.message}` : err.message);
  }
}

run();

Quick guide

  • Put your pluginKey in each call
  • Optional: baseUrl (default https://apimicroservices.wenova.fun, or process.env.WENOVA_API_URL)
  • Optional: kw to search province / district / village names
  • Optional: langlao/lo (Lao in name) or en/english/eng (primary name only)
  • Optional: rawResponse: true — return full API JSON { success, code, message, data }
  • Use numeric id values from a previous list response for detail calls

Available functions

| Function | HTTP | |----------|------| | getProvinces({ pluginKey, kw?, lang?, baseUrl?, rawResponse? }) | GET /npm-provinces | | getProvinceById(id, { pluginKey, lang?, baseUrl?, rawResponse? }) | GET /npm-provinces/:id | | getDistrictsByProvince(provinceId, { pluginKey, kw?, lang?, baseUrl?, rawResponse? }) | GET /npm-districts/by-province/:provinceId | | getDistrictById(id, { pluginKey, lang?, baseUrl?, rawResponse? }) | GET /npm-districts/:id | | getVillagesByDistrict(districtId, { pluginKey, kw?, lang?, baseUrl?, rawResponse? }) | GET /npm-vilages/by-district/:districtId | | getVillageById(id, { pluginKey, lang?, baseUrl?, rawResponse? }) | GET /npm-vilages/:id |

By default (v1.1+), each function returns data from the success envelope — an array for lists, an object or null for detail by id.

REST API (no Bearer token)

Base URL: https://apimicroservices.wenova.fun (override with baseUrl or WENOVA_API_URL).

| Method | Path | Query | |--------|------|--------| | GET | /npm-provinces | key (required), kw?, lang? | | GET | /npm-provinces/:id | key (required), lang? | | GET | /npm-districts/by-province/:provinceId | key (required), kw?, lang? | | GET | /npm-districts/:id | key (required), lang? | | GET | /npm-vilages/by-district/:districtId | key (required), kw?, lang? | | GET | /npm-vilages/:id | key (required), lang? |

Success response (v1.1+)

{
  "success": true,
  "code": 90001,
  "message": "Operation completed successfully",
  "data": []
}

The package returns data directly (e.g. [] or { "id": 1, "name": "..." }).

Error response (Wenova 5-digit code)

When the API rejects a request (no statusCode in body):

{
  "code": 60101,
  "message": "Plugin key (key) query parameter is required",
  "path": "/npm-provinces",
  "method": "GET"
}

Thrown errors include message, and when from the API: code, path, method, httpStatus.

try {
  await getProvinces({ pluginKey: '' });
} catch (err) {
  console.error(`[${err.code}] ${err.message}`);
}

Common Wenova codes (Address / Plugins 60xxx)

| Code | Message (summary) | What to do | |------|-------------------|------------| | 60101 | Plugin key (key) required | Pass pluginKey on every call | | 60102 | Key not enabled for address API | Use Address plugin activationKey (Dashboard → Plugin) | | 60103 | User plugin subscription not active | Check key in Dashboard → Plugin or Key | | 60104 | Invalid province/district/village id in URL | Use positive integer ids from list responses | | 60501 | Rate limit exceeded | Retry later | | 90901 | Internal server error | Retry or contact support |

SDK errors (before HTTP)

| Code | Message | Cause | |------|---------|--------| | 60101 | pluginKey is required | Missing pluginKey in options | | 60104 | id must be a positive number | Invalid id for detail | | 60104 | provinceId must be a positive number | Invalid provinceId | | 60104 | districtId must be a positive number | Invalid districtId |

Success behaviour

  • List endpoints: return an array; may be [] if nothing matches kw
  • Detail by id: return an object or null if not found (HTTP 200)

Related packages

Changelog

1.1.0

  • Unwrap success envelope { success, code, message, data } — lists return arrays directly
  • Attach Wenova code, path, method, httpStatus on API errors
  • Client validation uses 60101 / 60104 where applicable
  • Optional rawResponse on all functions
  • Document Wenova error JSON (replaces legacy statusCode + timestamp examples)