domain-quotes 0.0.10 → 0.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -16
- package/dist/index.js +1 -0
- package/package.json +11 -8
- package/todo.txt +0 -5
package/README.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Domain Quotes
|
|
2
2
|
|
|
3
|
-
[](https://github.com/namewiz/domain-quotes/actions/workflows/build.yml)
|
|
4
|
+
[](https://github.com/namewiz/domain-quotes/actions/workflows/test.yml)
|
|
5
|
+
[](https://www.npmjs.com/package/domain-quotes)
|
|
6
|
+
[](https://github.com/namewiz/domain-quotes/blob/main/LICENSE)
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Domain Quote is a lightweight TypeScript/JavaScript library to compute domain registration quotes across currencies with discounts and VAT, using curated datasets.
|
|
10
10
|
|
|
11
11
|
Includes:
|
|
12
12
|
- Extension support based on unified registrar price list (OpenProvider/NIRA)
|
|
@@ -19,25 +19,25 @@ Includes:
|
|
|
19
19
|
Install
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
npm i
|
|
22
|
+
npm i domain-quotes
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
Usage
|
|
26
26
|
|
|
27
27
|
```ts
|
|
28
|
-
import {
|
|
28
|
+
import { getDefaultQuote, DomainPrices, DEFAULT_RATES } from 'domain-quotes';
|
|
29
29
|
|
|
30
|
-
// Quick
|
|
31
|
-
const quote = await
|
|
30
|
+
// Quick quote (uses bundled defaults)
|
|
31
|
+
const quote = await getDefaultQuote('com', 'USD', { discountCodes: ['SAVE10'] });
|
|
32
32
|
// → { extension, currency, basePrice, discount, tax, totalPrice, symbol }
|
|
33
33
|
|
|
34
34
|
// Advanced: custom or explicit config via the class
|
|
35
|
-
const dp = new DomainPrices(
|
|
35
|
+
const dp = new DomainPrices(DEFAULT_RATES); // or provide your own DomainPricesConfig
|
|
36
36
|
const eur = await dp.getPrice('example.com', 'EUR', { discountPolicy: 'stack' });
|
|
37
37
|
|
|
38
38
|
// Add a 15% markup before discounts/taxes
|
|
39
39
|
const withMarkup = new DomainPrices({
|
|
40
|
-
...
|
|
40
|
+
...DEFAULT_RATES,
|
|
41
41
|
markup: { type: 'percentage', value: 0.15 },
|
|
42
42
|
});
|
|
43
43
|
const quoteWithMarkup = await withMarkup.getPrice('example.com', 'USD', { discountCodes: ['SAVE10'] });
|
|
@@ -45,16 +45,17 @@ const quoteWithMarkup = await withMarkup.getPrice('example.com', 'USD', { discou
|
|
|
45
45
|
|
|
46
46
|
API
|
|
47
47
|
|
|
48
|
-
- `
|
|
49
|
-
- Computes
|
|
48
|
+
- `getDefaultQuote(extension: string, currency: string, options?: GetPriceOptions): Promise<PriceQuote>`
|
|
49
|
+
- Computes a quote for a TLD/SLD extension (e.g. `com`, `com.ng`, `.org`) using the bundled defaults.
|
|
50
|
+
- Alias: `getDefaultPrice(...)` for backward-compatibility.
|
|
50
51
|
- `options`
|
|
51
52
|
- `discountCodes?: string[]` – one or more codes; case-insensitive.
|
|
52
53
|
- `now?: number | Date` – inject time for deterministic tests.
|
|
53
54
|
- `discountPolicy?: 'stack' | 'max'` – default `'max'` (highest single discount only).
|
|
54
55
|
|
|
55
56
|
- `class DomainPrices(config: DomainPricesConfig)`
|
|
56
|
-
- `getPrice(extension: string, currency: string, options?: GetPriceOptions): Promise<PriceQuote>` – same behavior as above, but uses the provided config.
|
|
57
|
-
- `
|
|
57
|
+
- `getPrice(extension: string, currency: string, options?: GetPriceOptions): Promise<PriceQuote>` – same behavior as above, but uses the provided config. Alias: `getQuote(...)`.
|
|
58
|
+
- `DEFAULT_RATES: DomainPricesConfig` – exported snapshot config used by `getDefaultQuote`.
|
|
58
59
|
|
|
59
60
|
- `listSupportedExtensions(): string[]`
|
|
60
61
|
- All extensions with a non-zero price in the dataset.
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var k={SAVE1:{rate:.01,extensions:["com","net"],startAt:"2023-01-01T00:00:00Z",endAt:"2025-12-31T23:59:59Z"},NEWUSER15:{rate:.15,extensions:["com","net","org"],startAt:"2023-01-01T00:00:00Z",endAt:"2024-12-31T23:59:59Z"},FALL20:{rate:.2,extensions:["org","info"],startAt:"2024-09-01T00:00:00Z",endAt:"2024-12-01T00:00:00Z"}};var v={US:0,GB:.2,DE:.19,NG:.075};var b={USD:"US",GBP:"GB",EUR:"DE",NGN:"NG"};function ie(){return Object.keys(b)}function oe(t){return t!=null&&b.hasOwnProperty(t.toUpperCase())}function ce(){let t=E();return Object.keys(t).sort()}function ae(t){let e=E(),r=O(e,t),n=e[r];return typeof n=="number"&&n>0}function O(t,e){if(!e)return e;let n=e.trim().toLowerCase().replace(/^\.+/,"");if(!n)return"";if(t.hasOwnProperty(n))return n;if(n.includes(".")){let s=n.split(".");for(let o=0;o<s.length;o++){let c=s.slice(o).join(".");if(t.hasOwnProperty(c))return c}return s[s.length-1]}return n}function V(t){return t instanceof Date?t.getTime():typeof t=="number"?t:Date.now()}var j="https://raw.githubusercontent.com/namewiz/registrar-pricelist/refs/heads/main/data/unified-create-prices.csv",F="https://raw.githubusercontent.com/namewiz/registrar-pricelist/refs/heads/main/data/exchange-rates.json";async function L(t){let e=await fetch(t);if(!e.ok)throw new Error(`Failed to fetch ${t}: ${e.status} ${e.statusText}`);return e.text()}async function Z(t){let e=await fetch(t);if(!e.ok)throw new Error(`Failed to fetch ${t}: ${e.status} ${e.statusText}`);return e.json()}function B(t){let e=t.split(/\r?\n/).map(s=>s.trim()).filter(Boolean);if(e.length===0)return{};let r=e.shift(),n={};for(let s of e){let o=s.split(",");if(o.length<3)continue;let c=o[0]?.trim().toLowerCase(),i=o[2]?.trim(),a=Number(i);!c||!Number.isFinite(a)||a<=0||(!(c in n)||a<n[c])&&(n[c]=a)}return n}var[J,z]=await Promise.all([L(j).then(B),Z(F)]);function E(){return J}function X(){return z}function H(){return v}function q(){return k}var h=class extends Error{constructor(e,r){super(r),this.name="DomainPricesError",this.code=e}},P=class extends h{constructor(e){super("ERR_UNSUPPORTED_EXTENSION",`Unsupported extension: ${e}`),this.name="UnsupportedExtensionError"}},l=class extends h{constructor(e){super("ERR_UNSUPPORTED_CURRENCY",`Unsupported currency: ${e}`),this.name="UnsupportedCurrencyError"}};function W(){return{countryCode:"US",currencyName:"United States Dollar",currencySymbol:"$",currencyCode:"USD",exchangeRate:1,inverseRate:1}}function p(t){return Math.round(t*100)/100}function Y(t,e){if(!e)return t;let r=typeof e.value=="number"?e.value:0;if(!Number.isFinite(r)||r<=0)return t;switch(e.type){case"percentage":return t+t*r;case"fixedUsd":return t+r;default:return t}}var y=class{constructor(e){this.config=e}findRateInfo(e){if(e==="USD")return W();let r=this.config.exchangeRates.find(n=>n.currencyCode===e);if(!r)throw new l(e);return r}async getPrice(e,r,n={}){let s=this.config.createPrices,o=this.config.vatRates,c=this.config.discounts,i=O(s,e),a=n.transaction||"create",u;switch(a){case"renew":u=this.config.renewPrices?.[i]??s[i];break;case"restore":u=this.config.restorePrices?.[i]??s[i];break;case"transfer":u=this.config.transferPrices?.[i]??s[i];break;case"create":default:u=s[i];break}if(u===void 0||u===0)throw new P(i);let R=(r||"").toUpperCase(),w=b[R];if(!w)throw new l(r);let D=o[w];if(typeof D!="number")throw new l(r);let T=this.findRateInfo(R),G=T.currencySymbol,_=Y(u,this.config.markup),d=p(_*T.exchangeRate),Q=Array.from(new Set((n.discountCodes||[]).map(m=>m.toUpperCase()))),C=V(n.now),x=[];for(let m of Q){let f=c[m];if(!f)continue;let U=Date.parse(f.startAt),A=Date.parse(f.endAt);Number.isNaN(U)||Number.isNaN(A)||C<U||C>A||f.extensions.includes(i)&&x.push(p(d*f.rate))}let g=0;x.length>0&&(n.discountPolicy==="stack"?g=p(x.reduce((m,f)=>m+f,0)):g=Math.max(...x)),g>d&&(g=d);let S=p(d-g),N=p(S*D),I=p(S+N);return{extension:i,currency:R,basePrice:d,discount:g,tax:N,totalPrice:I,symbol:G,transaction:a}}async getQuote(e,r,n={}){return this.getPrice(e,r,n)}},K={createPrices:E(),exchangeRates:X(),vatRates:H(),discounts:q()};async function ee(t,e,r={}){return new y(K).getPrice(t,e,r)}async function ue(t,e,r={}){return ee(t,e,r)}export{K as DEFAULT_RATES,y as DomainPrices,y as DomainQuote,l as UnsupportedCurrencyError,P as UnsupportedExtensionError,ee as getDefaultPrice,ue as getDefaultQuote,oe as isSupportedCurrency,ae as isSupportedExtension,ie as listSupportedCurrencies,ce as listSupportedExtensions};
|
package/package.json
CHANGED
|
@@ -1,29 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "domain-quotes",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "Fast multi-currency domain
|
|
3
|
+
"version": "0.0.20",
|
|
4
|
+
"description": "Fast multi-currency domain quote checker library across registrars.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "npx -y esbuild src/index.ts --bundle --minify --format=esm --target=esnext --outdir=dist/ --platform=neutral",
|
|
9
|
-
"postbuild": "cp dist/index.js docs/
|
|
9
|
+
"postbuild": "cp dist/index.js docs/domain-quotes.js",
|
|
10
10
|
"test": "npm run build && node --test",
|
|
11
|
-
"start": "npm run build && cp dist/index.js docs/
|
|
11
|
+
"start": "npm run build && cp dist/index.js docs/domain-quotes.js && npx serve docs"
|
|
12
12
|
},
|
|
13
|
-
"homepage": "https://namewiz.github.io/
|
|
13
|
+
"homepage": "https://namewiz.github.io/domain-quotes",
|
|
14
14
|
"repository": {
|
|
15
15
|
"type": "git",
|
|
16
|
-
"url": "git+https://github.com/namewiz/
|
|
16
|
+
"url": "git+https://github.com/namewiz/domain-quotes.git"
|
|
17
17
|
},
|
|
18
18
|
"bugs": {
|
|
19
|
-
"url": "https://github.com/namewiz/
|
|
19
|
+
"url": "https://github.com/namewiz/domain-quotes/issues"
|
|
20
20
|
},
|
|
21
21
|
"author": "Justice Ogbonna <dev@justiceo.com>",
|
|
22
22
|
"keywords": [
|
|
23
23
|
"domain-name",
|
|
24
|
+
"domain-quotes",
|
|
24
25
|
"domain-price",
|
|
25
26
|
"domain-availability",
|
|
26
|
-
"price-check"
|
|
27
|
+
"price-check",
|
|
28
|
+
"quote",
|
|
29
|
+
"quote-check"
|
|
27
30
|
],
|
|
28
31
|
"exports": {
|
|
29
32
|
".": "./dist/index.js"
|
package/todo.txt
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
"comment": "organizational email constraint, origin website, max # of years, whether it can be combined with other coupons, user country code, new customer only",
|
|
3
|
-
"comment2": "doesn't support fixed amount intentionally, avoid -ve charges, ",
|
|
4
|
-
"comment3": "each code can be used an unlimited number of times between start and end",
|
|
5
|
-
"comment4": "Alt: enable use:once or use:once_per_user",
|