Javascript URL mutation library

Overview

URI.js

CDNJS


IMPORTANT: You may not need URI.js anymore! Modern browsers provide the URL and URLSearchParams interfaces.


NOTE: The npm package name changed to urijs


I always want to shoot myself in the head when looking at code like the following:

var url = "http://example.org/foo?bar=baz";
var separator = url.indexOf('?') > -1 ? '&' : '?';

url += separator + encodeURIComponent("foo") + "=" + encodeURIComponent("bar");

Things are looking up with URL and the URL spec but until we can safely rely on that API, have a look at URI.js for a clean and simple API for mutating URIs:

var url = new URI("http://example.org/foo?bar=baz");
url.addQuery("foo", "bar");

URI.js is here to help with that.

API Example

// mutating URLs
URI("http://example.org/foo.html?hello=world")
  .username("rodneyrehm")
    // -> http://[email protected]/foo.html?hello=world
  .username("")
    // -> http://example.org/foo.html?hello=world
  .directory("bar")
    // -> http://example.org/bar/foo.html?hello=world
  .suffix("xml")
    // -> http://example.org/bar/foo.xml?hello=world
  .query("")
    // -> http://example.org/bar/foo.xml
  .tld("com")
    // -> http://example.com/bar/foo.xml
  .query({ foo: "bar", hello: ["world", "mars"] });
    // -> http://example.com/bar/foo.xml?foo=bar&hello=world&hello=mars

// cleaning things up
URI("?&foo=bar&&foo=bar&foo=baz&")
  .normalizeQuery();
    // -> ?foo=bar&foo=baz

// working with relative paths
URI("/foo/bar/baz.html")
  .relativeTo("/foo/bar/world.html");
    // -> ./baz.html

URI("/foo/bar/baz.html")
  .relativeTo("/foo/bar/sub/world.html")
    // -> ../baz.html
  .absoluteTo("/foo/bar/sub/world.html");
    // -> /foo/bar/baz.html

// URI Templates
URI.expand("/foo/{dir}/{file}", {
  dir: "bar",
  file: "world.html"
});
// -> /foo/bar/world.html

See the About Page and API Docs for more stuff.

Using URI.js

URI.js (without plugins) has a gzipped weight of about 7KB - if you include all extensions you end up at about 13KB. So unless you need second level domain support and use URI templates, we suggest you don't include them in your build. If you don't need a full featured URI mangler, it may be worth looking into the much smaller parser-only alternatives listed below.

URI.js is available through npm, bower, bowercdn, cdnjs and manually from the build page:

# using bower
bower install uri.js

# using npm
npm install urijs

Browser

I guess you'll manage to use the build tool or follow the instructions below to combine and minify the various files into URI.min.js - and I'm fairly certain you know how to <script src=".../URI.min.js"></script> that sucker, too.

Node.js and NPM

Install with npm install urijs or add "urijs" to the dependencies in your package.json.

// load URI.js
var URI = require('urijs');
// load an optional module (e.g. URITemplate)
var URITemplate = require('urijs/src/URITemplate');

URI("/foo/bar/baz.html")
  .relativeTo("/foo/bar/sub/world.html")
    // -> ../baz.html

RequireJS

Clone the URI.js repository or use a package manager to get URI.js into your project.

require.config({
  paths: {
    urijs: 'where-you-put-uri.js/src'
  }
});

require(['urijs/URI'], function(URI) {
  console.log("URI.js and dependencies: ", URI("//amazon.co.uk").is('sld') ? 'loaded' : 'failed');
});
require(['urijs/URITemplate'], function(URITemplate) {
  console.log("URITemplate.js and dependencies: ", URITemplate._cache ? 'loaded' : 'failed');
});

Minify

See the build tool or use Google Closure Compiler:

// ==ClosureCompiler==
// @compilation_level SIMPLE_OPTIMIZATIONS
// @output_file_name URI.min.js
// @code_url http://medialize.github.io/URI.js/src/IPv6.js
// @code_url http://medialize.github.io/URI.js/src/punycode.js
// @code_url http://medialize.github.io/URI.js/src/SecondLevelDomains.js
// @code_url http://medialize.github.io/URI.js/src/URI.js
// @code_url http://medialize.github.io/URI.js/src/URITemplate.js
// ==/ClosureCompiler==

