Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@localazy/cdn-client

Package Overview
Dependencies
Maintainers
4
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@localazy/cdn-client - npm Package Compare versions

Comparing version 1.4.1 to 1.5.0

6

dist/browser/localazy-cdn-client.umd.min.js

@@ -1,6 +0,6 @@

!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("isomorphic-fetch")):"function"==typeof define&&define.amd?define(["exports","isomorphic-fetch"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).LocalazyCDN={})}(this,(function(e){"use strict";var t=Object.defineProperty,s=(e,s,i)=>(((e,s,i)=>{s in e?t(e,s,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[s]=i})(e,"symbol"!=typeof s?s+"":s,i),i);
/* @localazy/cdn-client@1.4.1
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).LocalazyCDN={})}(this,(function(e){"use strict";var t=Object.defineProperty,s=(e,s,i)=>(((e,s,i)=>{s in e?t(e,s,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[s]=i})(e,"symbol"!=typeof s?s+"":s,i),i);
/* @localazy/cdn-client@1.5.0
* (c) 2024 Localazy <team@localazy.com>
* @license MIT */
class i{constructor(e){s(this,"context"),this.context=e}async fetchLocale(e){return this.context.cache.has(e)?new Promise((t=>{t(this.context.cache.get(e))})):this.context.client.get(e.metafileLocale.uri)}async fetchMetafile(){return await this.context.client.get(this.context.metafile.params.jsonPath)}}const a=e=>"string"==typeof e,l=e=>void 0===e,r=e=>Array.isArray(e),o=e=>"[object Object]"===Object.prototype.toString.call(e),n=e=>[...new Set(e)],c=(e,t)=>{const s={};return e.filter((e=>{const i=t(e);return!Object.hasOwn(s,i)&&(s[i]=!0,!0)}))};class h{constructor(){s(this,"map"),this.map=new Map}get(e){return this.map.get(e)}has(e){return this.map.has(e)}set(e,t){this.map.set(e,t)}flush(){this.map=new Map}}class u{constructor(e){s(this,"context"),s(this,"cacheAdapter"),this.context=e,this.cacheAdapter=new h}setIfMissed(e){const{metafileFile:t,metafileLocale:s,data:i}=e,a=this.keyFromMetafile({metafileFile:t,metafileLocale:s});this.cacheAdapter.has(a)||this.cacheAdapter.set(a,i)}has(e){const t=this.keyFromMetafile(e);return this.cacheAdapter.has(t)}get(e){const t=this.keyFromMetafile(e);return this.cacheAdapter.get(t)}flush(){this.cacheAdapter.flush()}keyFromMetafile(e){const{metafileFile:t,metafileLocale:s}=e,i=[...n(t.productFlavors)].sort().join("-");return[this.context.metafile.params.cdnId,t.id,t.file,t.path,t.library,t.module,t.buildType,i,s.locale,s.timestamp.toString()].filter((e=>""!==e)).join("-")}}class p{constructor(e){s(this,"context"),this.context=e}}class f extends p{constructor(){super(...arguments),s(this,"flush",(()=>{this.context.cache.flush()}))}}class d{constructor(e,t){s(this,"language"),s(this,"region"),s(this,"script"),s(this,"isRtl"),s(this,"name"),s(this,"localizedName"),s(this,"uri"),s(this,"timestamp"),s(this,"baseLocale"),this.language=e.language,this.region=e.region,this.script=e.script,this.isRtl=e.isRtl,this.name=e.name,this.localizedName=e.localizedName,this.uri=e.uri,this.timestamp=e.timestamp,this.baseLocale=t}get locale(){return this.language&&this.region&&this.script?`${this.language}_${this.region}#${this.script}`:this.language&&this.script?`${this.language}#${this.script}`:this.language&&this.region?`${this.language}_${this.region}`:this.language}get isBaseLocale(){return this.locale===this.baseLocale}toCdnLocale(){return{locale:this.locale,isBaseLocale:this.isBaseLocale,language:this.language,region:this.region,script:this.script,isRtl:this.isRtl,name:this.name,localizedName:this.localizedName}}}class m{constructor(e){s(this,"id"),s(this,"file"),s(this,"path"),s(this,"library"),s(this,"module"),s(this,"buildType"),s(this,"timestamp"),s(this,"productFlavors"),s(this,"locales"),s(this,"baseUrl"),this.id=e.id,this.file=e.file,this.path=e.path,this.library=e.library,this.module=e.module,this.buildType=e.buildType,this.timestamp=e.timestamp,this.productFlavors=e.productFlavors,this.locales=e.locales,this.baseUrl=e.baseUrl}toCdnFile(){return{id:this.id,file:this.file,path:this.path,library:this.library,module:this.module,buildType:this.buildType,productFlavors:this.productFlavors,locales:this.locales.map((e=>({locale:e.locale,isBaseLocale:e.isBaseLocale,uri:`${this.baseUrl}${e.uri}`})))}}}class g{constructor(e,t){s(this,"projectUrl"),s(this,"baseLocale"),s(this,"locales"),s(this,"timestamp"),s(this,"files"),s(this,"filesMap"),this.projectUrl=e.projectUrl,this.timestamp=e.timestamp,this.files=g.filesFactory(e.files,e.baseLocale,t),this.filesMap=g.filesMapFactory(this.files),this.locales=g.localesFactory(this.files),this.baseLocale=this.locales.find((e=>e.isBaseLocale))}static createEmpty(e){return new g({projectUrl:"",baseLocale:"",timestamp:0,files:{}},e)}static filesFactory(e,t,s){return Object.keys(e).reduce(((i,a)=>{const l=e[a].locales.map((e=>new d(e,t)));return i.push(new m({...e[a],id:a,locales:l,baseUrl:s.baseUrl})),i}),[])}static filesMapFactory(e){return e.reduce(((e,t)=>(e[t.id]=t,e)),{})}static localesFactory(e){const t=e.reduce(((e,t)=>(e.push(...t.locales.map((e=>e.toCdnLocale()))),e)),[]);return c(t,(e=>e.locale))}}class w{constructor(e){s(this,"options"),this.options=w.parseMetafileUrl(e)}get url(){return this.options.url}get baseUrl(){return this.options.baseUrl}get cdnId(){return this.options.cdnId}get jsonPath(){return this.options.jsonPath}static parseMetafileUrl(e){let t;try{t=new URL(e)}catch(e){throw new Error('Invalid param: "options.metafile" cannot be parsed as url.')}const s=t.pathname.match(/^\/(.*?)\/(.*?)\.(v2.json|js|ts)$/);if(null===s||4!==s.length)throw new Error('Invalid param: "options.metafile" contains invalid metafile url.');const i=s[1],a=s[2];return{url:e,baseUrl:t.origin,cdnId:i,jsonPath:`/${i}/${a}.v2.json`}}}class y{constructor(e){s(this,"params"),s(this,"parsedData"),s(this,"data"),this.params=new w(e.metafile),this.parsedData=null,this.data=g.createEmpty(this.params)}setMetafile(e){this.parsedData=e,this.data=new g(e,this.params)}}class x{constructor(e){s(this,"context"),this.context=e}createCdnResponse(e){const{requests:t,responses:s,hasSingleFileResponse:i,hasSingleLocaleResponse:a}=e;return 0===s.length?{}:(this.cacheResponses(t,s),i&&a?s[0]:x.transformResponses(e))}cacheResponses(e,t){t.forEach(((t,s)=>{const{metafileFile:i,metafileLocale:a}=e[s];i&&a&&this.context.cache.setIfMissed({metafileFile:i,metafileLocale:a,data:t})}))}static transformResponses(e){const{requests:t,responses:s,hasSingleFileResponse:i}=e;return s.reduce(((e,s,a)=>{const{metafileFile:l,metafileLocale:r}=t[a];return l&&r&&(i?e[r.locale]=s:(e[l.id]||(e[l.id]={}),e[l.id][r.locale]=s)),e}),{})}}class b{constructor(e){s(this,"metafile"),s(this,"cdn"),s(this,"client"),s(this,"api"),s(this,"cache"),s(this,"responseFactory"),this.metafile=e.metafileContext,this.cdn=e.cdn,this.client=e.client,this.api=new i(this),this.cache=new u(this),this.responseFactory=new x(this)}}class F extends p{constructor(){super(...arguments),s(this,"locales",(e=>{const{excludeBaseLocale:t}=e||{},{locales:s}=this.context.metafile.data;return t?s.filter((e=>!e.isBaseLocale)):s})),s(this,"refresh",(async()=>{const e=await this.context.api.fetchMetafile();this.context.metafile.setMetafile(e)})),s(this,"switch",(async e=>{this.context.metafile.params=new w(e.metafile),await this.refresh()}))}get projectUrl(){return this.context.metafile.data.projectUrl}get baseLocale(){return this.context.metafile.data.baseLocale}get url(){return this.context.metafile.params.url}get files(){return this.context.metafile.data.files.map((e=>e.toCdnFile()))}}class L{constructor(e){s(this,"data"),s(this,"context"),this.context=e.context,this.data=e.data||{}}}class M{constructor(e){s(this,"files"),s(this,"localesMap"),s(this,"hasSingleFileResponse"),s(this,"hasSingleLocaleResponse"),s(this,"context"),this.files=[],this.localesMap=new L({context:e}),this.hasSingleFileResponse=!1,this.hasSingleLocaleResponse=!1,this.context=e}async execute(){const e=this.getPromises(),t=e.map((e=>e[0])),s=e.map((e=>e[1])),i=await Promise.all(t);return this.context.responseFactory.createCdnResponse({requests:s,responses:i,localesMap:this.localesMap,hasSingleFileResponse:this.hasSingleFileResponse,hasSingleLocaleResponse:this.hasSingleLocaleResponse})}getPromises(){return this.files.reduce(((e,t)=>(this.localesMap.data[t.id]&&e.push(...this.localesMap.data[t.id].map((e=>{const s={metafileFile:t,metafileLocale:e};return[this.context.api.fetchLocale(s),s]}))),e)),[])}}class q{constructor(e){s(this,"context"),s(this,"request"),this.context=e,this.request=new M(this.context)}addFiles(e){if(!(o(e)||a(e)||l(e)||r(e)))throw new Error('Invalid param: "request.files" must be object, array, string or undefined.');if(r(e)&&e.forEach((e=>{if(!o(e)&&!a(e))throw new Error('Invalid param: array "request.files" must contain objects or strings.')})),a(e)){this.request.hasSingleFileResponse=!0;const t=this.context.metafile.data.files.find((t=>t.id===e));if(!(t instanceof m))throw new Error(`File not found: "${e}".`);this.request.files=[t]}else if(l(e))this.request.files=[...this.context.metafile.data.files];else if(r(e))this.request.files=e.map((e=>{let t;if(a(e)){const s=this.context.metafile.data.files.find((t=>t.id===e));if(l(s))throw new Error(`File not found: "${e}".`);t=s}else{const s=this.context.metafile.data.files.find((t=>t.id===e.id));if(l(s))throw new Error(`File not found: "${e.id}".`);t=s}return t}));else if(o(e)){this.request.hasSingleFileResponse=!0;const t=this.context.metafile.data.files.find((t=>t.id===e.id));if(l(t))throw new Error(`File not found: "${e.id}".`);this.request.files=[t]}return this}addLocales(e,t){if(!(a(e)||l(e)||r(e)))throw new Error('Invalid param: "request.locales" must be array, string or undefined.');return r(e)&&e.forEach((e=>{if(!a(e))throw new Error('Invalid param: array "request.locales" must contain strings.')})),a(e)?(this.request.hasSingleLocaleResponse=!0,this.request.files.reduce(((t,s)=>(t.data[s.id]=s.locales.filter((t=>t.locale===e)),t)),this.request.localesMap)):l(e)?this.request.files.reduce(((e,s)=>(e.data[s.id]=t?s.locales.filter((e=>!e.isBaseLocale)):s.locales,e)),this.request.localesMap):r(e)&&this.request.files.reduce(((t,s)=>(t.data[s.id]=s.locales.filter((t=>e.includes(t.locale))),t)),this.request.localesMap),this}getCdnRequest(){const e=this.request;return this.request=new M(this.context),e}}class R{constructor(e){s(this,"baseUrl"),this.baseUrl=e}async get(e){const t=await fetch(`${this.baseUrl}${e}`),s=t.headers.get("content-type")||"",i=["application/json5","application/json"].includes(s);if(t.status>=400)throw new Error(`Request failed with status code ${t.status}`);let a="";if(i)try{a=await t.json()}catch(e){a={}}else try{a=await t.text()}catch(e){a=""}return a}}class j{constructor(e){s(this,"metafile"),s(this,"cache"),s(this,"context"),s(this,"fetch",(async e=>{const{files:t,locales:s,excludeBaseLocale:i}=e||{};return new q(this.context).addFiles(t).addLocales(s,i).getCdnRequest().execute()}));const t=new y(e),i=new R(t.params.baseUrl);this.context=new b({metafileContext:t,cdn:this,client:i}),this.metafile=new F(this.context),this.cache=new f(this.context)}static async create(e){if(!e)throw new Error('Invalid param: missing required "options" parameter.');if(!a(e.metafile))throw new Error('Invalid param: "options.metafile" must be string.');const t=new j(e);return await t.metafile.refresh(),t}}e.Api=i,e.CdnBase=p,e.CdnCache=f,e.CdnClient=j,e.CdnMetafile=F,e.Context=b,e.FetchHttpAdapter=R,e.LocalesCache=u,e.LocalesMap=L,e.MemoryCacheAdapter=h,e.MetafileContext=y,e.MetafileData=g,e.MetafileFile=m,e.MetafileLocale=d,e.MetafileParams=w,e.Request=M,e.RequestBuilder=q,e.ResponseFactory=x,e.isArray=r,e.isPlainObject=o,e.isString=a,e.isUndefined=l,e.uniq=n,e.uniqBy=c,Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})}));
class i{constructor(e){s(this,"context"),this.context=e}async fetchLocale(e){return this.context.cache.has(e)?new Promise((t=>{t(this.context.cache.get(e))})):this.context.client.get(e.metafileLocale.uri)}async fetchMetafile(){return await this.context.client.get(this.context.metafile.params.jsonPath)}}const a=e=>"string"==typeof e,l=e=>void 0===e,r=e=>Array.isArray(e),o=e=>"[object Object]"===Object.prototype.toString.call(e),n=e=>[...new Set(e)],c=(e,t)=>{const s={};return e.filter((e=>{const i=t(e);return!Object.hasOwn(s,i)&&(s[i]=!0,!0)}))};class h{constructor(){s(this,"map"),this.map=new Map}get(e){return this.map.get(e)}has(e){return this.map.has(e)}set(e,t){this.map.set(e,t)}flush(){this.map=new Map}}class u{constructor(e){s(this,"context"),s(this,"cacheAdapter"),this.context=e,this.cacheAdapter=new h}setIfMissed(e){const{metafileFile:t,metafileLocale:s,data:i}=e,a=this.keyFromMetafile({metafileFile:t,metafileLocale:s});this.cacheAdapter.has(a)||this.cacheAdapter.set(a,i)}has(e){const t=this.keyFromMetafile(e);return this.cacheAdapter.has(t)}get(e){const t=this.keyFromMetafile(e);return this.cacheAdapter.get(t)}flush(){this.cacheAdapter.flush()}keyFromMetafile(e){const{metafileFile:t,metafileLocale:s}=e,i=[...n(t.productFlavors)].sort().join("-");return[this.context.metafile.params.cdnId,t.id,t.file,t.path,t.library,t.module,t.buildType,i,s.locale,s.timestamp.toString()].filter((e=>""!==e)).join("-")}}class p{constructor(e){s(this,"context"),this.context=e}}class f extends p{constructor(){super(...arguments),s(this,"flush",(()=>{this.context.cache.flush()}))}}class d{constructor(e,t){s(this,"language"),s(this,"region"),s(this,"script"),s(this,"isRtl"),s(this,"name"),s(this,"localizedName"),s(this,"uri"),s(this,"timestamp"),s(this,"baseLocale"),this.language=e.language,this.region=e.region,this.script=e.script,this.isRtl=e.isRtl,this.name=e.name,this.localizedName=e.localizedName,this.uri=e.uri,this.timestamp=e.timestamp,this.baseLocale=t}get locale(){return this.language&&this.region&&this.script?`${this.language}_${this.region}#${this.script}`:this.language&&this.script?`${this.language}#${this.script}`:this.language&&this.region?`${this.language}_${this.region}`:this.language}get isBaseLocale(){return this.locale===this.baseLocale}toCdnLocale(){return{locale:this.locale,isBaseLocale:this.isBaseLocale,language:this.language,region:this.region,script:this.script,isRtl:this.isRtl,name:this.name,localizedName:this.localizedName}}}class m{constructor(e){s(this,"id"),s(this,"file"),s(this,"path"),s(this,"library"),s(this,"module"),s(this,"buildType"),s(this,"timestamp"),s(this,"productFlavors"),s(this,"locales"),s(this,"baseUrl"),this.id=e.id,this.file=e.file,this.path=e.path,this.library=e.library,this.module=e.module,this.buildType=e.buildType,this.timestamp=e.timestamp,this.productFlavors=e.productFlavors,this.locales=e.locales,this.baseUrl=e.baseUrl}toCdnFile(){return{id:this.id,file:this.file,path:this.path,library:this.library,module:this.module,buildType:this.buildType,productFlavors:this.productFlavors,locales:this.locales.map((e=>({locale:e.locale,isBaseLocale:e.isBaseLocale,uri:`${this.baseUrl}${e.uri}`})))}}}class g{constructor(e,t){s(this,"projectUrl"),s(this,"baseLocale"),s(this,"locales"),s(this,"timestamp"),s(this,"files"),s(this,"filesMap"),this.projectUrl=e.projectUrl,this.timestamp=e.timestamp,this.files=g.filesFactory(e.files,e.baseLocale,t),this.filesMap=g.filesMapFactory(this.files),this.locales=g.localesFactory(this.files),this.baseLocale=this.locales.find((e=>e.isBaseLocale))}static createEmpty(e){return new g({projectUrl:"",baseLocale:"",timestamp:0,files:{}},e)}static filesFactory(e,t,s){return Object.keys(e).reduce(((i,a)=>{const l=e[a].locales.map((e=>new d(e,t)));return i.push(new m({...e[a],id:a,locales:l,baseUrl:s.baseUrl})),i}),[])}static filesMapFactory(e){return e.reduce(((e,t)=>(e[t.id]=t,e)),{})}static localesFactory(e){const t=e.reduce(((e,t)=>(e.push(...t.locales.map((e=>e.toCdnLocale()))),e)),[]);return c(t,(e=>e.locale))}}class w{constructor(e){s(this,"options"),this.options=w.parseMetafileUrl(e)}get url(){return this.options.url}get baseUrl(){return this.options.baseUrl}get cdnId(){return this.options.cdnId}get jsonPath(){return this.options.jsonPath}static parseMetafileUrl(e){let t;try{t=new URL(e)}catch(e){throw new Error('Invalid param: "options.metafile" cannot be parsed as url.')}const s=t.pathname.match(/^\/(.*?)\/(.*?)\.(v2.json|js|ts)$/);if(null===s||4!==s.length)throw new Error('Invalid param: "options.metafile" contains invalid metafile url.');const i=s[1],a=s[2];return{url:e,baseUrl:t.origin,cdnId:i,jsonPath:`/${i}/${a}.v2.json`}}}class y{constructor(e){s(this,"params"),s(this,"parsedData"),s(this,"data"),this.params=new w(e.metafile),this.parsedData=null,this.data=g.createEmpty(this.params)}setMetafile(e){this.parsedData=e,this.data=new g(e,this.params)}}class x{constructor(e){s(this,"context"),this.context=e}createCdnResponse(e){const{requests:t,responses:s,hasSingleFileResponse:i,hasSingleLocaleResponse:a}=e;return 0===s.length?{}:(this.cacheResponses(t,s),i&&a?s[0]:x.transformResponses(e))}cacheResponses(e,t){t.forEach(((t,s)=>{const{metafileFile:i,metafileLocale:a}=e[s];i&&a&&this.context.cache.setIfMissed({metafileFile:i,metafileLocale:a,data:t})}))}static transformResponses(e){const{requests:t,responses:s,hasSingleFileResponse:i}=e;return s.reduce(((e,s,a)=>{const{metafileFile:l,metafileLocale:r}=t[a];return l&&r&&(i?e[r.locale]=s:(e[l.id]||(e[l.id]={}),e[l.id][r.locale]=s)),e}),{})}}class b{constructor(e){s(this,"metafile"),s(this,"cdn"),s(this,"client"),s(this,"api"),s(this,"cache"),s(this,"responseFactory"),this.metafile=e.metafileContext,this.cdn=e.cdn,this.client=e.client,this.api=new i(this),this.cache=new u(this),this.responseFactory=new x(this)}}class F extends p{constructor(){super(...arguments),s(this,"locales",(e=>{const{excludeBaseLocale:t}=e||{},{locales:s}=this.context.metafile.data;return t?s.filter((e=>!e.isBaseLocale)):s})),s(this,"refresh",(async()=>{const e=await this.context.api.fetchMetafile();this.context.metafile.setMetafile(e)})),s(this,"switch",(async e=>{this.context.metafile.params=new w(e.metafile),await this.refresh()}))}get projectUrl(){return this.context.metafile.data.projectUrl}get baseLocale(){return this.context.metafile.data.baseLocale}get url(){return this.context.metafile.params.url}get files(){return this.context.metafile.data.files.map((e=>e.toCdnFile()))}}class L{constructor(e){s(this,"data"),s(this,"context"),this.context=e.context,this.data=e.data||{}}}class M{constructor(e){s(this,"files"),s(this,"localesMap"),s(this,"hasSingleFileResponse"),s(this,"hasSingleLocaleResponse"),s(this,"context"),this.files=[],this.localesMap=new L({context:e}),this.hasSingleFileResponse=!1,this.hasSingleLocaleResponse=!1,this.context=e}async execute(){const e=this.getPromises(),t=e.map((e=>e[0])),s=e.map((e=>e[1])),i=await Promise.all(t);return this.context.responseFactory.createCdnResponse({requests:s,responses:i,localesMap:this.localesMap,hasSingleFileResponse:this.hasSingleFileResponse,hasSingleLocaleResponse:this.hasSingleLocaleResponse})}getPromises(){return this.files.reduce(((e,t)=>(this.localesMap.data[t.id]&&e.push(...this.localesMap.data[t.id].map((e=>{const s={metafileFile:t,metafileLocale:e};return[this.context.api.fetchLocale(s),s]}))),e)),[])}}class q{constructor(e){s(this,"context"),s(this,"request"),this.context=e,this.request=new M(this.context)}addFiles(e){if(!(o(e)||a(e)||l(e)||r(e)))throw new Error('Invalid param: "request.files" must be object, array, string or undefined.');if(r(e)&&e.forEach((e=>{if(!o(e)&&!a(e))throw new Error('Invalid param: array "request.files" must contain objects or strings.')})),a(e)){this.request.hasSingleFileResponse=!0;const t=this.context.metafile.data.files.find((t=>t.id===e));if(!(t instanceof m))throw new Error(`File not found: "${e}".`);this.request.files=[t]}else if(l(e))this.request.files=[...this.context.metafile.data.files];else if(r(e))this.request.files=e.map((e=>{let t;if(a(e)){const s=this.context.metafile.data.files.find((t=>t.id===e));if(l(s))throw new Error(`File not found: "${e}".`);t=s}else{const s=this.context.metafile.data.files.find((t=>t.id===e.id));if(l(s))throw new Error(`File not found: "${e.id}".`);t=s}return t}));else if(o(e)){this.request.hasSingleFileResponse=!0;const t=this.context.metafile.data.files.find((t=>t.id===e.id));if(l(t))throw new Error(`File not found: "${e.id}".`);this.request.files=[t]}return this}addLocales(e,t){if(!(a(e)||l(e)||r(e)))throw new Error('Invalid param: "request.locales" must be array, string or undefined.');return r(e)&&e.forEach((e=>{if(!a(e))throw new Error('Invalid param: array "request.locales" must contain strings.')})),a(e)?(this.request.hasSingleLocaleResponse=!0,this.request.files.reduce(((t,s)=>(t.data[s.id]=s.locales.filter((t=>t.locale===e)),t)),this.request.localesMap)):l(e)?this.request.files.reduce(((e,s)=>(e.data[s.id]=t?s.locales.filter((e=>!e.isBaseLocale)):s.locales,e)),this.request.localesMap):r(e)&&this.request.files.reduce(((t,s)=>(t.data[s.id]=s.locales.filter((t=>e.includes(t.locale))),t)),this.request.localesMap),this}getCdnRequest(){const e=this.request;return this.request=new M(this.context),e}}class R{constructor(e){s(this,"baseUrl"),this.baseUrl=e}async get(e){const t=await fetch(`${this.baseUrl}${e}`),s=t.headers.get("content-type")||"",i=["application/json5","application/json"].includes(s);if(t.status>=400)throw new Error(`Request failed with status code ${t.status}`);let a;if(i)try{a=await t.json()}catch(e){a={}}else try{a=await t.text()}catch(e){a=""}return a}}const j=class e{constructor(e){s(this,"metafile"),s(this,"cache"),s(this,"context"),s(this,"fetch",(async e=>{const{files:t,locales:s,excludeBaseLocale:i}=e||{};return new q(this.context).addFiles(t).addLocales(s,i).getCdnRequest().execute()}));const t=new y(e),i=new R(t.params.baseUrl);this.context=new b({metafileContext:t,cdn:this,client:i}),this.metafile=new F(this.context),this.cache=new f(this.context)}static async create(t){if(!t)throw new Error('Invalid param: missing required "options" parameter.');if(!a(t.metafile))throw new Error('Invalid param: "options.metafile" must be string.');const s=new e(t);return await s.metafile.refresh(),s}};s(j,"version","1.5.0");let U=j;e.Api=i,e.CdnBase=p,e.CdnCache=f,e.CdnClient=U,e.CdnMetafile=F,e.Context=b,e.FetchHttpAdapter=R,e.LocalesCache=u,e.LocalesMap=L,e.MemoryCacheAdapter=h,e.MetafileContext=y,e.MetafileData=g,e.MetafileFile=m,e.MetafileLocale=d,e.MetafileParams=w,e.Request=M,e.RequestBuilder=q,e.ResponseFactory=x,e.isArray=r,e.isPlainObject=o,e.isString=a,e.isUndefined=l,e.uniq=n,e.uniqBy=c,Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})}));
//# sourceMappingURL=localazy-cdn-client.umd.min.js.map

