/** * Copyright schukai GmbH and contributors 2022. All Rights Reserved. * Node module: @schukai/monster * This file is licensed under the AGPLv3 License. * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html */ 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. * * @externalExample ../../example/i18n/providers/fetch.mjs * @license AGPLv3 * @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); }); } }