Resources

Documents specifying how URLs work:

Informal stuff

How other environments do things

Discussion on Hacker News

Forks / Code-borrow

  • node-dom-urls passy's partial implementation of the W3C URL Spec Draft for Node
  • urlutils cofounders' window.URL constructor for Node

Alternatives

If you don't like URI.js, you may like one of the following libraries. (If yours is not listed, drop me a line…)

Polyfill

URL Manipulation

URL Parsers

URI Template

Various

Authors

Contains Code From

License

URI.js is published under the MIT license. Until version 1.13.2 URI.js was also published under the GPL v3 license - but as this dual-licensing causes more questions than helps anyone, it was dropped with version 1.14.0.

Changelog

moved to Changelog

Comments
  • Get query string parameter value?

    Get query string parameter value?

    With URI.js, it's easy to SET parameters.

    I've read all the docs and hope I'm missing something, but I can't find a good way to GET the query string parameter value.

    What I'm having to do now is this:

    if (url.search(true).hasOwnProperty("my_parameter_name")) {
      console.log("parameter value is" + url.search(true).my_parameter_name);
    }
    

    Is there a better way?

    opened by tylercollier 18
  • Added more supporting methods for URN paths.

    Added more supporting methods for URN paths.

    First, I apologize if this should really be an issue instead of a PR, so that the solution could be properly planned in advance.

    I work on a product is required to accept URIs which may or may not be properly encoded and reformat them as properly-encoded URIs. This is a hard problem to solve on our own, and so URI.js has been a godsend. Unfortunately, the most common type of URI we handle is a URN; and URI.js does not currently have anything like recodePath for URNs. This patch implements a recodeURNPath method for URNs and calls it while normalizing a URN path.

    This PR might carry a risk with it, unfortunately. There is some equivocation in the documentation about the difference between URNs and URIs, which is reflected in the overall structure of URI.js:

    URLs are used to address the individual resources of your website. URNs are usually used for hooking into other applications, as mailto:, magnet: or spotify: suggest. While RFC 3986 defines the structure of an URL in depth, URNs are not. The structure (and meaning) of URNs are up to their distinct specifications.

    Technically, URN refers to a very specific thing: Uniform Resource Names as defined by RFC 2141 (the syntactic requirements of which are implemented in this patch). Though there is some degree of freedom to the structure of URNs in a specific namespace, they cannot break the rules laid out in 2141 (such as which characters are valid in a URN). In addition, this means that mailto: and spotify: URIs are not actually URNs at all (and in fact, the RFC defining mailto: scheme, RFC 2368, calls it a URL).

    I think URI.js is drawing its inspiration from this paragraph in RFC 3986 (which is mentioned in the quoted documentation above):

    A URI can be further classified as a locator, a name, or both. The term "Uniform Resource Locator" (URL) refers to the subset of URIs that, in addition to identifying a resource, provide a means of locating the resource by describing its primary access mechanism (e.g., its network "location"). The term "Uniform Resource Name" (URN) has been used historically to refer to both URIs under the "urn" scheme [RFC2141], which are required to remain globally unique and persistent even when the resource ceases to exist or becomes unavailable, and to any other URI with the properties of a name.

    The problem here is that even this is still a purely semantic distinction, while the distinction between URNs and URIs as implemented in URI.js is syntactic: URLs are anything that looks like protocol://user:password@hostname/path/with/slashes?query=string and URNs are anything that looks like scheme:path:with:colons?query=string.

    All this is to say: introducing the syntactic requirements to normalize real URNs as defined in RFC 2141 may or may not actually apply to the things URI.js treats as URNs.

    That said, in practice I think the risk isn't very significant. For one, users of URN-ish URIs already could not rely on URI.js for proper normalization of paths, and so I see no harm in URI.js applying its best effort. If a consumer needs a particular kind of syntax for their custom URI scheme, they always have had to implement that themselves, and so nothing changes here.

    Feature Path 
    opened by hardlyknowem 17
  • Fix several questionable .relativeTo() results.

    Fix several questionable .relativeTo() results.

    Thanks for fixing #75 – that fixed the specific cases that I raised.

    However, there are several more things that I think aren’t quite right about .relativeTo().

    May I humbly suggest the attached changeset?

    Hopefully the test cases that I have added and changed speak for themselves, but I’m happy to explain my rationale if anything is controversial, or to be corrected if I’m being silly :).

    Bug 
    opened by djcsdy 15
  • removeQuery won't remove the last value of a variable if provided in an Array

    removeQuery won't remove the last value of a variable if provided in an Array

    Hi,

    To have easy interactions between json objects and Search/Query serialisation, I addQuery and removeQuery elements always providing a list. This works great except it removeQuery, not removing the last value of a multi-value GET variable, if this value is specified via a singleton list (which is not illegal).

    I am to provide a pull request fixing this small issue.

    Bug QueryString 
    opened by Siltaar 14
  • URI.js expects users to do their own URI-encoding, thus defeating its own purpose

    URI.js expects users to do their own URI-encoding, thus defeating its own purpose

    URI("").segment(["%"]);
    // => URIError: URI malformed
    
    URI("%25").segment();
    // => ["%25"]
    

    This makes me want to cry.

    The whole point of having a library to handle URIs is that the user of the library shouldn’t have to think about how to encode or decode URIs.

    For example, if I know that there is a resource called “Business Plan (90%)” in a directory called “My Extremely Dull Documents”, I ought be able to create a relative URI referencing that resource with syntax somewhat like this:

    URI("").segment(["My Extremely Dull Documents"], ["Business Plan (90%)"]);
    

    which would then produce a URI whose text representation is: My%20Extremely%20Dull%20Documents/Business%20Plan%20%2890%25%29.

    Similarly when parsing the resulting URI I ought to be able to do something somewhat like:

    URI("My%20Extremely%20Dull%20Documents/Business%20Plan%20%2890%25%29").
        segment();
    

    And get back the original strings: ["My Extremely Dull Documents"], ["Business Plan (90%)"].

    I know I can use URI.encode and URI.decode on the path segments, but that requires the user to remember to do so, and to know and remember which of the several encoding schemes are used for which parts of the URI, so that’s pretty error-prone :(.

    Feature 
    opened by djcsdy 14
  • Constructor assigning IP addresses to path instead of host

    Constructor assigning IP addresses to path instead of host

    uri = URI("208.113.212.187") uri.path -> 208.113.212.187 _string -> ""

    It may not be RFC complaint, but no-one adds http:// to their IP addresses.

    Feature 
    opened by indolering 12
  • unsafe-eval security error in chrome extension

    unsafe-eval security error in chrome extension

    The error seems to be coming because of the following code:

    f=Function("return this")()
    

    Error:

    Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' chrome-extension-resource:".
    

    Reduced case chrome extension: http://dl.dropboxusercontent.com/u/42214070/urijs-security-issue.crx

    Bug 
    opened by chinchang 12
  • Fixed tld() returning wrong

    Fixed tld() returning wrong

    Now: http://example/ returns example from tld()

    After: http://example/ returns (empty string) from tld()

    I would prefer returning null but the other checks returns an empty string...

    opened by Jellyfrog 12
  • bower.json lists multiple files of the same filetype for

    bower.json lists multiple files of the same filetype for "main" option

    https://github.com/bower/bower.json-spec#main explicitly states that only one file per filetype should be listed in main:

    The entry-point files necessary to use your package. Only one file per filetype.

    "main": [
      "src/URI.js",
      "src/IPv6.js",
      "src/SecondLevelDomains.js",
      "src/punycode.js",
      "src/URITemplate.js",
      "src/jquery.URI.js",
      "src/URI.min.js",
      "src/jquery.URI.min.js",
      "src/URI.fragmentQuery.js",
      "src/URI.fragmentURI.js"
    ],
    

    I would expect only one .js file here.

    opened by bradleyayers 11
  • Port is not validated the same when constructing URI as when using uri.port() method

    Port is not validated the same when constructing URI as when using uri.port() method

    // The following works (when I think it shouldn't)
    var uri = URI('http://example.com:robots.txt');
    
    // Even this works
    console.log(uri.port()); // Will output 'robots.txt'
    
    // This does not work however...
    var uri = URI('http://example.com');
    
    // ...since this will (correctly) throw an error
    uri.port('robots.txt');
    

    Could we look into adding the same validation of the URI port when constructing URI instances from strings as we have when calling the uri.port method?

    Bug Authority 
    opened by fredrikekelund 10
  • RequireJS hits a 404 when minified file attempts to load

    RequireJS hits a 404 when minified file attempts to load "./URI"

    Installed via bower and configured RequireJS:

    paths: {
      urijs = '/dist/uri.js/URI.min'
    }
    

    We have a build system that copies only URI.min.js to our deploy path.

    However, once this js file has loaded, RequireJS hits a 404 trying to find:

    http://127.0.0.1:8080/URI.js?bust=1443743941152

    I'm not sure what's causing this - I assume "URI" is a package defined within that same file, so I don't understand why require is going out and trying to find it.

    Update: I've tried to reproduce this by cloning the repo and hitting a basic html file with requirejs. While I am able to get the file to load, the example on your README throws a "URI is not a function" error, and the object I'm given has properties best and noConflict - it seems to be giving me the IPv6 module...

    https://pste.me/#/BdSlk

    opened by viveleroi 10
  • Can we change separator?

    Can we change separator?

    Hello. Can i change params separator?

    var template = new URITemplate("http://example.org/{file}");
    var result = template.expand( {file: ['param1', 'param2', 'param3'] } );
    result === "http://example.org/param1,param2,param3";
    

    Can i use + instead comma? Like this: result === "http://example.org/param1+param2+param3";

    opened by bilalmalkoc 0
  • Make invalid port check optional to support url templates

    Make invalid port check optional to support url templates

    After version 1.18.11 of urijs, an invalid port exception is thrown if the uri is constructed with a port that isn't valid. This check is useful to avoid having an invalid value as a port, increasing the correctness of the generated URI, but makes impossible to use the library when working with url templates.

    Before 1.18.11, the following code snippet was possible:

    const uri = new urijs('https://github.com:{port}');
    

    After 1.18.11, the same code snippet throws the invalid port exception.

    There're several possible solutions to this problem, in case there's the desire to support URI templates.

    1. Make port check optional by passing an options object to the constructor:
    const uri = new urijs('https://github.com:{port}', { ensureValidPort: false });
    
    1. The second idea that comes to my mind is to throw the exception not when the URI is created but when it's converted to a string. My hypothesis here is that uri.toString() or uri.valueOf() might be the last calls to the urijs library before the constructed URI is used.
    const uri = new urijs('https://github.com:{port}'); // valid, no exception is thrown
    // do stuff here
    const resp = await fetch(uri.toString()); // here an exception will be thrown if the port is still invalid
    
    1. There might be also other valid options.

    Would such change be considered for this library?

    opened by roguib 0
  • charset=Shift_JIS will fail to parse URI.js with a syntax error caused by non-ASCII characters in RegExp

    charset=Shift_JIS will fail to parse URI.js with a syntax error caused by non-ASCII characters in RegExp

    Steps to Reproduce:

    1. Have an HTML payload where server gives response header content-type: text/html;charset=Shift_JIS
    2. Include the URI.js file with a script tag, use a compressed version of URI.js (not sure if same issue happens on the uncompressed one)

    Unfortunately I can't find an easy way to give a link for this easily, but if it's necessary I could produce one maybe with codesandbox.

    Expected:

    The Javascript include should run, there should be no errors in the console

    Actual:

    The Javascript fails to parse with an error in the logs:

    Uncaught SyntaxError: Unexpected token ':'
    

    Root Cause:

    There are non-ASCII characters inside of a Regular Expression in a couple places, example: https://github.com/medialize/URI.js/blob/b655c1b972111ade9f181b02374305942e68e30a/src/URI.js#L231

    The non-ASCII characters «»“”‘’ are interpreted differently when the charset is set to Shift_JIS on the HTML page as a response header, and it causes the regular expression not to be closed properly, running into the next lines making a syntax error in the middle of the JSON. The same behavior is seen in Firefox and Chrome, I have not checked Edge.

    Proposed solution:

    Don't use non-ASCII characters which are unsafe when charsets are changed on the page, instead use a String that will be constructed with escaped characters:

      URI.find_uri_expression = new RegExp("\\b((?:[a-z][\\w-]+:(?:\\/{1,3}|[a-z0-9%])|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,4}\\/)(?:[^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(?:\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]{};:'\".,<>?\xab\xbb\u201c\u201d\u2018\u2019]))", "ig");
    

    One other place: https://github.com/medialize/URI.js/blob/b655c1b972111ade9f181b02374305942e68e30a/src/URI.js#L238

    Could update to this:

        trim: new RegExp("[`!()\\[\\]{};:'\".,<>?\xab\xbb\u201c\u201d\u201E\u2018\u2019]+$"),
    

    These are 2 places, there might be more.

    opened by codefactor 2
  • @types/urijs/index can only be default-imported using the 'allowSyntheticDefaultImports' flag

    @types/urijs/index can only be default-imported using the 'allowSyntheticDefaultImports' flag

    Hello, I found an error that seems to be related to URIjs and ES6. Someone from 2016 [288] seems to have found this previously and couldnt replicate but here are the steps. Could you help me understand how to get around this?

    Error: node_modules/stellar-sdk/lib/server.d.ts:2:8 - error TS1259: Module '"/node_modules/@types/urijs/index"' can only be default-imported using the 'allowSyntheticDefaultImports' flag
    
    2 import URI from "urijs";
             ~~~
    
      node_modules/@types/urijs/index.d.ts:26:1
        26 export = URI;
           ~~~~~~~~~~~~~
        This module is declared with using 'export =', and can only be used with a default import when using the 'allowSyntheticDefaultImports' flag.
    

    To replicate

    1. ng new AppName
    2. npm install --save stellar-sdk
    3. add the SDK to the app within angular.json's build scripts: ["./node_modules/stellar-sdk/dist/stellar-sdk.min.js"]
    4. run the app to see the error
    opened by BenRacicot 1
  • Handling of relative URLs that have a protocol in latest 1.19.7

    Handling of relative URLs that have a protocol in latest 1.19.7

    I'm not sure how much URI.js tries to be in sync with the Web API URL, but even after ac43ca8f80c042f0256fb551ea5203863dec4481 , there's still a difference between URI.js and URL when it comes to slashes, e.g. when dealing with relative URLs that have a protocol (verified in Chrome 93.0.4577.82, Safari 14.1.2 and Firefox 92.0.1):

    > URI.version
    < '1.19.7'
    > new URI("https:index.html", "https://github.com").toString()
    < 'https://index.html/'
    > new URL("https:index.html", "https://github.com").toString()
    < 'https://github.com/index.html'
    

    This is caused by the newly introduced regex. It checks for zero or more slashes. Browsers seem to check for at least two slashes, if there's a base.

    To complicate things, browsers behave differently when no base is given or when the protocols don't match. Then they rather seem to correct typical typos or lazy users (that's at least my assumption):

    > new URI("https:index.html").toString()
    < 'https://index.html/'
    > new URL("https:index.html").toString()
    < 'https://index.html/'
    

    I didn't check whether this is spec'ed somewhere for the URL Web API, but rather wanted to point out this suspicious aspect of the regex.

    The good thing: as URI.js 1.19.6 threw an error for the above calls with a base, this issue shouldn't cause a regression for consumers.

    opened by codeworrior 1