@@ -10,6 +10,2 @@ export declare class Api {

export declare type ApiRequestConfig = object & {
reference: ApiLocaleRequest;
};
export declare type CacheGetLocalesRequest = ILocalesCacheItem;

@@ -38,2 +34,3 @@

protected context: Context;
static version: string;
protected constructor(options: CdnClientOptions);

@@ -120,12 +117,2 @@ fetch: (options?: CdnFetchOptions) => Promise<CdnResponse>;

export declare type CdnFilesSearchOptions = ((file: CdnFile, index?: number, array?: CdnFile[]) => boolean) | {
id?: string;
file?: string;
path?: string;
library?: string;
module?: string;
buildType?: string;
productFlavors?: string[];
};
export declare type CdnLocale = {

@@ -226,6 +213,2 @@ /**

export declare type ExcludeBaseLocale = {
excludeBaseLocale?: boolean;
};
export declare class FetchHttpAdapter implements IHttpAdapter {

@@ -237,6 +220,2 @@ protected baseUrl: string;

export declare type FileResponse = {
[fileId: string]: LocaleResponse;
};
export declare type FilesMap = {

@@ -243,0 +222,0 @@ [id: string]: MetafileFile;

@@ -7,6 +7,5 @@ var __defProp = Object.defineProperty;

};
/* @localazy/cdn-client@1.4.1
/* @localazy/cdn-client@1.5.0
* (c) 2024 Localazy <team@localazy.com>
* @license MIT */
import "isomorphic-fetch";
class Api {

@@ -204,7 +203,9 @@ constructor(context) {

productFlavors: this.productFlavors,
locales: this.locales.map((locale) => ({
locale: locale.locale,
isBaseLocale: locale.isBaseLocale,
uri: `${this.baseUrl}${locale.uri}`
}))
locales: this.locales.map(
(locale) => ({
locale: locale.locale,
isBaseLocale: locale.isBaseLocale,
uri: `${this.baseUrl}${locale.uri}`
})
)
};

@@ -240,41 +241,28 @@ }

static filesFactory(files, baseLocale, params) {
return Object.keys(files).reduce(
(acc, cur) => {
const locales = files[cur].locales.map(
(locale) => new MetafileLocale(locale, baseLocale)
);
acc.push(
new MetafileFile({
...files[cur],
id: cur,
locales,
baseUrl: params.baseUrl
})
);
return acc;
},
[]
);
return Object.keys(files).reduce((acc, cur) => {
const locales = files[cur].locales.map(
(locale) => new MetafileLocale(locale, baseLocale)
);
acc.push(
new MetafileFile({
...files[cur],
id: cur,
locales,
baseUrl: params.baseUrl
})
);
return acc;
}, []);
}
static filesMapFactory(files) {
return files.reduce(
(acc, cur) => {
acc[cur.id] = cur;
return acc;
},
{}
);
return files.reduce((acc, cur) => {
acc[cur.id] = cur;
return acc;
}, {});
}
static localesFactory(files) {
const locales = files.reduce(
(acc, cur) => {
acc.push(
...cur.locales.map(
(locale) => locale.toCdnLocale()
)
);
return acc;
},
[]
);
const locales = files.reduce((acc, cur) => {
acc.push(...cur.locales.map((locale) => locale.toCdnLocale()));
return acc;
}, []);
return uniqBy(locales, (cdnLocale) => cdnLocale.locale);

@@ -341,8 +329,3 @@ }

createCdnResponse(options) {
const {
requests,
responses,
hasSingleFileResponse,
hasSingleLocaleResponse
} = options;
const { requests, responses, hasSingleFileResponse, hasSingleLocaleResponse } = options;
if (responses.length === 0) {

@@ -356,6 +339,3 @@ return {};

responses.forEach((response, index) => {
const {
metafileFile,
metafileLocale
} = requests[index];
const { metafileFile, metafileLocale } = requests[index];
if (metafileFile && metafileLocale) {

@@ -368,22 +348,16 @@ this.context.cache.setIfMissed({ metafileFile, metafileLocale, data: response });

const { requests, responses, hasSingleFileResponse } = options;
return responses.reduce(
(acc, cur, index) => {
const {
metafileFile,
metafileLocale
} = requests[index];
if (metafileFile && metafileLocale) {
if (hasSingleFileResponse) {
acc[metafileLocale.locale] = cur;
} else {
if (!acc[metafileFile.id]) {
acc[metafileFile.id] = {};
}
acc[metafileFile.id][metafileLocale.locale] = cur;
return responses.reduce((acc, cur, index) => {
const { metafileFile, metafileLocale } = requests[index];
if (metafileFile && metafileLocale) {
if (hasSingleFileResponse) {
acc[metafileLocale.locale] = cur;
} else {
if (!acc[metafileFile.id]) {
acc[metafileFile.id] = {};
}
acc[metafileFile.id][metafileLocale.locale] = cur;
}
return acc;
},
{}
);
}
return acc;
}, {});
}

@@ -463,5 +437,3 @@ }

);
const requests = payload.map(
(item) => item[1]
);
const requests = payload.map((item) => item[1]);
const responses = await Promise.all(promises);

@@ -477,24 +449,18 @@ return this.context.responseFactory.createCdnResponse({

getPromises() {
return this.files.reduce(
(acc, cur) => {
if (this.localesMap.data[cur.id]) {
acc.push(
...this.localesMap.data[cur.id].map(
(metafileLocale) => {
const request = {
metafileFile: cur,
metafileLocale
};
return [
this.context.api.fetchLocale(request),
request
];
}
)
);
}
return acc;
},
[]
);
return this.files.reduce((acc, cur) => {
if (this.localesMap.data[cur.id]) {
acc.push(
...this.localesMap.data[cur.id].map(
(metafileLocale) => {
const request = {
metafileFile: cur,
metafileLocale
};
return [this.context.api.fetchLocale(request), request];
}
)
);
}
return acc;
}, []);
}

@@ -578,29 +544,20 @@ }

this.request.hasSingleLocaleResponse = true;
this.request.files.reduce(
(acc, cur) => {
acc.data[cur.id] = cur.locales.filter(
(metafileLocale) => metafileLocale.locale === locales
);
return acc;
},
this.request.localesMap
);
this.request.files.reduce((acc, cur) => {
acc.data[cur.id] = cur.locales.filter(
(metafileLocale) => metafileLocale.locale === locales
);
return acc;
}, this.request.localesMap);
} else if (isUndefined(locales)) {
this.request.files.reduce(
(acc, cur) => {
acc.data[cur.id] = excludeBaseLocale ? cur.locales.filter((metafileLocale) => !metafileLocale.isBaseLocale) : cur.locales;
return acc;
},
this.request.localesMap
);
this.request.files.reduce((acc, cur) => {
acc.data[cur.id] = excludeBaseLocale ? cur.locales.filter((metafileLocale) => !metafileLocale.isBaseLocale) : cur.locales;
return acc;
}, this.request.localesMap);
} else if (isArray(locales)) {
this.request.files.reduce(
(acc, cur) => {
acc.data[cur.id] = cur.locales.filter(
(metafileLocale) => locales.includes(metafileLocale.locale)
);
return acc;
},
this.request.localesMap
);
this.request.files.reduce((acc, cur) => {
acc.data[cur.id] = cur.locales.filter(
(metafileLocale) => locales.includes(metafileLocale.locale)
);
return acc;
}, this.request.localesMap);
}

@@ -623,10 +580,7 @@ return this;

const contentType = response.headers.get("content-type") || "";
const isJson = [
"application/json5",
"application/json"
].includes(contentType);
const isJson = ["application/json5", "application/json"].includes(contentType);
if (response.status >= 400) {
throw new Error(`Request failed with status code ${response.status}`);
}
let result = "";
let result;
if (isJson) {

@@ -648,3 +602,3 @@ try {

}
class CdnClient {
const _CdnClient = class _CdnClient {
constructor(options) {

@@ -672,7 +626,9 @@ __publicField(this, "metafile");

}
const cdn = new CdnClient(options);
const cdn = new _CdnClient(options);
await cdn.metafile.refresh();
return cdn;
}
}
};
__publicField(_CdnClient, "version", "1.5.0");
let CdnClient = _CdnClient;
export {

@@ -679,0 +635,0 @@ Api,

@@ -1,6 +0,6 @@

var t=Object.defineProperty,e=(e,s,i)=>(((e,s,i)=>{s in e?t(e,s,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[s]=i})(e,"symbol"!=typeof s?s+"":s,i),i);
/* @localazy/cdn-client@1.4.1
var e=Object.defineProperty,t=(t,s,i)=>(((t,s,i)=>{s in t?e(t,s,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[s]=i})(t,"symbol"!=typeof s?s+"":s,i),i);
/* @localazy/cdn-client@1.5.0
* (c) 2024 Localazy <team@localazy.com>
* @license MIT */
import"isomorphic-fetch";class s{constructor(t){e(this,"context"),this.context=t}async fetchLocale(t){return this.context.cache.has(t)?new Promise((e=>{e(this.context.cache.get(t))})):this.context.client.get(t.metafileLocale.uri)}async fetchMetafile(){return await this.context.client.get(this.context.metafile.params.jsonPath)}}const i=t=>"string"==typeof t,a=t=>void 0===t,l=t=>Array.isArray(t),r=t=>"[object Object]"===Object.prototype.toString.call(t),o=t=>[...new Set(t)],c=(t,e)=>{const s={};return t.filter((t=>{const i=e(t);return!Object.hasOwn(s,i)&&(s[i]=!0,!0)}))};class n{constructor(){e(this,"map"),this.map=new Map}get(t){return this.map.get(t)}has(t){return this.map.has(t)}set(t,e){this.map.set(t,e)}flush(){this.map=new Map}}class h{constructor(t){e(this,"context"),e(this,"cacheAdapter"),this.context=t,this.cacheAdapter=new n}setIfMissed(t){const{metafileFile:e,metafileLocale:s,data:i}=t,a=this.keyFromMetafile({metafileFile:e,metafileLocale:s});this.cacheAdapter.has(a)||this.cacheAdapter.set(a,i)}has(t){const e=this.keyFromMetafile(t);return this.cacheAdapter.has(e)}get(t){const e=this.keyFromMetafile(t);return this.cacheAdapter.get(e)}flush(){this.cacheAdapter.flush()}keyFromMetafile(t){const{metafileFile:e,metafileLocale:s}=t,i=[...o(e.productFlavors)].sort().join("-");return[this.context.metafile.params.cdnId,e.id,e.file,e.path,e.library,e.module,e.buildType,i,s.locale,s.timestamp.toString()].filter((t=>""!==t)).join("-")}}class u{constructor(t){e(this,"context"),this.context=t}}class p extends u{constructor(){super(...arguments),e(this,"flush",(()=>{this.context.cache.flush()}))}}class f{constructor(t,s){e(this,"language"),e(this,"region"),e(this,"script"),e(this,"isRtl"),e(this,"name"),e(this,"localizedName"),e(this,"uri"),e(this,"timestamp"),e(this,"baseLocale"),this.language=t.language,this.region=t.region,this.script=t.script,this.isRtl=t.isRtl,this.name=t.name,this.localizedName=t.localizedName,this.uri=t.uri,this.timestamp=t.timestamp,this.baseLocale=s}get locale(){return this.language&&this.region&&this.script?`${this.language}_${this.region}#${this.script}`:this.language&&this.script?`${this.language}#${this.script}`:this.language&&this.region?`${this.language}_${this.region}`:this.language}get isBaseLocale(){return this.locale===this.baseLocale}toCdnLocale(){return{locale:this.locale,isBaseLocale:this.isBaseLocale,language:this.language,region:this.region,script:this.script,isRtl:this.isRtl,name:this.name,localizedName:this.localizedName}}}class d{constructor(t){e(this,"id"),e(this,"file"),e(this,"path"),e(this,"library"),e(this,"module"),e(this,"buildType"),e(this,"timestamp"),e(this,"productFlavors"),e(this,"locales"),e(this,"baseUrl"),this.id=t.id,this.file=t.file,this.path=t.path,this.library=t.library,this.module=t.module,this.buildType=t.buildType,this.timestamp=t.timestamp,this.productFlavors=t.productFlavors,this.locales=t.locales,this.baseUrl=t.baseUrl}toCdnFile(){return{id:this.id,file:this.file,path:this.path,library:this.library,module:this.module,buildType:this.buildType,productFlavors:this.productFlavors,locales:this.locales.map((t=>({locale:t.locale,isBaseLocale:t.isBaseLocale,uri:`${this.baseUrl}${t.uri}`})))}}}class m{constructor(t,s){e(this,"projectUrl"),e(this,"baseLocale"),e(this,"locales"),e(this,"timestamp"),e(this,"files"),e(this,"filesMap"),this.projectUrl=t.projectUrl,this.timestamp=t.timestamp,this.files=m.filesFactory(t.files,t.baseLocale,s),this.filesMap=m.filesMapFactory(this.files),this.locales=m.localesFactory(this.files),this.baseLocale=this.locales.find((t=>t.isBaseLocale))}static createEmpty(t){return new m({projectUrl:"",baseLocale:"",timestamp:0,files:{}},t)}static filesFactory(t,e,s){return Object.keys(t).reduce(((i,a)=>{const l=t[a].locales.map((t=>new f(t,e)));return i.push(new d({...t[a],id:a,locales:l,baseUrl:s.baseUrl})),i}),[])}static filesMapFactory(t){return t.reduce(((t,e)=>(t[e.id]=e,t)),{})}static localesFactory(t){const e=t.reduce(((t,e)=>(t.push(...e.locales.map((t=>t.toCdnLocale()))),t)),[]);return c(e,(t=>t.locale))}}class g{constructor(t){e(this,"options"),this.options=g.parseMetafileUrl(t)}get url(){return this.options.url}get baseUrl(){return this.options.baseUrl}get cdnId(){return this.options.cdnId}get jsonPath(){return this.options.jsonPath}static parseMetafileUrl(t){let e;try{e=new URL(t)}catch(t){throw new Error('Invalid param: "options.metafile" cannot be parsed as url.')}const s=e.pathname.match(/^\/(.*?)\/(.*?)\.(v2.json|js|ts)$/);if(null===s||4!==s.length)throw new Error('Invalid param: "options.metafile" contains invalid metafile url.');const i=s[1],a=s[2];return{url:t,baseUrl:e.origin,cdnId:i,jsonPath:`/${i}/${a}.v2.json`}}}class w{constructor(t){e(this,"params"),e(this,"parsedData"),e(this,"data"),this.params=new g(t.metafile),this.parsedData=null,this.data=m.createEmpty(this.params)}setMetafile(t){this.parsedData=t,this.data=new m(t,this.params)}}class x{constructor(t){e(this,"context"),this.context=t}createCdnResponse(t){const{requests:e,responses:s,hasSingleFileResponse:i,hasSingleLocaleResponse:a}=t;return 0===s.length?{}:(this.cacheResponses(e,s),i&&a?s[0]:x.transformResponses(t))}cacheResponses(t,e){e.forEach(((e,s)=>{const{metafileFile:i,metafileLocale:a}=t[s];i&&a&&this.context.cache.setIfMissed({metafileFile:i,metafileLocale:a,data:e})}))}static transformResponses(t){const{requests:e,responses:s,hasSingleFileResponse:i}=t;return s.reduce(((t,s,a)=>{const{metafileFile:l,metafileLocale:r}=e[a];return l&&r&&(i?t[r.locale]=s:(t[l.id]||(t[l.id]={}),t[l.id][r.locale]=s)),t}),{})}}class y{constructor(t){e(this,"metafile"),e(this,"cdn"),e(this,"client"),e(this,"api"),e(this,"cache"),e(this,"responseFactory"),this.metafile=t.metafileContext,this.cdn=t.cdn,this.client=t.client,this.api=new s(this),this.cache=new h(this),this.responseFactory=new x(this)}}class b extends u{constructor(){super(...arguments),e(this,"locales",(t=>{const{excludeBaseLocale:e}=t||{},{locales:s}=this.context.metafile.data;return e?s.filter((t=>!t.isBaseLocale)):s})),e(this,"refresh",(async()=>{const t=await this.context.api.fetchMetafile();this.context.metafile.setMetafile(t)})),e(this,"switch",(async t=>{this.context.metafile.params=new g(t.metafile),await this.refresh()}))}get projectUrl(){return this.context.metafile.data.projectUrl}get baseLocale(){return this.context.metafile.data.baseLocale}get url(){return this.context.metafile.params.url}get files(){return this.context.metafile.data.files.map((t=>t.toCdnFile()))}}class F{constructor(t){e(this,"data"),e(this,"context"),this.context=t.context,this.data=t.data||{}}}class L{constructor(t){e(this,"files"),e(this,"localesMap"),e(this,"hasSingleFileResponse"),e(this,"hasSingleLocaleResponse"),e(this,"context"),this.files=[],this.localesMap=new F({context:t}),this.hasSingleFileResponse=!1,this.hasSingleLocaleResponse=!1,this.context=t}async execute(){const t=this.getPromises(),e=t.map((t=>t[0])),s=t.map((t=>t[1])),i=await Promise.all(e);return this.context.responseFactory.createCdnResponse({requests:s,responses:i,localesMap:this.localesMap,hasSingleFileResponse:this.hasSingleFileResponse,hasSingleLocaleResponse:this.hasSingleLocaleResponse})}getPromises(){return this.files.reduce(((t,e)=>(this.localesMap.data[e.id]&&t.push(...this.localesMap.data[e.id].map((t=>{const s={metafileFile:e,metafileLocale:t};return[this.context.api.fetchLocale(s),s]}))),t)),[])}}class R{constructor(t){e(this,"context"),e(this,"request"),this.context=t,this.request=new L(this.context)}addFiles(t){if(!(r(t)||i(t)||a(t)||l(t)))throw new Error('Invalid param: "request.files" must be object, array, string or undefined.');if(l(t)&&t.forEach((t=>{if(!r(t)&&!i(t))throw new Error('Invalid param: array "request.files" must contain objects or strings.')})),i(t)){this.request.hasSingleFileResponse=!0;const e=this.context.metafile.data.files.find((e=>e.id===t));if(!(e instanceof d))throw new Error(`File not found: "${t}".`);this.request.files=[e]}else if(a(t))this.request.files=[...this.context.metafile.data.files];else if(l(t))this.request.files=t.map((t=>{let e;if(i(t)){const s=this.context.metafile.data.files.find((e=>e.id===t));if(a(s))throw new Error(`File not found: "${t}".`);e=s}else{const s=this.context.metafile.data.files.find((e=>e.id===t.id));if(a(s))throw new Error(`File not found: "${t.id}".`);e=s}return e}));else if(r(t)){this.request.hasSingleFileResponse=!0;const e=this.context.metafile.data.files.find((e=>e.id===t.id));if(a(e))throw new Error(`File not found: "${t.id}".`);this.request.files=[e]}return this}addLocales(t,e){if(!(i(t)||a(t)||l(t)))throw new Error('Invalid param: "request.locales" must be array, string or undefined.');return l(t)&&t.forEach((t=>{if(!i(t))throw new Error('Invalid param: array "request.locales" must contain strings.')})),i(t)?(this.request.hasSingleLocaleResponse=!0,this.request.files.reduce(((e,s)=>(e.data[s.id]=s.locales.filter((e=>e.locale===t)),e)),this.request.localesMap)):a(t)?this.request.files.reduce(((t,s)=>(t.data[s.id]=e?s.locales.filter((t=>!t.isBaseLocale)):s.locales,t)),this.request.localesMap):l(t)&&this.request.files.reduce(((e,s)=>(e.data[s.id]=s.locales.filter((e=>t.includes(e.locale))),e)),this.request.localesMap),this}getCdnRequest(){const t=this.request;return this.request=new L(this.context),t}}class q{constructor(t){e(this,"baseUrl"),this.baseUrl=t}async get(t){const e=await fetch(`${this.baseUrl}${t}`),s=e.headers.get("content-type")||"",i=["application/json5","application/json"].includes(s);if(e.status>=400)throw new Error(`Request failed with status code ${e.status}`);let a="";if(i)try{a=await e.json()}catch(t){a={}}else try{a=await e.text()}catch(t){a=""}return a}}class M{constructor(t){e(this,"metafile"),e(this,"cache"),e(this,"context"),e(this,"fetch",(async t=>{const{files:e,locales:s,excludeBaseLocale:i}=t||{};return new R(this.context).addFiles(e).addLocales(s,i).getCdnRequest().execute()}));const s=new w(t),i=new q(s.params.baseUrl);this.context=new y({metafileContext:s,cdn:this,client:i}),this.metafile=new b(this.context),this.cache=new p(this.context)}static async create(t){if(!t)throw new Error('Invalid param: missing required "options" parameter.');if(!i(t.metafile))throw new Error('Invalid param: "options.metafile" must be string.');const e=new M(t);return await e.metafile.refresh(),e}}export{s as Api,u as CdnBase,p as CdnCache,M as CdnClient,b as CdnMetafile,y as Context,q as FetchHttpAdapter,h as LocalesCache,F as LocalesMap,n as MemoryCacheAdapter,w as MetafileContext,m as MetafileData,d as MetafileFile,f as MetafileLocale,g as MetafileParams,L as Request,R as RequestBuilder,x as ResponseFactory,l as isArray,r as isPlainObject,i as isString,a as isUndefined,o as uniq,c as uniqBy};
class s{constructor(e){t(this,"context"),this.context=e}async fetchLocale(e){return this.context.cache.has(e)?new Promise((t=>{t(this.context.cache.get(e))})):this.context.client.get(e.metafileLocale.uri)}async fetchMetafile(){return await this.context.client.get(this.context.metafile.params.jsonPath)}}const i=e=>"string"==typeof e,a=e=>void 0===e,l=e=>Array.isArray(e),r=e=>"[object Object]"===Object.prototype.toString.call(e),o=e=>[...new Set(e)],c=(e,t)=>{const s={};return e.filter((e=>{const i=t(e);return!Object.hasOwn(s,i)&&(s[i]=!0,!0)}))};class n{constructor(){t(this,"map"),this.map=new Map}get(e){return this.map.get(e)}has(e){return this.map.has(e)}set(e,t){this.map.set(e,t)}flush(){this.map=new Map}}class h{constructor(e){t(this,"context"),t(this,"cacheAdapter"),this.context=e,this.cacheAdapter=new n}setIfMissed(e){const{metafileFile:t,metafileLocale:s,data:i}=e,a=this.keyFromMetafile({metafileFile:t,metafileLocale:s});this.cacheAdapter.has(a)||this.cacheAdapter.set(a,i)}has(e){const t=this.keyFromMetafile(e);return this.cacheAdapter.has(t)}get(e){const t=this.keyFromMetafile(e);return this.cacheAdapter.get(t)}flush(){this.cacheAdapter.flush()}keyFromMetafile(e){const{metafileFile:t,metafileLocale:s}=e,i=[...o(t.productFlavors)].sort().join("-");return[this.context.metafile.params.cdnId,t.id,t.file,t.path,t.library,t.module,t.buildType,i,s.locale,s.timestamp.toString()].filter((e=>""!==e)).join("-")}}class u{constructor(e){t(this,"context"),this.context=e}}class p extends u{constructor(){super(...arguments),t(this,"flush",(()=>{this.context.cache.flush()}))}}class f{constructor(e,s){t(this,"language"),t(this,"region"),t(this,"script"),t(this,"isRtl"),t(this,"name"),t(this,"localizedName"),t(this,"uri"),t(this,"timestamp"),t(this,"baseLocale"),this.language=e.language,this.region=e.region,this.script=e.script,this.isRtl=e.isRtl,this.name=e.name,this.localizedName=e.localizedName,this.uri=e.uri,this.timestamp=e.timestamp,this.baseLocale=s}get locale(){return this.language&&this.region&&this.script?`${this.language}_${this.region}#${this.script}`:this.language&&this.script?`${this.language}#${this.script}`:this.language&&this.region?`${this.language}_${this.region}`:this.language}get isBaseLocale(){return this.locale===this.baseLocale}toCdnLocale(){return{locale:this.locale,isBaseLocale:this.isBaseLocale,language:this.language,region:this.region,script:this.script,isRtl:this.isRtl,name:this.name,localizedName:this.localizedName}}}class d{constructor(e){t(this,"id"),t(this,"file"),t(this,"path"),t(this,"library"),t(this,"module"),t(this,"buildType"),t(this,"timestamp"),t(this,"productFlavors"),t(this,"locales"),t(this,"baseUrl"),this.id=e.id,this.file=e.file,this.path=e.path,this.library=e.library,this.module=e.module,this.buildType=e.buildType,this.timestamp=e.timestamp,this.productFlavors=e.productFlavors,this.locales=e.locales,this.baseUrl=e.baseUrl}toCdnFile(){return{id:this.id,file:this.file,path:this.path,library:this.library,module:this.module,buildType:this.buildType,productFlavors:this.productFlavors,locales:this.locales.map((e=>({locale:e.locale,isBaseLocale:e.isBaseLocale,uri:`${this.baseUrl}${e.uri}`})))}}}class m{constructor(e,s){t(this,"projectUrl"),t(this,"baseLocale"),t(this,"locales"),t(this,"timestamp"),t(this,"files"),t(this,"filesMap"),this.projectUrl=e.projectUrl,this.timestamp=e.timestamp,this.files=m.filesFactory(e.files,e.baseLocale,s),this.filesMap=m.filesMapFactory(this.files),this.locales=m.localesFactory(this.files),this.baseLocale=this.locales.find((e=>e.isBaseLocale))}static createEmpty(e){return new m({projectUrl:"",baseLocale:"",timestamp:0,files:{}},e)}static filesFactory(e,t,s){return Object.keys(e).reduce(((i,a)=>{const l=e[a].locales.map((e=>new f(e,t)));return i.push(new d({...e[a],id:a,locales:l,baseUrl:s.baseUrl})),i}),[])}static filesMapFactory(e){return e.reduce(((e,t)=>(e[t.id]=t,e)),{})}static localesFactory(e){const t=e.reduce(((e,t)=>(e.push(...t.locales.map((e=>e.toCdnLocale()))),e)),[]);return c(t,(e=>e.locale))}}class g{constructor(e){t(this,"options"),this.options=g.parseMetafileUrl(e)}get url(){return this.options.url}get baseUrl(){return this.options.baseUrl}get cdnId(){return this.options.cdnId}get jsonPath(){return this.options.jsonPath}static parseMetafileUrl(e){let t;try{t=new URL(e)}catch(e){throw new Error('Invalid param: "options.metafile" cannot be parsed as url.')}const s=t.pathname.match(/^\/(.*?)\/(.*?)\.(v2.json|js|ts)$/);if(null===s||4!==s.length)throw new Error('Invalid param: "options.metafile" contains invalid metafile url.');const i=s[1],a=s[2];return{url:e,baseUrl:t.origin,cdnId:i,jsonPath:`/${i}/${a}.v2.json`}}}class w{constructor(e){t(this,"params"),t(this,"parsedData"),t(this,"data"),this.params=new g(e.metafile),this.parsedData=null,this.data=m.createEmpty(this.params)}setMetafile(e){this.parsedData=e,this.data=new m(e,this.params)}}class x{constructor(e){t(this,"context"),this.context=e}createCdnResponse(e){const{requests:t,responses:s,hasSingleFileResponse:i,hasSingleLocaleResponse:a}=e;return 0===s.length?{}:(this.cacheResponses(t,s),i&&a?s[0]:x.transformResponses(e))}cacheResponses(e,t){t.forEach(((t,s)=>{const{metafileFile:i,metafileLocale:a}=e[s];i&&a&&this.context.cache.setIfMissed({metafileFile:i,metafileLocale:a,data:t})}))}static transformResponses(e){const{requests:t,responses:s,hasSingleFileResponse:i}=e;return s.reduce(((e,s,a)=>{const{metafileFile:l,metafileLocale:r}=t[a];return l&&r&&(i?e[r.locale]=s:(e[l.id]||(e[l.id]={}),e[l.id][r.locale]=s)),e}),{})}}class y{constructor(e){t(this,"metafile"),t(this,"cdn"),t(this,"client"),t(this,"api"),t(this,"cache"),t(this,"responseFactory"),this.metafile=e.metafileContext,this.cdn=e.cdn,this.client=e.client,this.api=new s(this),this.cache=new h(this),this.responseFactory=new x(this)}}class b extends u{constructor(){super(...arguments),t(this,"locales",(e=>{const{excludeBaseLocale:t}=e||{},{locales:s}=this.context.metafile.data;return t?s.filter((e=>!e.isBaseLocale)):s})),t(this,"refresh",(async()=>{const e=await this.context.api.fetchMetafile();this.context.metafile.setMetafile(e)})),t(this,"switch",(async e=>{this.context.metafile.params=new g(e.metafile),await this.refresh()}))}get projectUrl(){return this.context.metafile.data.projectUrl}get baseLocale(){return this.context.metafile.data.baseLocale}get url(){return this.context.metafile.params.url}get files(){return this.context.metafile.data.files.map((e=>e.toCdnFile()))}}class F{constructor(e){t(this,"data"),t(this,"context"),this.context=e.context,this.data=e.data||{}}}class L{constructor(e){t(this,"files"),t(this,"localesMap"),t(this,"hasSingleFileResponse"),t(this,"hasSingleLocaleResponse"),t(this,"context"),this.files=[],this.localesMap=new F({context:e}),this.hasSingleFileResponse=!1,this.hasSingleLocaleResponse=!1,this.context=e}async execute(){const e=this.getPromises(),t=e.map((e=>e[0])),s=e.map((e=>e[1])),i=await Promise.all(t);return this.context.responseFactory.createCdnResponse({requests:s,responses:i,localesMap:this.localesMap,hasSingleFileResponse:this.hasSingleFileResponse,hasSingleLocaleResponse:this.hasSingleLocaleResponse})}getPromises(){return this.files.reduce(((e,t)=>(this.localesMap.data[t.id]&&e.push(...this.localesMap.data[t.id].map((e=>{const s={metafileFile:t,metafileLocale:e};return[this.context.api.fetchLocale(s),s]}))),e)),[])}}class R{constructor(e){t(this,"context"),t(this,"request"),this.context=e,this.request=new L(this.context)}addFiles(e){if(!(r(e)||i(e)||a(e)||l(e)))throw new Error('Invalid param: "request.files" must be object, array, string or undefined.');if(l(e)&&e.forEach((e=>{if(!r(e)&&!i(e))throw new Error('Invalid param: array "request.files" must contain objects or strings.')})),i(e)){this.request.hasSingleFileResponse=!0;const t=this.context.metafile.data.files.find((t=>t.id===e));if(!(t instanceof d))throw new Error(`File not found: "${e}".`);this.request.files=[t]}else if(a(e))this.request.files=[...this.context.metafile.data.files];else if(l(e))this.request.files=e.map((e=>{let t;if(i(e)){const s=this.context.metafile.data.files.find((t=>t.id===e));if(a(s))throw new Error(`File not found: "${e}".`);t=s}else{const s=this.context.metafile.data.files.find((t=>t.id===e.id));if(a(s))throw new Error(`File not found: "${e.id}".`);t=s}return t}));else if(r(e)){this.request.hasSingleFileResponse=!0;const t=this.context.metafile.data.files.find((t=>t.id===e.id));if(a(t))throw new Error(`File not found: "${e.id}".`);this.request.files=[t]}return this}addLocales(e,t){if(!(i(e)||a(e)||l(e)))throw new Error('Invalid param: "request.locales" must be array, string or undefined.');return l(e)&&e.forEach((e=>{if(!i(e))throw new Error('Invalid param: array "request.locales" must contain strings.')})),i(e)?(this.request.hasSingleLocaleResponse=!0,this.request.files.reduce(((t,s)=>(t.data[s.id]=s.locales.filter((t=>t.locale===e)),t)),this.request.localesMap)):a(e)?this.request.files.reduce(((e,s)=>(e.data[s.id]=t?s.locales.filter((e=>!e.isBaseLocale)):s.locales,e)),this.request.localesMap):l(e)&&this.request.files.reduce(((t,s)=>(t.data[s.id]=s.locales.filter((t=>e.includes(t.locale))),t)),this.request.localesMap),this}getCdnRequest(){const e=this.request;return this.request=new L(this.context),e}}class q{constructor(e){t(this,"baseUrl"),this.baseUrl=e}async get(e){const t=await fetch(`${this.baseUrl}${e}`),s=t.headers.get("content-type")||"",i=["application/json5","application/json"].includes(s);if(t.status>=400)throw new Error(`Request failed with status code ${t.status}`);let a;if(i)try{a=await t.json()}catch(e){a={}}else try{a=await t.text()}catch(e){a=""}return a}}const M=class e{constructor(e){t(this,"metafile"),t(this,"cache"),t(this,"context"),t(this,"fetch",(async e=>{const{files:t,locales:s,excludeBaseLocale:i}=e||{};return new R(this.context).addFiles(t).addLocales(s,i).getCdnRequest().execute()}));const s=new w(e),i=new q(s.params.baseUrl);this.context=new y({metafileContext:s,cdn:this,client:i}),this.metafile=new b(this.context),this.cache=new p(this.context)}static async create(t){if(!t)throw new Error('Invalid param: missing required "options" parameter.');if(!i(t.metafile))throw new Error('Invalid param: "options.metafile" must be string.');const s=new e(t);return await s.metafile.refresh(),s}};t(M,"version","1.5.0");let j=M;export{s as Api,u as CdnBase,p as CdnCache,j as CdnClient,b as CdnMetafile,y as Context,q as FetchHttpAdapter,h as LocalesCache,F as LocalesMap,n as MemoryCacheAdapter,w as MetafileContext,m as MetafileData,d as MetafileFile,f as MetafileLocale,g as MetafileParams,L as Request,R as RequestBuilder,x as ResponseFactory,l as isArray,r as isPlainObject,i as isString,a as isUndefined,o as uniq,c as uniqBy};
//# sourceMappingURL=localazy-cdn-client.min.js.map
{
"name": "@localazy/cdn-client",
"version": "1.4.1",
"version": "1.5.0",
"description": "Node.js module that allows you to easily interact with the Localazy CDN.",

@@ -59,3 +59,3 @@ "author": "Localazy <team@localazy.com>",

"main-ts:watch": "reexport --watch src/main.ts",
"check": "npm run typecheck && npm run test:coverage && npm run lint",
"check": "npm run typecheck && npm run test:coverage && npm run lint && npm run prettier",
"typecheck": "npx tsc --noemit",

@@ -68,2 +68,4 @@ "test": "vitest",

"lint:fix": "npm run lint -- --fix",
"prettier": "prettier . --check",
"prettier:fix": "prettier . --write",
"typedoc": "npm run docs:html && npm run docs:md",

@@ -74,14 +76,11 @@ "typedoc:html": "rimraf typedoc/html/* && typedoc --plugin typedoc-plugin-missing-exports --tsconfig tsconfig.typedoc.json --out typedoc/html src/main.ts",

},
"dependencies": {
"isomorphic-fetch": "^3.0.0"
},
"devDependencies": {
"@localazy/conventional-changelog-preset": "github:localazy/conventional-changelog-preset",
"@localazy/conventional-changelog-preset": "^1.2.6",
"@rollup/plugin-terser": "^0.4.4",
"@types/isomorphic-fetch": "^0.0.39",
"@types/lodash": "^4.17.0",
"@types/node": "^20.11.26",
"@types/node": "^20.11.28",
"@typescript-eslint/eslint-plugin": "^7.2.0",
"@typescript-eslint/parser": "^7.2.0",
"@vitest/coverage-v8": "^1.3.1",
"@vitest/ui": "^1.3.1",
"@vitest/coverage-v8": "^1.4.0",
"@vitest/ui": "^1.4.0",
"conventional-changelog": "^5.1.0",

@@ -92,15 +91,23 @@ "conventional-changelog-cli": "^4.1.0",

"eslint": "^8.57.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-airbnb-typescript": "^18.0.0",
"eslint-config-node": "^4.1.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^5.1.3",
"fetch-mock": "^9.11.0",
"isomorphic-fetch": "^3.0.0",
"prettier": "^3.2.5",
"reexport": "^1.4.1",
"rollup-plugin-terser": "^7.0.2",
"typedoc": "^0.25.12",
"typedoc-plugin-markdown": "^3.17.1",
"typedoc-plugin-missing-exports": "^2.2.0",
"unplugin-replace": "^0.2.1",
"vite": "^5.1.6",
"vite-bundle-visualizer": "^1.1.0",
"vite-plugin-dts": "^3.7.3",
"vitest": "^1.3.1"
"vitest": "^1.4.0"
}
}

@@ -12,21 +12,58 @@ <div align="center">

[//]: # ([**Live Demo**]&#40;&#41;)
Node.js module that allows you to easily interact with the [Localazy CDN](https://localazy.com/docs/cdn/cdn-introduction).
[![coverage](.github/badges/version.svg)](https://www.npmjs.com/package/@localazy/cdn-client)
[![coverage](.github/badges/license.svg)](https://github.com/localazy/cdn-client/blob/main/LICENSE)
[![npm](.github/badges/npm.svg)](https://www.npmjs.com/package/@localazy/cdn-client)
[![maintainer](.github/badges/maintainer.svg)](https://github.com/localazy)
[![license](.github/badges/license.svg)](https://github.com/localazy/cdn-client/blob/main/LICENSE)<br>
[![coverage](.github/badges/coverage.svg)](https://github.com/localazy/cdn-client/actions)
[![size](.github/badges/size.svg)](https://bundlephobia.com/package/@localazy/cdn-client)
</div>
## 🔧 Install
## 🚀 Quick Start
```bash
npm install @localazy/cdn-client
# or use your favorite package manager
# or use your favourite package manager
```
For more information, visit the [installation guide](https://localazy.github.io/cdn-client/get-started/install.html).
```javascript
import { CdnClient } from '@localazy/cdn-client';
const cdn = await CdnClient.create({
// use your own metafile
metafile: 'https://delivery.localazy.com/_a855374211039568660198b39c31/_e0.v2.json',
});
const result = await cdn.fetch({
// select files from metafile
files: cdn.metafile.files[0],
// select locales
locales: ['en', 'de'],
});
```
<details><summary><i><samp>example result</samp></i></summary>
```javascript
const result = {
en: {
cdn_info: 'With the CDN you can deliver the translation files instantly',
cdn_testing: 'We\'re testing the CDN',
hello_localazy: 'Hello Localazy!',
using_javascript: 'In this project we decided to use JavaScript'
},
de: {
cdn_info: 'Mit dem CDN können Sie die Übersetzungsdateien sofort liefern',
cdn_testing: 'Wir testen das CDN',
hello_localazy: 'Hallo Localazy!',
using_javascript: 'In diesem Projekt haben wir uns für JavaScript entschieden'
}
};
```
</details>
For more information, visit [Installation](https://localazy.github.io/cdn-client/get-started/install.html) guide.
## 🛟 Support

@@ -39,13 +76,16 @@

## 💙 Localazy Ecosystem
## 💙 Localazy Packages
Check out other npm packages from Localazy:
Check out all npm packages from Localazy:
- [@localazy/cli](https://www.npmjs.com/package/@localazy/cli)
- [@localazy/api-client](https://www.npmjs.com/package/@localazy/api-client)
- [@localazy/cdn-client](https://www.npmjs.com/package/@localazy/cdn-client)
- [@localazy/languages](https://www.npmjs.com/package/@localazy/languages)
- [@localazy/strapi-plugin](https://www.npmjs.com/package/@localazy/strapi-plugin)
| Package | Description |
|--------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------|
| [@localazy/cli](https://www.npmjs.com/package/@localazy/cli) | Localazy CLI tool for app and software localization and translation. |
| [@localazy/api-client](https://www.npmjs.com/package/@localazy/api-client) | Node.js module that allows you to easily interact with the Localazy API. |
| [@localazy/cdn-client](https://www.npmjs.com/package/@localazy/cdn-client) | Node.js module that allows you to easily interact with the Localazy CDN. |
| [@localazy/languages](https://www.npmjs.com/package/@localazy/languages) | Available Localazy Languages |
| [@localazy/strapi-plugin](https://www.npmjs.com/package/@localazy/strapi-plugin) | The official Strapi Plugin by Localazy. |
| [@localazy/directus-extension-localazy](https://www.npmjs.com/package/@localazy/directus-extension-localazy) | The official Localazy module extension for Directus |
Discover all available [integration options and localization examples](https://github.com/localazy).
Discover all available [integration options](https://github.com/localazy) and [localization examples](https://github.com/localazy).

@@ -52,0 +92,0 @@ ## 📜 License

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc