Select Git revision
fetch.mjs 3.96 KiB
'use strict';
/**
* @author schukai GmbH
*/
import {internalSymbol} from "../../constants.mjs";
import {extend} from "../../data/extend.mjs";
import {Formatter} from "../../text/formatter.mjs";
import {getGlobalFunction} from "../../types/global.mjs";
import {isInstance, isString} from "../../types/is.mjs";
import {validateObject, validateString} from "../../types/validate.mjs";
import {parseLocale} from "../locale.mjs";
import {Provider} from "../provider.mjs";
import {Translations} from "../translations.mjs";
export {Fetch}
/**
* The fetch provider retrieves a JSON file from the given URL and returns a translation object.
*
* ```
* <script type="module">
* import {Fetch} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@latest/source/i18n/providers/fetch.mjs';
* new Fetch()
* </script>
* ```
*
* @example <caption>das ist ein test</caption>
*
* import {Fetch} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@latest/source/i18n/providers/fetch.mjs';
*
* // fetch from API
* const translation = new Fetch('https://example.com/${language}.json').getTranslation('en-GB');
* // ↦ https://example.com/en.json
*
* @since 1.13.0
* @copyright schukai GmbH
* @memberOf Monster.I18n.Providers
* @see {@link https://datatracker.ietf.org/doc/html/rfc3066}
* @tutorial i18n-locale-and-formatter
*/
class Fetch extends Provider {
/**
* As options the key `fetch` can be passed. This config object is passed to the fetch method as init.
*
* The url may contain placeholders (language, script, region, variants, extlang, privateUse), so you can specify one url for all translations.
*
* ```
* new Fetch('https://www.example.com/assets/${language}.json')
* ```
*
* @param {string|URL} url
* @param {Object} options see {@link Monster.I18n.Providers.Fetch#defaults}
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/fetch}
*/
constructor(url, options) {
super(options);
if (isInstance(url, URL)) {
url = url.toString();
}
if (options === undefined) {
options = {};
}
validateString(url);
/**
* @property {string}
*/
this.url = url;
/**
* @private
* @property {Object} options
*/
this[internalSymbol] = extend({}, super.defaults, this.defaults, validateObject(options));
}
/**
* Defaults
*
* @property {Object} fetch
* @property {String} fetch.method=GET
* @property {String} fetch.mode=cors
* @property {String} fetch.cache=no-cache
* @property {String} fetch.credentials=omit
* @property {String} fetch.redirect=follow
* @property {String} fetch.referrerPolicy=no-referrer
*
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API}
*/
get defaults() {
return {
fetch: {
method: 'GET', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'omit', // include, *same-origin, omit
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
}
}
}
/**
*
* @param {Locale|string} locale
* @return {Promise}
*/
getTranslations(locale) {
if (isString(locale)) {
locale = parseLocale(locale);
}
let formatter = new Formatter(locale.getMap())
return getGlobalFunction('fetch')(formatter.format(this.url), this.getOption('fetch', {}))
.then((response) => response.json()).then(data => {
return new Translations(locale).assignTranslations(data);
});
}
}