Releases(v1.19.11)
Parse and stringify URL query strings

query-string Parse and stringify URL query strings My open source work is supported by the community Special thanks to: All your environment variables

Sindre Sorhus 6.2k Jan 9, 2023
Belirlediğiniz Özel URL'yi her saniye dener ve alırsa belirlediğiniz kanala sizi etiketleyerek onay mesajı atar.

Novasy Url Spam Selam, bahsedilecek pek bir şey yok config.json dosyasını düzenledikten sonra kullanabilirsiniz. Bana ulaşabileceğiniz sosyal medya he

novasy 28 Dec 29, 2022
Backend para encurtar url utilizando o que aprendi no Ignite da Rocketseat.

?? URL Shortener ?? ?? Tecnologias | ?? Projeto | ?? Como executar | ?? Licença ?? Tecnologias Esse projeto foi desenvolvido com as seguintes tecnolog

Iago Beserra 4 Jan 25, 2022
Spec compliant URL state machine for Node.js

URL Parser This repository contains a work in progress state machine 100% compliant to the URL parser specification. The goal is to create a performan

Yagiz Nizipli 190 Dec 3, 2022
The ultimate JavaScript string library

Voca is a JavaScript library for manipulating strings. https://vocajs.com v.camelCase('bird flight'); // => 'birdFlight' v.sprintf('%s co

