diff --git a/README.md b/README.md index 1fc0913..19ad0a0 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,19 @@ or ## Usage -**Schema:** +**Import** + +`import MudParser from 'mud-parser';` + +or + +`const MudParser = require('mud-parser');` + +**Usage** + +`const result = MudParser(schema, response.data);` + +**Schema example:** ```js { @@ -27,20 +39,20 @@ or parsers: [ { key: "title", value: "data.movies.0.title" }, { key: "imdbId", value: "data.movies.0.imdb_code" }, - { key: "realName", value: "data.movies.0.cast.0.full_name" }, - { key: "characterName", value: "data.movies.0.cast.0.character" }, + { key: "realName", value: "data.movies.0.cast|castMembers.0.full_name" }, + { key: "characterName", value: "data.movies.0.cast|castMembers.0.character" }, ], } ``` -**Outcome:** +**Output:** ```js [ { title: '12 Angry Men', imdbId: 'tt0050083', - cast: [ + castMembers: [ { realName: 'Martin Balsam', characterName: 'Juror 1' @@ -55,7 +67,7 @@ or { title: 'Limelight', imdbId: 'tt0044837', - cast: [ + castMembers: [ { realName: 'Charles Chaplin', characterName: 'Calvero' diff --git a/package.json b/package.json index 6608f80..64ddcc7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "mud-parser", - "version": "0.1.1", - "description": "A simple JSON parser.", + "version": "0.2.0", + "description": "Unify JSON with schemas.", "main": "index.js", "scripts": { "test": "mocha test/" diff --git a/src/MudParser.js b/src/MudParser.js index aa3b81b..1f76a85 100644 --- a/src/MudParser.js +++ b/src/MudParser.js @@ -1,9 +1,12 @@ const Iterator = require("./Iterator"); const { getFromObject, createObject } = require("./ObjectUtils"); +let replace = {}; + const MudParser = (schema, data) => { if (data === undefined) return null; checkSchema(schema); + replace = {}; let hierarchy = ResultHierarchy(schema.parsers, data); let result = []; Object.keys(hierarchy).map((h) => result.push(hierarchy[h])); @@ -53,18 +56,45 @@ const getIndexes = (str) => { whileStop++; if (whileStop >= 15) break; - indexes.push(match.index); + indexes.push(match); } return indexes; }; +const saveReplace = (key, replaceValue, index) => { + replace[key] = { replace: replaceValue, index }; +}; + +const getReplace = (str, index) => { + for (let keyName in replace) { + if (str.includes(keyName) && index === replace[keyName].index) { + return str.replace(keyName, replace[keyName].replace); + } + } + + return str; +}; + +const checkAndGetReplace = (str, index) => { + const re = /\|/; + let match = re.exec(str); + if (match !== null) { + let main = str.substring(0, match.index); + let replace = str.substring(match.index + 1); + saveReplace(main, replace, index); + return main; + } + return str; +}; + const getNonArrays = (str) => { const indexes = getIndexes(str); let res = []; let counter = 0; - indexes.map((index) => { - res.push(str.substring(counter, index)); - counter = index + 3; + indexes.map((match, index) => { + let path = str.substring(counter, match.index); + res.push(checkAndGetReplace(path, index)); + counter = match.index + match[0].length; }); let last = str.substring(counter); if (last !== "") res.push(last); @@ -123,20 +153,20 @@ const ResultHierarchy = (schema, data) => { let result = {}; let _ = schema.map((sch) => { const schemaRes = getSchema(sch, data); - schemaRes.map((sch) => { - let objStringArr = []; - let indexes = getLastIndexes(sch.path); + schemaRes.map((schR) => { + let objStringArrReplaced = []; + let indexes = getLastIndexes(schR.path); let initIndex = 0; - indexes.map((index) => { - let keyString = sch.path.substring(initIndex, index); + indexes.map((index, ii) => { + let keyString = schR.path.substring(initIndex, index); keyString = keyString.replaceAll(".", ""); keyString += "__"; - objStringArr.push(keyString); + objStringArrReplaced.push(getReplace(keyString, ii)); initIndex = index; }); - createObject(result, objStringArr.join(".")); - let lastObj = getFromObject(objStringArr.join("."), result); - lastObj[sch.key] = sch.value; + createObject(result, objStringArrReplaced.join(".")); + let lastObj = getFromObject(objStringArrReplaced.join("."), result); + lastObj[schR.key] = schR.value; }); }); return result; diff --git a/test/test.js b/test/test.js index fdfc9a2..60e6713 100644 --- a/test/test.js +++ b/test/test.js @@ -7,21 +7,21 @@ const currencyApi = require("./json/currencyApi.json"); const MudParser = require("../src/MudParser"); describe("Test MudParser with movie api", () => { - const schema = { - version: 1, - parsers: [ - { key: "title", value: "data.movies.0.title" }, - { key: "imdbId", value: "data.movies.0.imdb_code" }, - { key: "image", value: "data.movies.0.small_cover_image" }, - { key: "source", value: "data.movies.0.trailers.0.url" }, - { key: "quality", value: "data.movies.0.trailers.0.quality" }, - { key: "seeds", value: "data.movies.0.trailers.0.seeds" }, - { key: "size", value: "data.movies.0.trailers.0.size" }, - { key: "type", value: "data.movies.0.trailers.0.type" }, - ], - }; - it("test parsing movieApi", () => { + const schema = { + version: 1, + parsers: [ + { key: "title", value: "data.movies.0.title" }, + { key: "imdbId", value: "data.movies.0.imdb_code" }, + { key: "image", value: "data.movies.0.small_cover_image" }, + { key: "source", value: "data.movies.0.trailers.0.url" }, + { key: "quality", value: "data.movies.0.trailers.0.quality" }, + { key: "seeds", value: "data.movies.0.trailers.0.seeds" }, + { key: "size", value: "data.movies.0.trailers.0.size" }, + { key: "type", value: "data.movies.0.trailers.0.type" }, + ], + }; + const result = MudParser(schema, movieApi); assert(result.length === 2, result.length); for (let i = 0; i < 2; i++) { @@ -44,6 +44,42 @@ describe("Test MudParser with movie api", () => { }); } }); + + it("test parsing movieApi with renaming middle object", () => { + const schema = { + version: 1, + parsers: [ + { key: "title", value: "data.movies.0.title" }, + { key: "imdbId", value: "data.movies.0.imdb_code" }, + { key: "image", value: "data.movies.0.small_cover_image" }, + { key: "source", value: "data.movies.0.trailers|sources.0.url" }, + { key: "quality", value: "data.movies.0.trailers|sources.0.quality" }, + { key: "seeds", value: "data.movies.0.trailers|sources.0.seeds" }, + { key: "size", value: "data.movies.0.trailers|sources.0.size" }, + { key: "type", value: "data.movies.0.trailers|sources.0.type" }, + ], + }; + + const result = MudParser(schema, movieApi); + assert(result.length === 2, result.length); + for (let i = 0; i < 2; i++) { + assert(result[i].title === movieApi.data.movies[i].title); + assert(result[i].imdbId === movieApi.data.movies[i].imdb_code); + assert(result[i].image === movieApi.data.movies[i].small_cover_image); + assert( + result[i].sources.length === movieApi.data.movies[i].trailers.length, + ); + result[i].sources.map((source, tIndex) => { + assert(source.source === movieApi.data.movies[i].trailers[tIndex].url); + assert( + source.quality === movieApi.data.movies[i].trailers[tIndex].quality, + ); + assert(source.seeds === movieApi.data.movies[i].trailers[tIndex].seeds); + assert(source.size === movieApi.data.movies[i].trailers[tIndex].size); + assert(source.type === movieApi.data.movies[i].trailers[tIndex].type); + }); + } + }); }); describe("Test MudParser with movie api 2", () => { @@ -63,7 +99,6 @@ describe("Test MudParser with movie api 2", () => { it("test parsing movieApi", () => { const result = MudParser(schema, movieApi2); - console.log(result); assert(result.length === 2, result.length); for (let i = 0; i < 2; i++) { assert(result[i].title === movieApi2[i].title);