| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 | 
							- const loader = require("./loader.js").loader;
 
- const phrasebook = require("./phrasebook.js").phrasebook;
 
- /**
 
-  * This class represents languages library. This store its location on the 
 
-  * server, and create loaders for them. It could also load langiage 
 
-  * library from json file.
 
-  */
 
- class languages {
 
-     /**
 
-      * @var {string}  
 
-      * This represents path to directory where phrasebooks had been stored.
 
-      */
 
-     #path;
 
-     /**
 
-      * @var {Map}
 
-      * This store languages and its files on server. 
 
-      */
 
-     #libs;
 
-     /**
 
-      * @var {bool}
 
-      * This store that directory is in the local file system, or remote
 
-      * server. When true, resources would be loaded by node:fs. When 
 
-      * false, resources would be fetched.
 
-      */
 
-     #local;
 
-     /**
 
-      * This create new languages library. Next, languages could be added to
 
-      * the library by command, or by loading index file.
 
-      * 
 
-      * @throws {TypeError} - When parameters is not in correct format.
 
-      * 
 
-      * @param {string} path - Path to phrasebooks on the server or filesystem.
 
-      * @param {bool} local - True when phrasebooks dirs would be loaded by 
 
-      *                       node:fs module. False when would be fetch.
 
-      */
 
-     constructor(path, local = false) {
 
-         if (typeof(path) !== "string") {
 
-             throw new TypeError("Path to the phrasebooks must be string.");
 
-         }
 
-         if (typeof(local) !== "boolean") {
 
-             throw new TypeError("Local must be bool variable.");
 
-         }
 
-         this.#local = local;
 
-         this.#path = path;
 
-         this.#libs = new Map();
 
-     }
 
-     /**
 
-      * This add new language to the library by name. Name must be in form
 
-      * like POSIX locale, like en_US, or pl_PL. That mean first two letter
 
-      * mest be ISO 639-1 and second two letters mst be in ISO 3166-1 alpha-2
 
-      * 2 letter country code format.
 
-      * 
 
-      * @see https://www.loc.gov/standards/iso639-2/php/code_list.php
 
-      * @see https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes
 
-      * @see https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
 
-      * @see https://en.wikipedia.org/wiki/Locale_(computer_software)
 
-      * 
 
-      * @throws {TypeError} - When tpes of the parameters is not correct.
 
-      * 
 
-      * @param {string} name - Name of the language, like "en_US".
 
-      * @param {string} file - Name of the file in the directory.
 
-      * @return {languages} - Instnace of this class to chain.
 
-      */
 
-     add(name, file) {
 
-         if (typeof(name) !== "string") {
 
-             throw new TypeError("Name of the language must be sting.");
 
-         }
 
-         if (typeof(file) !== "string") {
 
-             throw new TypeError("File on in the directory must be string.");
 
-         }
 
-         if (this.#libs.has(name)) {
 
-             console.error("Language \"" + name + "\" already loaded.");
 
-             console.error("It could not being loaded twice.");
 
-             return this;
 
-         }
 
-         if (!this.#valid_locale(name)) {
 
-             console.error("Language name \"" + name + "\" invalid formated.");
 
-             console.error("It could not being loaded.")
 
-             return this;
 
-         }
 
-         
 
-         this.#libs.set(name, file);
 
-         return this;
 
-     }
 
-     /**
 
-      * This load all phrasebook given in the index file. Index must be
 
-      * JSON file, which contain one object. That object properties must be
 
-      * languages names in the notation like in add function. Valus of that
 
-      * properties musts being strings which contains names of the phrasebook
 
-      * files in the path directory.
 
-      * 
 
-      * @example ``` { "pl_PL": "polish.json", "en_US": "english.json" } ```
 
-      * 
 
-      * @see add
 
-      * 
 
-      * @param {string} index - Index file in the phrasebook directory.
 
-      * @return {languages} - New languages instance with loaded index.
 
-      */
 
-     async load(index) {
 
-         if (typeof(index) !== "string") {
 
-             throw new TypeError("Name of index file is not string.");
 
-         }
 
-         const response = await this.#load_index(index);
 
-         const result = new languages(this.#path, this.#local);
 
-         
 
-         Object.keys(response).forEach(name => {
 
-             if (typeof(name) !== "string") {
 
-                 console.error("Name of the language must be string.");
 
-                 console.error("Check languages index.");
 
-                 console.error("Skipping it.")
 
-                 return;
 
-             }
 
-             if (typeof(response[name]) !== "string") {
 
-                 console.error("Name of phrasebook file must be string.");
 
-                 console.error("Check languages index.");
 
-                 console.error("Skipping it.");
 
-                 return;
 
-             }
 
-             result.add(name, response[name]);
 
-         });
 
-         return result;
 
-     }
 
-     /**
 
-      * This load index object. That check, and when content must be loaded
 
-      * from local filesystem, it use node:fs, or when it must be fetched from
 
-      * remote, then use fetch API.
 
-      * 
 
-      * @param {string} index - Name of the index file in library. 
 
-      * @returns {object} - Loaded index file content. 
 
-      */
 
-     async #load_index(index) {
 
-         const path = this.#full_path(index);
 
-         if (this.#local) {
 
-             let fs = null;
 
-             NODE: fs = require("node:fs/promises"); 
 
-            
 
-             if (fs === null) {
 
-                 throw new Error("Could not use ndoe:fs in browser.");
 
-             }
 
-             return JSON.parse(
 
-                 await fs.readFile(path, { encoding: "utf-8" })
 
-             );
 
-         }
 
-         const request = await fetch(path);
 
-         return await request.json();
 
-     }
 
-     /**
 
-      * This check that language exists in languages library.
 
-      * 
 
-      * @param {string} name - Name of the language to check.
 
-      * @return {bool} - True when language exists, false when not
 
-      */
 
-     has(name) {
 
-         return this.#libs.has(name);
 
-     }
 
-     /**
 
-      * This return all avairable languages.
 
-      * 
 
-      * @return {Array} - List of all avairable languages.
 
-      */
 
-     get avairable() {
 
-         const alls = new Array();
 
-         this.#libs.keys().forEach(name => {
 
-             alls.push(name);
 
-         });
 