Dmitri Pavlutin 3.5k Dec 20, 2022
:fishing_pole_and_fish: A library that allows you to access the text selected by the user

selecting A library that allows you to access the text selected by the user. Instalation To install Selecting, execute: npm install selecting Or Bow

Evandro Leopoldino Gonçalves 87 Nov 17, 2022
Lo-fi, powerful, community-driven string manipulation library.

Lo-fi, powerful, community-driven string manipulation library. This is the main monorepo codebase of Plexis.js a production-ready string manipulation

Plexis 145 Sep 24, 2022
String manipulation helpers for javascript

The stable release documentation can be found here https://epeli.github.io/underscore.string/ Underscore.string Javascript lacks complete string manip

Esa-Matti Suuronen 3.4k Dec 25, 2022
Extra JavaScript string methods.

string.js string.js, or simply S is a lightweight (< 5 kb minified and gzipped) JavaScript library for the browser or for Node.js that provides extra

JP Richardson 1.8k Dec 17, 2022
A robust HTML entity encoder/decoder written in JavaScript.

he he (for “HTML entities”) is a robust HTML entity encoder/decoder written in JavaScript. It supports all standardized named character references as

Mathias Bynens 3.2k Dec 27, 2022
Multiline strings in JavaScript

multiline Multiline strings in JavaScript No more string concatenation or array join! Use ES2015 template literals instead whenever possible. Before c

