domain-quotes 0.0.20 → 0.1.0

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 CHANGED
@@ -121,7 +121,7 @@ interface DomainPricesConfig {
121
121
  restorePrices?: Record<string, number>;
122
122
  transferPrices?: Record<string, number>;
123
123
  exchangeRates: ExchangeRateData[]; // currency conversion data
124
- vatRates: Record<string, number>; // ISO country code VAT rate
124
+ vatRate: number; // single VAT rate applied to subtotal
125
125
  discounts: Record<string, DiscountConfig>; // discount code → config
126
126
  markup?: PriceMarkup; // optional markup applied before conversion
127
127
  }
@@ -135,7 +135,7 @@ Errors
135
135
  Notes
136
136
 
137
137
  - Rounding is to 2 decimal places at each step to keep totals predictable (`base`, `discount`, `tax`, `total`).
138
- - VAT mapping is intentionally narrow and explicit by currency country: `USD US (0)`, `GBP → GB (0.2)`, `EUR DE (0.19)`, `NGN NG (0.075)`.
138
+ - A single VAT rate is applied to the subtotal by default (7.5% in the default config). Override `vatRate` in the config to change it.
139
139
  - Price and exchange-rate data are fetched from maintained remote sources at import time:
140
140
  - Prices: `https://raw.githubusercontent.com/namewiz/registrar-pricelist/refs/heads/main/data/unified-create-prices.csv`
141
141
  - Exchange rates: `https://raw.githubusercontent.com/namewiz/registrar-pricelist/refs/heads/main/data/exchange-rates.json`
package/dist/index.js CHANGED
@@ -1 +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};
1
+ var S={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 U=.075;function I(){return(_.supportedCurrencies??["USD","NGN"]).slice()}function et(e){if(!e)return!1;let t=e.toUpperCase();return I().includes(t)}function nt(){let e=y();return Object.keys(e).sort()}function rt(e){let t=y(),n=A(e),r=t[n];return typeof r=="number"&&r>0}function A(e){return e&&e.trim().toLowerCase().replace(/^\.+/,"")}function $(e){return e instanceof Date?e.getTime():typeof e=="number"?e:Date.now()}var L="https://raw.githubusercontent.com/namewiz/registrar-pricelist/refs/heads/main/data/unified-create-prices.csv",M="https://raw.githubusercontent.com/namewiz/registrar-pricelist/refs/heads/main/data/exchange-rates.json";async function Z(e){let t=await fetch(e);if(!t.ok)throw new Error(`Failed to fetch ${e}: ${t.status} ${t.statusText}`);return t.text()}async function j(e){let t=await fetch(e);if(!t.ok)throw new Error(`Failed to fetch ${e}: ${t.status} ${t.statusText}`);return t.json()}function V(e){let t=e.split(/\r?\n/).map(i=>i.trim()).filter(Boolean);if(t.length===0)return{};let n=t.shift(),r={};for(let i of t){let g=i.split(",");if(g.length<3)continue;let u=g[0]?.trim().toLowerCase(),s=g[2]?.trim(),o=Number(s);!u||!Number.isFinite(o)||o<=0||(!(u in r)||o<r[u])&&(r[u]=o)}return r}var[z,J]=await Promise.all([Z(L).then(V),j(M)]);function y(){return z}function X(){return J}function H(){return S}var h=class extends Error{constructor(t,n){super(n),this.name="DomainPricesError",this.code=t}},R=class extends h{constructor(t){super("ERR_UNSUPPORTED_EXTENSION",`Unsupported extension: ${t}`),this.name="UnsupportedExtensionError"}},P=class extends h{constructor(t){super("ERR_UNSUPPORTED_CURRENCY",`Unsupported currency: ${t}`),this.name="UnsupportedCurrencyError"}};function q(){return{countryCode:"US",currencyName:"United States Dollar",currencySymbol:"$",currencyCode:"USD",exchangeRate:1,inverseRate:1}}function p(e){return Number(e.toFixed(2))}function B(e,t){if(!t)return e;let n=typeof t.value=="number"?t.value:0;if(!Number.isFinite(n)||n<=0)return e;switch(t.type){case"percentage":return e+e*n;case"fixedUsd":return e+n;default:return e}}var E=class{constructor(t){this.config=t}findRateInfo(t){if(t==="USD")return q();let n=this.config.exchangeRates.find(r=>r.currencyCode===t);if(!n)throw new P(t);return n}async getPrice(t,n,r={}){let i=this.config.createPrices,g=typeof this.config.vatRate=="number"?this.config.vatRate:U,u=this.config.discounts,s=A(t),o=r.transaction||"create",c;switch(o){case"renew":c=this.config.renewPrices?.[s]??i[s];break;case"restore":c=this.config.restorePrices?.[s]??i[s];break;case"transfer":c=this.config.transferPrices?.[s]??i[s];break;case"create":default:c=i[s];break}if(c===void 0||c===0)throw new R(s);let x=(n||"").toUpperCase();if(!(this.config.supportedCurrencies??["USD","NGN"]).includes(x))throw new P(n);let D=this.findRateInfo(x),k=D.currencySymbol,v=B(c,this.config.markup),d=p(v*D.exchangeRate),G=g,O=Array.from(new Set((r.discountCodes||[]).map(m=>m.toUpperCase()))),C=$(r.now),l=[];for(let m of O){let a=u[m];if(!a)continue;let w=Date.parse(a.startAt),N=Date.parse(a.endAt);Number.isNaN(w)||Number.isNaN(N)||C<w||C>N||a.extensions.includes(s)&&l.push(p(d*a.rate))}let f=0;l.length>0&&(r.discountPolicy==="stack"?f=p(l.reduce((m,a)=>m+a,0)):f=Math.max(...l)),f>d&&(f=d);let b=p(d-f),T=p(b*G),Q=p(b+T);return{extension:s,currency:x,basePrice:d,discount:f,tax:T,totalPrice:Q,symbol:k,transaction:o}}async getQuote(t,n,r={}){return this.getPrice(t,n,r)}},_={createPrices:y(),exchangeRates:X(),vatRate:U,discounts:H(),supportedCurrencies:["USD","NGN"]};async function W(e,t,n={}){return new E(_).getPrice(e,t,n)}async function st(e,t,n={}){return W(e,t,n)}export{_ as DEFAULT_CONFIG,U as DEFAULT_VAT_RATE,E as DomainPrices,E as DomainQuote,P as UnsupportedCurrencyError,R as UnsupportedExtensionError,W as getDefaultPrice,st as getDefaultQuote,et as isSupportedCurrency,rt as isSupportedExtension,I as listSupportedCurrencies,nt as listSupportedExtensions};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domain-quotes",
3
- "version": "0.0.20",
3
+ "version": "0.1.0",
4
4
  "description": "Fast multi-currency domain quote checker library across registrars.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",