-         return alls;
 
-     }
 
-     /**
 
-      * This load phrasebook with give name.
 
-      * 
 
-      * @throws {TypeError} - Param type is not correct.
 
-      * @throws {RangeError} - Language not exists in libs.
 
-      * 
 
-      * @param {string} name - Name of the language to load. 
 
-      * @returns {phrasebook} - Phrasebook loaded from the file.
 
-      */
 
-     select(name) {
 
-         if (typeof(name) !== "string") {
 
-             throw new TypeError("Name of the language must be string.");
 
-         }
 
-         if (!this.has(name)) {
 
-             DEBUG: throw new RangeError(
 
-                 "Not found language \"" + name + "\"."
 
-             );
 
-             return new phrasebook(new Map());
 
-         }
 
-         
 
-         const file = this.#libs.get(name);
 
-         const path = this.#full_path(file);
 
-         return new loader(path, this.#local).load();
 
-     }
 
-     /**
 
-      * This return full path to the file.
 
-      * 
 
-      * @param {string} name - Name of the file to get its path
 
-      * @return {string} - Full path of the file
 
-      */
 
-     #full_path(name) {
 
-         let glue = "/";
 
-         if (this.#path[this.#path.length - 1] === glue) {
 
-             glue = "";
 
-         }
 
-         return this.#path + glue + name;
 
-     }
 
-     /**
 
-      * This check that format is valid POSIX like locale.
 
-      * 
 
-      * @param {string} name - Name to check format of.
 
-      * @return {bool} - True when format is valid, false when not.
 
-      */
 
-     #valid_locale(name) {
 
-         const splited = name.split("_");
 
-         if (splited.length !== 2) {
 
-             return false;
 
-         }
 
-         const first = splited[0];
 
-         const second = splited[1];
 
-         if (first.toLowerCase() !== first || first.length !== 2) {
 
-             return false;
 
-         }
 
-         if (second.toUpperCase() !== second || second.length !== 2) {
 
-             return false;
 
-         }
 
-         return true;
 
-     }
 
- }
 
- exports.languages = languages;
 
 
  |