Sindre Sorhus 1.4k Dec 30, 2022
sprintf.js is a complete open source JavaScript sprintf implementation

sprintf-js sprintf-js is a complete open source JavaScript sprintf implementation for the browser and Node.js. Note: as of v1.1.1 you might need some

Alexandru Mărășteanu 2k Jan 4, 2023
Backend API Rest application for ShortLink, a URL shortening service where you enter a valid URL and get back an encoded URL

ShortLink - The Shortest URL (API) Sobre o Projeto | Como Usar | Importante! Sobre o projeto The Shortest URL é um projeto back-end de ShortLink, um s

Bruno Weber 2 Mar 22, 2022
Lightweight, Portable, Flexible Distributed/Mobile Deep Learning with Dynamic, Mutation-aware Dataflow Dep Scheduler; for Python, R, Julia, Scala, Go, Javascript and more

Apache MXNet (incubating) for Deep Learning Apache MXNet is a deep learning framework designed for both efficiency and flexibility. It allows you to m

The Apache Software Foundation 20.2k Jan 5, 2023
📦 Fully typed and immutable store made on top of Immer with mutation, action, subscription and validation!

Riux is a fully typed and immutable store made on top of Immer with mutation, action, subscription and validation! Table of contents ?? Installation U

null 10 Aug 27, 2022
Piccloud is a full-stack (Angular & Spring Boot) online image clipboard that lets you share images over the internet by generating a unique URL. Others can access the image via this URL.

Piccloud Piccloud is a full-stack application built with Angular & Spring Boot. It is an online image clipboard that lets you share images over the in

Olayinka Atobiloye 3 Dec 15, 2022
A URL builder library for JavaScript, TypeScript

url-naong url-naong is url builder that is inspired by urlcat naong is korean name of Meowth(pokemon monster) install npm install url-naong --save Us

ByungJoon Lee 3 Jul 17, 2022
Little Javascript / Typescript library for validating format of string like email, url, password...

String-Validators Little Javascript / Typescript library for validating format of string like email, url, password... Signaler un Bug · Proposer une F

J.Delauney 3 Oct 14, 2022
Tiny API that provide product/library name for a URL

JSer.info Product Name API Tiny API that provide product/library name for a URL. Usage Supported All products. curl https://jser-product-name.deno.dev

JSer.info 6 Oct 21, 2022
WPPConnect/WA-JS API SERVER is a small api server to provide url preview for @wppconnect/wa-js library

WPPConnect/WA-JS API SERVER WPPConnect/WA-JS API SERVER is a small api server to provide url preview for @wppconnect/wa-js library Our online channels

null 13 Aug 11, 2022