├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── dist
└── json-knife.bundle.js
├── gulpfile.babel.js
├── license.txt
├── package-lock.json
├── package.json
├── public
├── index.html
└── sample.js
├── src
├── controller.js
├── entry.js
├── pattern.js
├── service.js
└── util.js
├── test
├── answer.js
├── sample.js
└── test.js
└── webpack.config.babel.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | target
3 | !/node_modules/
4 | /node_modules/
5 | .idea/inspectionProfiles/
6 | /.idea
7 | /.npmignore
8 | /public/root_domain_process.html
9 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - '10'
4 | script: npm run test
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Andrew-Kang-G
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # json-knife [](https://travis-ci.org/Andrew-Kang-G/json-knife) [](https://www.npmjs.com/package/json-knife) [](https://www.jsdelivr.com/package/gh/Andrew-Kang-G/json-knife)
2 | ## Overview
3 | Mass replace specific properties value with a new value recursively in huge, complex and deep JSON string
4 | with a robust regular expression based engine.
5 |
6 | Zero dependency, 7KB
7 |
8 | LIVE DEMO
9 |
10 |
11 | ## Installation
12 |
13 | For ES5 users,
14 |
15 | ``` html
16 |
17 |
18 |
19 |
22 |
23 |
24 | ```
25 |
26 | For ES6 npm users, run 'npm install --save json-knife' on console.
27 |
28 | ``` html
29 | import Pattern from 'json-knife';
30 | ```
31 |
32 | ## Syntax & Usage
33 | Very simple to use. Now we are going to set all 'Mike{[Gentleman]}' to null in the sample JSON string.
34 |
35 | ```javascript
36 |
37 | /**
38 | * @brief
39 | * Mass Update certain key-values recursively in huge, complex JSON string trees
40 | * @author Andrew Kang
41 | * @param original string required (must be JSON string)
42 | * @param key string required
43 | * @param value string or boolean or number or null required
44 | * @return string
45 | */
46 |
47 | // IMPORTANT : the variable 'original' should be valid JSON.
48 | // You can test your JSON string source like here.
49 | // https://jsonformatter.curiousconcept.com/
50 |
51 | var result = Pattern.sculptJson(original, 'Mike{[Gentleman]}', null);
52 |
53 | // You can convert the result string to an object type.
54 | var resultObj = JSON.parse(result);
55 |
56 | ```
57 | **[Original source]**
58 |
59 | var original =
60 | ```json
61 | {
62 | "prob\"lems": [{
63 | "classes": [{
64 | "medications": [{
65 | "medicationsClasses": [{
66 | "Mike {[Gentleman]}": [{
67 | "associatedDrug": [{
68 | "name": "asprin",
69 | "dose": 35.3,
70 | "strength": "500 mg",
71 | "className" : false
72 | }],
73 | "Mike {[Gentleman]}": [{
74 | "name": "somethingElse",
75 | "dose": "",
76 | "strength": "500 mg",
77 | "friends": {
78 | "self": {
79 | "Mike {[Gentleman]}": "33",
80 | "names": ["aa"]
81 | }
82 | }
83 | }]
84 | }],
85 | "Judy": [{
86 | "associatedDrug": [{
87 | "name": "asprin",
88 | "dose": "",
89 | "strength": "500 mg",
90 | "friends": ["Mike {[Gentleman]}"]
91 | }],
92 | "associatedDrug#2": [{
93 | "name": "somethingElse",
94 | "dose": "",
95 | "strength": "500 mg"
96 | }],
97 | "friends": [{"Mike {[Gentleman]}": null}, {"Mike {[Gentleman]}": [["c[ 3\"5ool", 35], ["ca],[1\"3lm"], 53]}, "Jackson", "Mike {[Gentleman]}"]
98 | }]
99 | }]
100 | }],
101 | "classNameMissed": [{
102 | "Mike {[Gentleman]}": "missing_value"
103 | }]
104 | }],
105 | "className": [{}]
106 | }]
107 | }
108 | ```
109 | **[Result]** - string type
110 |
111 | ```json
112 | {
113 | "prob\"lems": [{
114 | "classes": [{
115 | "medications": [{
116 | "medicationsClasses": [{
117 | "Mike {[Gentleman]}": null,
118 | "Judy": [{
119 | "associatedDrug": [{
120 | "name": "asprin",
121 | "dose": "",
122 | "strength": "500 mg",
123 | "friends": ["Mike {[Gentleman]}"]
124 | }],
125 | "associatedDrug#2": [{
126 | "name": "somethingElse",
127 | "dose": "",
128 | "strength": "500 mg"
129 | }],
130 | "friends": [{"Mike {[Gentleman]}": null}, {"Mike {[Gentleman]}": null}, "Jackson", "Mike {[Gentleman]}"]
131 | }]
132 | }]
133 | }],
134 | "classNameMissed": [{
135 | "Mike {[Gentleman]}": null
136 | }]
137 | }],
138 | "className": [{}]
139 | }]
140 | }
141 | ```
142 |
143 | Please inform me of the source related things by leaving issues on Github or emailing me at studypurpose@naver.com.
--------------------------------------------------------------------------------
/dist/json-knife.bundle.js:
--------------------------------------------------------------------------------
1 | var Pattern=function(e){function t(r){if(n[r])return n[r].exports;var u=n[r]={exports:{},id:r,loaded:!1};return e[r].call(u.exports,u,u.exports,t),u.loaded=!0,u.exports}var n={};return t.m=e,t.c=n,t.p="../dist/",t(0)}([function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var u=n(1),l=r(u);t.default=l.default,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function u(e,t,n){if(!e||"string"!=typeof e)throw new Error('the variable "original" must be a string type and not be null.');if(!t||"string"!=typeof t)throw new Error('the variable "key" must be a string type and not be null.');if(/"/.test(t))throw new Error('the variable "key" must not contain double quotes, but this can be allowed in the next version.');if(!(n&&("string"==typeof n||"number"==typeof n||"boolean"==typeof n)||"object"==typeof n&&null==n))throw new Error('the variable "value" must be a string or number or boolean or null.');return n&&"string"==typeof n&&(n=n.replace(/([^\u005C])"/g,'$1\\"')),e=e.trim(),a.default.sculpt(e,a.default.getMaterials(e,t,n))}Object.defineProperty(t,"__esModule",{value:!0});var l=n(2),a=r(l);t.default={sculptJson:u},e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function u(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t0?n[u-1].step:0;if(o[4]){o[5]&&(p+=(o[5].match(new RegExp(y.default.steps.asc,"g"))||[]).length,p-=(o[5].match(new RegExp(y.default.steps.desc,"g"))||[]).length);var c=null;if(o[6]){var i=o[6],f=i.length;c=o.index+f,s>=p&&(s===p?(r.push(c),s=null):(r.push(a(c,i,s-p)),s=null))}n.push({step:p,previousLastIndex:c,key:null,noKey:o[0],debugInfo:o}),u+=1}else{if(o[3]){var d=null;t===n[n.length-1].key&&(d=o.index+o[3].length,r.push(a(d,o[3],n[n.length-1].step)),s=null),null!==s&&(d=o.index+o[3].length,r.push(a(d,o[3],s)),s=null);var h=p-(o[0].match(new RegExp(y.default.steps.desc,"g"))||[]).length;if(n.push({step:h,previousLastIndex:d,key:null,noKey:null}),0!==h)throw new Error("The final step should be 0.");break}var g=o[1].match(new RegExp("^"+y.default.commons.spaceOrEndBracketOrNot,"g"))[0],v=(o[1].match(new RegExp(y.default.steps.desc,"g"))||[]).length,O=(o[1].match(new RegExp(y.default.steps.asc,"g"))||[]).length;p+=O,p-=v;var x=o.index+g.length;s>=p&&(s===p?(r.push(x),s=null):(r.push(a(x,g,s-p+O)),s=null)),t===o[2]&&null==s&&(s=p),n.push({step:p,previousLastIndex:x,key:o[2],noKey:null}),u+=1}}}catch(e){throw console.log("The error has occurred at idx : "+u),console.log(n),console.log(r),e}finally{}return r}function o(e,t,n){"string"==typeof n&&(n='"'+n+'"');for(var r=[],u=new RegExp(y.default.jsonOutput(v.default.Text.escapeRegex(t)),"g"),a={},o=!1,p=[],c=0,i=function(){var u=a[0],i=l(a),f=u.replace(new RegExp(v.default.Text.escapeRegex(a[i])+"$"),n),d=a.index,h=a.index+a[0].length;return r.find(function(e){return e.startIndexd})?"continue":(5!==i&&6!==i||(o||(p=s(e,t),o=!0),h=p[c]),r.push({value:n,matchedKeyValue:u,newMatchedKeyValue:f,startIndex:d,lastIndex:h}),void(c+=1))};null!==(a=u.exec(e));){i()}return r}function p(e,t){return t.reverse().forEach(function(t,n){e=v.default.Text.replaceBetween(e,t.startIndex,t.lastIndex,t.newMatchedKeyValue)}),e}function c(e){var t=[],n=0;try{!function(){var r=new RegExp("(?:"+y.default.jsonOutput2()+")|("+y.default.commons.spaceOrEndBracketOrNot+"$)|(?:"+y.default.steps.withNoKey(!0)+")","g"),l={},a=[],s=null,o=0,p=[],c=null,i=0,f=null;a.push({key:"ORIGIN",step:i});for(var d=function(){var r=o;if(l[5]){var d=null;l[6]&&(r+=(l[6].match(new RegExp(y.default.steps.asc,"g"))||[]).length,r-=(l[6].match(new RegExp(y.default.steps.desc,"g"))||[]).length,/,/.test(l[6])&&(p.push(a[a.length-1].step),d=p.filter(function(e){return e===a[a.length-1].step}).length,0===d&&(d=null)),/\[/.test(l[6])&&(i=r&&(a=a.filter(function(e){return e.step=r&&(a=a.filter(function(e){return e.stept?1:-1}function d(e,t){var n=c(e).map(function(e){return JSON.stringify(e)}).sort(f),r=c(t).map(function(e){return JSON.stringify(e)}).sort(f);return i(n,r)}Object.defineProperty(t,"__esModule",{value:!0});var h=n(3),y=r(h),g=n(4),v=r(g);t.default={getMaterials:o,sculpt:p,deepCompare:d},e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function u(e){return o.key(e)+"(?:"+o.valueType.string+"|"+o.valueType.number+"|"+o.valueType.boolean+"|"+o.valueType.object+"|"+o.valueType.array+"|"+o.valueType.empty+")"}function l(){return p.withKey+"("+o.valueType2.string+"|"+o.valueType2.number+"|"+o.valueType2.boolean+"|"+o.valueType2.empty+"|)"}Object.defineProperty(t,"__esModule",{value:!0});var a=n(4),s=(r(a),{spaceOrNot:"[\\n\\r\\t\\s]*",spaceOrNotOrComma:"[,\\n\\r\\t\\s]*",spaceOrBigStartBracketOrNot:"[\\[\\n\\r\\t\\s]*",spaceOrStartBracketOrNot:"[\\[{\\n\\r\\t\\s]*",spaceOrEndBracketOrNot:"[}\\]\\n\\r\\t\\s]*",everything:"(?:.|[\\n\\r\\t\\s])"}),o={key:function(){var e=arguments.length<=0||void 0===arguments[0]?null:arguments[0];return e?"[,{]"+s.spaceOrNot+'"('+e+')"'+s.spaceOrNot+":"+s.spaceOrNot:"[,{]"+s.spaceOrNot+o.keyType+s.spaceOrNot+":"+s.spaceOrNot},keyType:'"((?:[^"]*?[^\\u005C])|(?:(?=[^"]*[\\u005C]").*?[^\\u005C]))"',valueType:{string:'(""|".*?[^\\u005C]")',number:"(-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)",boolean:"(true|false)",object:"({)",array:"(\\[)",empty:"(null|undefined)",emptyObject:"{"+s.spaceOrNot+"}"},valueType2:{string:'(?:""|".*?[^\\u005C]")',number:"(?:-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)",boolean:"(?:true|false)",empty:"(?:null|undefined)",emptyObject:"{"+s.spaceOrNot+"}",emptyArray:"\\["+s.spaceOrNot+"\\]"}},p={withKey:"("+s.spaceOrEndBracketOrNot+",(?:[\\[\\n\\r\\t\\s]*{[\\[\\n\\r\\t\\s]*)+|"+s.spaceOrEndBracketOrNot+",|(?:[\\[\\n\\r\\t\\s]*{[\\[\\n\\r\\t\\s]*)+)"+s.spaceOrNot+o.keyType+s.spaceOrNot+":"+s.spaceOrNot,withNoKey:function(){var e=arguments.length<=0||void 0===arguments[0]||arguments[0],t=e?"|":"";return"((((?:"+s.spaceOrNot+"[\\]}]"+s.spaceOrNot+")+"+t+"),"+s.spaceOrStartBracketOrNot+"|(?:"+s.spaceOrNot+"\\["+s.spaceOrNot+")+)("+o.valueType2.string+"|"+o.valueType2.number+"|"+o.valueType2.boolean+"|"+o.valueType2.empty+"|"+o.valueType2.emptyObject+"|"+o.valueType2.emptyArray+")|("+o.valueType2.emptyObject+"|"+o.valueType2.emptyArray+"))"},asc:"[\\[{]",desc:"[\\]}]",toNumberOfGap:function(e){return"(?:"+s.spaceOrNot+"[\\]},]"+s.spaceOrNot+"){"+e+"}$"}};t.default={commons:s,jsonBase:o,jsonOutput:u,jsonOutput2:l,steps:p},e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var u=n(3),l=(r(u),{replaceBetween:function(e,t,n,r){return e.substring(0,t)+r+e.substring(n)},escapeRegex:function(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}});t.default={Text:l},e.exports=t.default}]);
--------------------------------------------------------------------------------
/gulpfile.babel.js:
--------------------------------------------------------------------------------
1 | import gulp from 'gulp';
2 | import babel from 'gulp-babel';
3 | import mocha from 'gulp-mocha';
4 | import gutil from 'gulp-util';
5 | import webpack from 'webpack';
6 | import webpackConfig from './webpack.config.babel';
7 | import WebpackDevServer from 'webpack-dev-server';
8 |
9 | gulp.task('default', ['webpack']);
10 |
11 | gulp.task('babel', () => {
12 | return gulp.src('src/*.js')
13 | .pipe(babel())
14 | .pipe(gulp.dest('target'));
15 | });
16 |
17 | gulp.task('test', ['babel'], () => {
18 | return gulp.src('test/*.js')
19 | .pipe(mocha({reporter: 'list'}))
20 | .on('error', () => {
21 | gulp.emit('end');
22 | });
23 | });
24 |
25 | gulp.task('watch-test', () => {
26 | return gulp.watch(['src/**', 'test/**'], ['test']);
27 | });
28 |
29 | gulp.task('webpack', ['test'], function(callback) {
30 | var myConfig = Object.create(webpackConfig);
31 | myConfig.plugins = [
32 | new webpack.optimize.DedupePlugin(),
33 | new webpack.optimize.UglifyJsPlugin()
34 | ];
35 |
36 | // run webpack
37 | webpack(myConfig, function(err, stats) {
38 | if (err) throw new gutil.PluginError('webpack', err);
39 | gutil.log('[webpack]', stats.toString({
40 | colors: true,
41 | progress: true
42 | }));
43 | callback();
44 | });
45 | });
46 |
47 | gulp.task('server', ['webpack'], function(callback) {
48 | // modify some webpack config options
49 | var myConfig = Object.create(webpackConfig);
50 | myConfig.devtool = 'eval';
51 | myConfig.debug = true;
52 |
53 | // Start a webpack-dev-server
54 | new WebpackDevServer(webpack(myConfig), {
55 | publicPath: '/' + myConfig.output.publicPath,
56 | stats: {
57 | colors: true
58 | },
59 | hot: true
60 | }).listen(8080, 'localhost', function(err) {
61 | if(err) throw new gutil.PluginError('webpack-dev-server', err);
62 | gutil.log('[webpack-dev-server]', 'http://localhost:8080/webpack-dev-server/index.html');
63 | });
64 | });
--------------------------------------------------------------------------------
/license.txt:
--------------------------------------------------------------------------------
1 | json-knife
2 | https://github.com/Andrew-Kang-G/json-knife
3 |
4 | The MIT License (MIT)
5 |
6 | Copyright (c) 2019 Andrew-Kang-G
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy
9 | of this software and associated documentation files (the "Software"), to deal
10 | in the Software without restriction, including without limitation the rights
11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | copies of the Software, and to permit persons to whom the Software is
13 | furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in all
16 | copies or substantial portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 | SOFTWARE.
25 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "json-knife",
3 | "version": "1.3.1",
4 | "description": "Bulk set properties recursively in huge, complex and deep JSON string with a robust regular expression based engine",
5 | "main": "src/entry.js",
6 | "scripts": {
7 | "build": "gulp",
8 | "test": "gulp test"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git+https://github.com/Andrew-Kang-G/json-knife.git"
13 | },
14 | "keywords": [
15 | "json",
16 | "parser",
17 | "recursive",
18 | "update",
19 | "remove"
20 | ],
21 | "author": "Andrew Kang",
22 | "license": "MIT",
23 | "bugs": {
24 | "url": "https://github.com/Andrew-Kang-G/json-knife/issues"
25 | },
26 | "homepage": "https://github.com/Andrew-Kang-G/json-knife#readme",
27 | "devDependencies": {
28 | "chai": "^3.3.0",
29 | "gulp": "^3.9.0",
30 | "gulp-babel": "^5.3.0",
31 | "gulp-mocha": "^2.1.3",
32 | "gulp-util": "^3.0.7",
33 | "mocha": "^2.3.3",
34 | "webpack": "^1.12.2",
35 | "lodash": "^4.17.11",
36 | "growl": "^1.10.0",
37 | "minimatch": "^3.0.2",
38 | "webpack-dev-server": "^3.1.11",
39 | "babel-core": "^5.8.25",
40 | "babel-plugin-syntax-dynamic-import": "^6.18.0",
41 | "babel-loader": "^8.0.4",
42 | "babel-plugin-transform-object-rest-spread": "^6.26.0",
43 | "babel-plugin-transform-runtime": "^6.23.0",
44 | "babel-preset-env": "^1.7.0",
45 | "babel-preset-stage-0": "^6.24.1"
46 | },
47 | "dependencies": {}
48 | }
49 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
Test codes. Check console.
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
176 |
177 |
--------------------------------------------------------------------------------
/public/sample.js:
--------------------------------------------------------------------------------
1 | var original = '{\n' +
2 | ' "prob\\"lems": [{\n' +
3 | ' "classes": [{\n' +
4 | ' "medications": [{\n' +
5 | ' "medicationsClasses": [{\n' +
6 | ' "Mike {[Gentleman]}": [{\n' +
7 | ' "associatedDrug": [{\n' +
8 | ' "name": "asprin",\n' +
9 | ' "dose": "a",\n' +
10 | ' "strength": "500 mg"\n' +
11 | ' }],\n' +
12 | ' "Mike {[Gentleman]}": [{\n' +
13 | ' "name": "somethingElse",\n' +
14 | ' "dose": "",\n' +
15 | ' "strength": "500 mg",\n' +
16 | ' "friends": {\n' +
17 | ' "self": {\n' +
18 | ' "Mike {[Gentleman]}": "33",\n' +
19 | ' "names": ["aa"]\n' +
20 | ' }\n' +
21 | ' }\n' +
22 | ' }]\n' +
23 | ' }],\n' +
24 | ' "Judy": [{\n' +
25 | ' "associatedDrug": [{\n' +
26 | ' "name": "asprin",\n' +
27 | ' "dose": "",\n' +
28 | ' "strength": "500 mg",\n' +
29 | ' "friends": ["Mike {[Gentleman]}"]\n' +
30 | ' }],\n' +
31 | ' "associatedDrug#2": [{\n' +
32 | ' "name": "somethingElse",\n' +
33 | ' "dose": "",\n' +
34 | ' "strength": "500 mg"\n' +
35 | ' }],\n' +
36 | ' "friends": [{"Mike {[Gentleman]}": null}, {"Mike {[Gentleman]}": [["c[ 3\\"5ool", 35], ["ca],[1\\"3lm"], 53]}, "Jackson", "Mike {[Gentleman]}"]\n' +
37 | ' }]\n' +
38 | ' }]\n' +
39 | ' }],\n' +
40 | ' "classNameMissed": [{\n' +
41 | ' "Mike {[Gentleman]}": "missing_value"\n' +
42 | ' }]\n' +
43 | ' }],\n' +
44 | ' "className": [{}]\n' +
45 | ' }]\n' +
46 | ' }';
47 |
48 | var original2 ={
49 | "problems": [
50 | {
51 | "classes": [
52 | {
53 | "medications": [
54 | {
55 | "medicationsClasses": [
56 | {
57 | "Mike {[Gentleman]}": [
58 | {
59 | "associatedDrug": [
60 | {
61 | "name": "asprin",
62 | "dose": {"a":[[],3, [{}]],"B":{},"c":[{}]},
63 | "strength": "500 mg"
64 | },
65 | [{
66 | "name15": "asprin",
67 | "dose15": 5,
68 | "strength15": "500 mg"
69 | },22,[true, false]],
70 | [33,{
71 | "name16": "asprin",
72 | "dose16": 6,
73 | "strength16": "500 mg"
74 | }],
75 | {
76 | "name2": "asprin",
77 | "dose2": "a",
78 | "strength2": "500 mg"
79 | },
80 | {
81 | "name3": "asprin",
82 | "dose3": "a",
83 | "strength3": "500 mg"
84 | }
85 | ],
86 | "Mike {[Gentleman]}": [
87 | {
88 | "name": "somethingElse",
89 | "dose": "",
90 | "strength": "500 mg",
91 | "friends": {
92 | "self": {
93 | "Mike {[Gentleman]}": "33",
94 | "names": [
95 | "aa",
96 | true,
97 | {"xxx" : ["zd", 5, 3]}
98 | ]
99 | }
100 | }
101 | }
102 | ]
103 | },
104 | {
105 | "dassociatedDrug": [
106 | {
107 | "dose": "a",
108 | "name": "asprin",
109 | "strength": "500 mg"
110 | }
111 | ],
112 | "Mike {[Gentleman]}": [
113 | {
114 | "name": "somethingElse",
115 | "dose": "",
116 | "strength": "500 mg",
117 | "friends": {
118 | "self": {
119 | "Mike {[Gentleman]}": "33",
120 | "names": [
121 | "aa"
122 | ]
123 | }
124 | }
125 | }
126 | ]
127 | }
128 | ],
129 | "Judy": [
130 | {
131 | "associatedDrug": [
132 | {
133 | "name": "asprin",
134 | "dose": "",
135 | "strength": "500 mg",
136 | "friends": [
137 | "Mike {[Gentleman]}"
138 | ]
139 | }
140 | ],
141 | "associatedDrug#2": [
142 | {
143 | "name": "somethingElse",
144 | "dose": "",
145 | "strength": "500 mg"
146 | }
147 | ],
148 | "friends": [
149 | {
150 | "Mike {[Gentleman]}": null
151 | },
152 | {
153 | "Mike {[Gentleman]}": [
154 | [
155 | "c[ 3\"5ool",
156 | [3,5],
157 | 49
158 | ],
159 | [
160 | "ca],[1\"3lm"
161 | ],
162 | 53
163 | ]
164 | },
165 | "Jackson",
166 | "Mike {[Gentleman]}",
167 | {
168 | "problems": [
169 | {
170 | "aclasses": [
171 | {
172 | "medications": [
173 | {
174 | "medicationsClasses": [
175 | {
176 | "Mike {[Gentleman]}": [
177 | {
178 | "associatedDrug": [
179 | {
180 | "name": "asprin",
181 | "dose": "a",
182 | "strength": "500 mg"
183 | }
184 | ],
185 | "Mike {[Gentleman]}": [
186 | {
187 | "name": "somethingElse",
188 | "dose": "",
189 | "strength": "500 mg",
190 | "friends": {
191 | "self": {
192 | "Mike {[Gentleman]}": "33",
193 | "names": [
194 | "aa"
195 | ]
196 | }
197 | }
198 | },
199 | {
200 | "problems": [
201 | {
202 | "xxclasses": [
203 | {
204 | "yyclassNameMissed": [
205 | {
206 | "medicationsClasses": [
207 | {
208 | "Mike {[Gentleman]}": [
209 | {
210 | "associatedDrug": [
211 | {
212 | "name": "asprin",
213 | "dose": "a",
214 | "strength": "500 mg"
215 | }
216 | ],
217 | "Mike {[Gentleman]}": [
218 | {
219 | "name": "somethingElse",
220 | "dose": "",
221 | "strength": "500 mg",
222 | "friends": {
223 | "self": {
224 | "Mike {[Gentleman]}": "33",
225 | "names": [
226 | "aa"
227 | ]
228 | }
229 | }
230 | }
231 | ]
232 | }
233 | ],
234 | "Judy": [
235 | {
236 | "associatedDrug": [
237 | {
238 | "name": "asprin",
239 | "dose": "",
240 | "strength": "500 mg",
241 | "friends": [
242 | "Mike {[Gentleman]}"
243 | ]
244 | }
245 | ],
246 | "associatedDrug#2": [
247 | {
248 | "name": "somethingElse",
249 | "dose": "",
250 | "strength": "500 mg"
251 | }
252 | ],
253 | "friends": [
254 | {
255 | "Mike {[Gentleman]}": null
256 | },
257 | {
258 | "Mike {[Gentleman]}": [
259 | [
260 | "c[ 3\"5ool",
261 | 35
262 | ],
263 | [
264 | "ca],[1\"3lm"
265 | ],
266 | 53
267 | ]
268 | },
269 | "Jackson",
270 | "Mike {[Gentleman]}",
271 | {
272 | "problems": [
273 | {
274 | "classes": [
275 | {
276 | "medications": [
277 | {
278 | "medicationsClasses": [
279 | {
280 | "Mike {[Gentleman]}": [
281 | {
282 | "associatedDrug": [
283 | {
284 | "name": "asprin",
285 | "dose": "a",
286 | "strength": "500 mg"
287 | }
288 | ],
289 | "Mike {[Gentleman]}": [
290 | {
291 | "name": "somethingElse",
292 | "dose": "",
293 | "strength": "500 mg",
294 | "friends": {
295 | "self": {
296 | "Mike {[Gentleman]}": "33",
297 | "names": [
298 | "aa"
299 | ]
300 | }
301 | }
302 | }
303 | ]
304 | }
305 | ],
306 | "Judy": [
307 | {
308 | "associatedDrug": [
309 | {
310 | "name": "asprin",
311 | "dose": "",
312 | "strength": "500 mg",
313 | "friends": [
314 | "Mike {[Gentleman]}"
315 | ]
316 | }
317 | ],
318 | "associatedDrug#2": [
319 | {
320 | "name": "somethingElse",
321 | "dose": "",
322 | "strength": "500 mg"
323 | }
324 | ],
325 | "friends": [
326 | {
327 | "Mike {[Gentleman]}": null
328 | },
329 | {
330 | "Mike {[Gentleman]}": [
331 | [
332 | "c[ 3\"5ool",
333 | 35
334 | ],
335 | [
336 | "ca],[1\"3lm"
337 | ],
338 | 53
339 | ]
340 | },
341 | "Jackson",
342 | "Mike {[Gentleman]}"
343 | ]
344 | }
345 | ]
346 | }
347 | ]
348 | }
349 | ],
350 | "classNameMissed": [
351 | {
352 | "Mike {[Gentleman]}": "missing_value"
353 | }
354 | ]
355 | }
356 | ],
357 | "className": [
358 | {}
359 | ]
360 | }
361 | ]
362 | }
363 | ]
364 | }
365 | ]
366 | }
367 | ]
368 | }
369 | ],
370 | "yyclassNameMissed2": [
371 | {
372 | "Mike {[Gentleman]}": "missing_value"
373 | }
374 | ]
375 | }
376 | ],
377 | "xxclasses2": [
378 | {}
379 | ]
380 | }
381 | ]
382 | }
383 | ]
384 | }
385 | ],
386 | "Judy": [
387 | {
388 | "associatedDrug": [
389 | {
390 | "name": "asprin",
391 | "dose": "",
392 | "strength": "500 mg",
393 | "friends": [
394 | "Mike {[Gentleman]}"
395 | ]
396 | }
397 | ],
398 | "associatedDrug#2": [
399 | {
400 | "name": "somethingElse",
401 | "dose": "",
402 | "strength": "500 mg"
403 | }
404 | ],
405 | "friends": [
406 | {
407 | "Mike {[Gentleman]}": null
408 | },
409 | {
410 | "Mike {[Gentleman]}": [
411 | [
412 | "c[ 3\"5ool",
413 | 35
414 | ],
415 | [
416 | "ca],[1\"3lm"
417 | ],
418 | 53
419 | ]
420 | },
421 | "Jackson",
422 | "Mike {[Gentleman]}"
423 | ]
424 | }
425 | ]
426 | }
427 | ]
428 | }
429 | ],
430 | "classNameMissed": [
431 | {
432 | "Mike {[Gentleman]}": "missing_value"
433 | }
434 | ]
435 | }
436 | ],
437 | "className": [
438 | {}
439 | ]
440 | }
441 | ]
442 | }
443 | ]
444 | }
445 | ]
446 | }
447 | ]
448 | }
449 | ],
450 | "classNameMissed": [
451 | {
452 | "Mike {[Gentleman]}": "missing_value"
453 | }
454 | ]
455 | }
456 | ],
457 | "className": [
458 | {}
459 | ]
460 | }
461 | ]
462 | };
463 |
464 | var original3 ={
465 | "problems": [
466 | {
467 | "classes": [
468 | {
469 | "medications": [
470 | {
471 | "medicationsClasses": [
472 | {
473 | "Mike {[Gentleman]}": [
474 | {
475 | "associatedDrug": [
476 | {
477 | "name": "asprin",
478 | "dose": {"a":[[],3, [{}]],"B":{},"c":[{}]},
479 | "strength": "500 mg"
480 | },
481 | [{
482 | "name15": "asprin",
483 | "dose15": 5,
484 | "strength15": "500 mg"
485 | },22,[true, false]],
486 | [33,{
487 | "name16": "asprin",
488 | "dose16": 6,
489 | "strength16": "500 mg"
490 | }],
491 | {
492 | "name2": "asprin",
493 | "dose2": "a",
494 | "strength2": "500 mg"
495 | },
496 | {
497 | "name3": "asprin",
498 | "dose3": "a",
499 | "strength3": "500 mg"
500 | }
501 | ],
502 | "Mike {[Gentleman]}": [
503 | {
504 | "name": "somethingElse",
505 | "dose": "",
506 | "strength": "500 mg",
507 | "friends": {
508 | "self": {
509 | "Mike {[Gentleman]}": "33",
510 | "names": [
511 | "aa",
512 | true,
513 | {"xxx" : ["zd", 3, 5]}
514 | ]
515 | }
516 | }
517 | }
518 | ]
519 | },
520 | {
521 | "dassociatedDrug": [
522 | {
523 | "name": "asprin",
524 | "dose": "a",
525 | "strength": "500 mg"
526 | }
527 | ],
528 | "Mike {[Gentleman]}": [
529 | {
530 | "name": "somethingElse",
531 | "dose": "",
532 | "strength": "500 mg",
533 | "friends": {
534 | "self": {
535 | "Mike {[Gentleman]}": "33",
536 | "names": [
537 | "aa"
538 | ]
539 | }
540 | }
541 | }
542 | ]
543 | }
544 | ],
545 | "Judy": [
546 | {
547 | "associatedDrug": [
548 | {
549 | "name": "asprin",
550 | "dose": "",
551 | "strength": "500 mg",
552 | "friends": [
553 | "Mike {[Gentleman]}"
554 | ]
555 | }
556 | ],
557 | "associatedDrug#2": [
558 | {
559 | "name": "somethingElse",
560 | "dose": "",
561 | "strength": "500 mg"
562 | }
563 | ],
564 | "friends": [
565 | {
566 | "Mike {[Gentleman]}": null
567 | },
568 | {
569 | "Mike {[Gentleman]}": [
570 | [
571 | "c[ 3\"5ool",
572 | [3,5],
573 | 49
574 | ],
575 | [
576 | "ca],[1\"3lm"
577 | ],
578 | 53
579 | ]
580 | },
581 | "Jackson",
582 | "Mike {[Gentleman]}",
583 | {
584 | "problems": [
585 | {
586 | "aclasses": [
587 | {
588 | "medications": [
589 | {
590 | "medicationsClasses": [
591 | {
592 | "Mike {[Gentleman]}": [
593 | {
594 | "associatedDrug": [
595 | {
596 | "name": "asprin",
597 | "dose": "a",
598 | "strength": "500 mg"
599 | }
600 | ],
601 | "Mike {[Gentleman]}": [
602 | {
603 | "name": "somethingElse",
604 | "dose": "",
605 | "strength": "500 mg",
606 | "friends": {
607 | "self": {
608 | "Mike {[Gentleman]}": "33",
609 | "names": [
610 | "aa"
611 | ]
612 | }
613 | }
614 | },
615 | {
616 | "problems": [
617 | {
618 | "xxclasses": [
619 | {
620 | "yyclassNameMissed": [
621 | {
622 | "medicationsClasses": [
623 | {
624 | "Mike {[Gentleman]}": [
625 | {
626 | "associatedDrug": [
627 | {
628 | "name": "asprin",
629 | "dose": "a",
630 | "strength": "500 mg"
631 | }
632 | ],
633 | "Mike {[Gentleman]}": [
634 | {
635 | "name": "somethingElse",
636 | "dose": "",
637 | "strength": "500 mg",
638 | "friends": {
639 | "self": {
640 | "Mike {[Gentleman]}": "33",
641 | "names": [
642 | "aa"
643 | ]
644 | }
645 | }
646 | }
647 | ]
648 | }
649 | ],
650 | "Judy": [
651 | {
652 | "associatedDrug": [
653 | {
654 | "name": "asprin",
655 | "dose": "",
656 | "strength": "500 mg",
657 | "friends": [
658 | "Mike {[Gentleman]}"
659 | ]
660 | }
661 | ],
662 | "associatedDrug#2": [
663 | {
664 | "name": "somethingElse",
665 | "dose": "",
666 | "strength": "500 mg"
667 | }
668 | ],
669 | "friends": [
670 | {
671 | "Mike {[Gentleman]}": null
672 | },
673 | {
674 | "Mike {[Gentleman]}": [
675 | [
676 | "c[ 3\"5ool",
677 | 35
678 | ],
679 | [
680 | "ca],[1\"3lm"
681 | ],
682 | 53
683 | ]
684 | },
685 | "Jackson",
686 | "Mike {[Gentleman]}",
687 | {
688 | "problems": [
689 | {
690 | "classes": [
691 | {
692 | "medications": [
693 | {
694 | "medicationsClasses": [
695 | {
696 | "Mike {[Gentleman]}": [
697 | {
698 | "associatedDrug": [
699 | {
700 | "name": "asprin",
701 | "dose": "a",
702 | "strength": "500 mg"
703 | }
704 | ],
705 | "Mike {[Gentleman]}": [
706 | {
707 | "name": "somethingElse",
708 | "dose": "",
709 | "strength": "500 mg",
710 | "friends": {
711 | "self": {
712 | "Mike {[Gentleman]}": "33",
713 | "names": [
714 | "aa"
715 | ]
716 | }
717 | }
718 | }
719 | ]
720 | }
721 | ],
722 | "Judy": [
723 | {
724 | "associatedDrug": [
725 | {
726 | "name": "asprin",
727 | "dose": "",
728 | "strength": "500 mg",
729 | "friends": [
730 | "Mike {[Gentleman]}"
731 | ]
732 | }
733 | ],
734 | "associatedDrug#2": [
735 | {
736 | "name": "somethingElse",
737 | "dose": "",
738 | "strength": "500 mg"
739 | }
740 | ],
741 | "friends": [
742 | {
743 | "Mike {[Gentleman]}": null
744 | },
745 | {
746 | "Mike {[Gentleman]}": [
747 | [
748 | "c[ 3\"5ool",
749 | 35
750 | ],
751 | [
752 | "ca],[1\"3lm"
753 | ],
754 | 53
755 | ]
756 | },
757 | "Jackson",
758 | "Mike {[Gentleman]}"
759 | ]
760 | }
761 | ]
762 | }
763 | ]
764 | }
765 | ],
766 | "classNameMissed": [
767 | {
768 | "Mike {[Gentleman]}": "missing_value"
769 | }
770 | ]
771 | }
772 | ],
773 | "className": [
774 | {}
775 | ]
776 | }
777 | ]
778 | }
779 | ]
780 | }
781 | ]
782 | }
783 | ]
784 | }
785 | ],
786 | "yyclassNameMissed2": [
787 | {
788 | "Mike {[Gentleman]}": "missing_value"
789 | }
790 | ]
791 | }
792 | ],
793 | "xxclasses2": [
794 | {}
795 | ]
796 | }
797 | ]
798 | }
799 | ]
800 | }
801 | ],
802 | "Judy": [
803 | {
804 | "associatedDrug": [
805 | {
806 | "name": "asprin",
807 | "dose": "",
808 | "strength": "500 mg",
809 | "friends": [
810 | "Mike {[Gentleman]}"
811 | ]
812 | }
813 | ],
814 | "associatedDrug#2": [
815 | {
816 | "name": "somethingElse",
817 | "dose": "",
818 | "strength": "500 mg"
819 | }
820 | ],
821 | "friends": [
822 | {
823 | "Mike {[Gentleman]}": null
824 | },
825 | {
826 | "Mike {[Gentleman]}": [
827 | [
828 | "c[ 3\"5ool",
829 | 35
830 | ],
831 | [
832 | "ca],[1\"3lm"
833 | ],
834 | 53
835 | ]
836 | },
837 | "Jackson",
838 | "Mike {[Gentleman]}"
839 | ]
840 | }
841 | ]
842 | }
843 | ]
844 | }
845 | ],
846 | "classNameMissed": [
847 | {
848 | "Mike {[Gentleman]}": "missing_value"
849 | }
850 | ]
851 | }
852 | ],
853 | "className": [
854 | {}
855 | ]
856 | }
857 | ]
858 | }
859 | ]
860 | }
861 | ]
862 | }
863 | ]
864 | }
865 | ],
866 | "classNameMissed": [
867 | {
868 | "Mike {[Gentleman]}": "missing_value"
869 | }
870 | ]
871 | }
872 | ],
873 | "className": [
874 | {}
875 | ]
876 | }
877 | ]
878 | };
879 |
--------------------------------------------------------------------------------
/src/controller.js:
--------------------------------------------------------------------------------
1 | import Service from './service';
2 |
3 | /**
4 | * @brief
5 | * Mass Update certain key-values recursively in huge, complex JSON string trees
6 | * @author Andrew Kang
7 | * @param original string required (must be JSON string)
8 | * @param key string required
9 | * @param value string or boolean or number required
10 | * @return string
11 | */
12 | function sculptJson(original, key, value){
13 |
14 | if (!(original && typeof original === 'string')) {
15 | throw new Error('the variable "original" must be a string type and not be null.');
16 | }else if (!(key && typeof key === 'string')) {
17 | throw new Error('the variable "key" must be a string type and not be null.');
18 | }else if (/"/.test(key)) {
19 | throw new Error('the variable "key" must not contain double quotes, but this can be allowed in the next version.');
20 | }else if (! ((value && (typeof value === 'string' || typeof value === 'number'|| typeof value === 'boolean')) || (typeof value == 'object' && value == null))) {
21 | throw new Error('the variable "value" must be a string or number or boolean or null.');
22 | }
23 |
24 | if(value && typeof value === 'string') {
25 | value = value.replace(/([^\u005C])"/g, '$1\\"');
26 | }
27 | original = original.trim();
28 |
29 | return Service.sculpt(original, Service.getMaterials(original, key, value));
30 | }
31 |
32 | /**
33 | * @brief
34 | * [Research] Deep-compare two JSONs regardless of positions of every 'key' in objects but considering positions of elements in arrays.
35 | * @author Andrew Kang
36 | * @param original string required (must be JSON string)
37 | * @param original2 string required (must be JSON string)
38 | * @return string
39 | */
40 | function deepCompare(original, original2){
41 |
42 | if (!(original && typeof original === 'string')) {
43 | throw new Error('the variable "original" must be a string type and not be null.');
44 | }else if (!(original2 && typeof original2 === 'string')) {
45 | throw new Error('the variable "original2" must be a string type and not be null.');
46 | }
47 |
48 | original = original.trim();
49 | original2 = original2.trim();
50 |
51 | return Service.deepCompare(original, original2);
52 | }
53 |
54 |
55 | export default {
56 |
57 | sculptJson
58 |
59 | };
--------------------------------------------------------------------------------
/src/entry.js:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | *
4 | * -- Url-knife --
5 | *
6 | * Copyright (c) 2019 Andrew Kang
7 | *
8 | * The MIT License (MIT)
9 |
10 | Copyright (c) 2011-2018 Twitter, Inc.
11 | Copyright (c) 2011-2018 The Bootstrap Authors
12 |
13 | Permission is hereby granted, free of charge, to any person obtaining a copy
14 | of this software and associated documentation files (the "Software"), to deal
15 | in the Software without restriction, including without limitation the rights
16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 | copies of the Software, and to permit persons to whom the Software is
18 | furnished to do so, subject to the following conditions:
19 |
20 | The above copyright notice and this permission notice shall be included in
21 | all copies or substantial portions of the Software.
22 |
23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29 | THE SOFTWARE.
30 |
31 |
32 | * */
33 |
34 | import Pattern from './controller';
35 |
36 | export default Pattern;
37 |
--------------------------------------------------------------------------------
/src/pattern.js:
--------------------------------------------------------------------------------
1 | import Util from './util';
2 |
3 | const commons = {
4 |
5 | spaceOrNot: '[\\n\\r\\t\\s]*',
6 | spaceOrNotOrComma: '[,\\n\\r\\t\\s]*',
7 | spaceOrBigStartBracketOrNot: '[\\[\\n\\r\\t\\s]*',
8 | spaceOrStartBracketOrNot: '[\\[{\\n\\r\\t\\s]*',
9 | spaceOrEndBracketOrNot: '[}\\]\\n\\r\\t\\s]*',
10 | everything: '(?:.|[\\n\\r\\t\\s])'
11 |
12 | }
13 |
14 | const jsonBase = {
15 |
16 | // key starts with two patterns (1) {"key": (2) ,"key" :
17 | key(k = null) {
18 | if (k) {
19 | return '[,{]' +
20 | commons.spaceOrNot +
21 | '"(' + k + ')"' +
22 | commons.spaceOrNot +
23 | ':' +
24 | commons.spaceOrNot;
25 | } else {
26 | return '[,{]' +
27 | commons.spaceOrNot +
28 | jsonBase.keyType +
29 | commons.spaceOrNot +
30 | ':' +
31 | commons.spaceOrNot;
32 | }
33 | },
34 |
35 |
36 | //keyType : '"((?:[^"\\\\]|\\\\"|\\\\[^"])*)"',
37 | keyType: '"((?:[^"]*?[^\\u005C])|(?:(?=[^"]*[\\u005C]").*?[^\\u005C]))"',
38 |
39 | valueType: {
40 | // 2
41 | string: '(""|".*?[^\\u005C]")',
42 | // 3
43 | //number: '([-+]?(?:\\d+\\.?\\d*|\\d*\.?\\d+)(?:[Ee][-+]?[0-2]?\\d{1,2})?)',
44 | number : '(-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)',
45 | // 4
46 | boolean: '(true|false)',
47 | // 5
48 | object: '({)',
49 | // 6
50 | array: '(\\[)',
51 | // 7
52 | empty: '(null|undefined)',
53 | // 7
54 | emptyObject: '{' + commons.spaceOrNot + '}',
55 |
56 | /* // 2
57 |
58 | astring: '(?:".*?[^\\u005C\\u0022]"|"")',
59 | // 3
60 | anumber: '(?:[-+]?(?:\\d+\\.?\\d*|\\d*\.?\\d+)(?:[Ee][-+]?[0-2]?\\d{1,2})?)',
61 | // 4
62 | aboolean: '(?:true|false)',
63 | // 5
64 | aobject: '(?:{)',
65 | // 6
66 | aarray: '(?:\\[)',
67 | // 7
68 | aempty: '(?:null)',*/
69 | },
70 |
71 | valueType2: {
72 |
73 | string: '(?:""|".*?[^\\u005C]")',
74 |
75 | number : '(?:-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)',
76 |
77 | boolean: '(?:true|false)',
78 |
79 | empty: '(?:null|undefined)',
80 |
81 | emptyObject: '{' + commons.spaceOrNot + '}',
82 |
83 | // 7
84 | emptyArray: '\\[' + commons.spaceOrNot + '\\]',
85 | }
86 |
87 | }
88 |
89 | // This is for service.js -> calculateSteps
90 | const steps = {
91 |
92 | // withKey is areas where JSON sets up hierarchies(steps).
93 | withKey: '(' +
94 | // }],[[{
95 | commons.spaceOrEndBracketOrNot +
96 | ',' +
97 | '(?:' +
98 | '[\\[\\n\\r\\t\\s]*{[\\[\\n\\r\\t\\s]*)+' +
99 | '|' +
100 | // }],
101 | commons.spaceOrEndBracketOrNot +
102 | ',' +
103 | '|' +
104 | // [[{
105 | '(?:[\\[\\n\\r\\t\\s]*{[\\[\\n\\r\\t\\s]*)+' +
106 | ')' +
107 |
108 | commons.spaceOrNot +
109 | jsonBase.keyType +
110 | commons.spaceOrNot +
111 | ':' +
112 | commons.spaceOrNot,
113 |
114 |
115 | // withNoKey is areas where JSON sets up hierarchies(steps).
116 | withNoKey(includeNoStepAreas = true) {
117 |
118 | const token = includeNoStepAreas ? '|' : '';
119 |
120 | return '(' +
121 |
122 | '(' +
123 |
124 | /* 1. -> }]},{, }]},[ */
125 |
126 | // catch desc symbols
127 | '(' +
128 | '(?:' + commons.spaceOrNot + '[\\]}]' + commons.spaceOrNot + ')+' +
129 | token + ')' +
130 |
131 | ',' +
132 |
133 | commons.spaceOrStartBracketOrNot +
134 |
135 | '|' +
136 |
137 | /* 2. -> [ */
138 | // don't need to catch asc symbols
139 | '(?:' + commons.spaceOrNot + '\\[' + commons.spaceOrNot + ')+' +
140 |
141 | ')' +
142 |
143 | '(' +
144 | jsonBase.valueType2.string + '|'
145 | + jsonBase.valueType2.number + '|'
146 | + jsonBase.valueType2.boolean + '|'
147 | + jsonBase.valueType2.empty + '|'
148 | + jsonBase.valueType2.emptyObject + '|'
149 | + jsonBase.valueType2.emptyArray +
150 | ')' +
151 |
152 | '|(' + jsonBase.valueType2.emptyObject + '|' + jsonBase.valueType2.emptyArray +'))'
153 |
154 | },
155 |
156 |
157 | asc: '[\\[{]',
158 | desc: '[\\]}]',
159 | toNumberOfGap(number) {
160 | return '(?:' + commons.spaceOrNot + '[\\]},]' + commons.spaceOrNot + ')' + '{' + number + '}$';
161 | }
162 |
163 | }
164 |
165 | // This is for service.js -> getMaterials
166 | function jsonOutput(k) {
167 |
168 | return jsonBase.key(k) + '(?:' + jsonBase.valueType.string + '|'
169 | + jsonBase.valueType.number + '|'
170 | + jsonBase.valueType.boolean + '|'
171 | + jsonBase.valueType.object + '|'
172 | + jsonBase.valueType.array + '|'
173 | + jsonBase.valueType.empty + ')'
174 |
175 | }
176 |
177 |
178 | function jsonOutput2() {
179 |
180 | return steps.withKey + '(' + jsonBase.valueType2.string + '|'
181 | + jsonBase.valueType2.number + '|'
182 | + jsonBase.valueType2.boolean + '|'
183 | + jsonBase.valueType2.empty + '|'
184 | + ')'
185 |
186 | }
187 |
188 | export default {
189 | commons, jsonBase, jsonOutput, jsonOutput2, steps
190 | }
--------------------------------------------------------------------------------
/src/service.js:
--------------------------------------------------------------------------------
1 | import Pattern from './pattern';
2 | import Util from './util';
3 |
4 |
5 | function getMatchedGroupNumber(match) {
6 | for (let a = 2; a < 8; a++) {
7 | if (match[a] !== undefined) {
8 | return a;
9 | }
10 | }
11 | }
12 |
13 | function adjustPreviousLastIndex(previousLastIndex, downArea, stepGapCnt) {
14 |
15 | let stepGapLength = 0;
16 |
17 | let rx = new RegExp(Pattern.steps.toNumberOfGap(stepGapCnt), '');
18 | let match = {};
19 | if ((match = rx.exec(downArea)) !== null) {
20 | stepGapLength = match[0].length;
21 | /* console.log('previousLastIndex : ' + previousLastIndex);
22 | console.log('downArea : ' + downArea);
23 | console.log('stepGapCnt : ' + stepGapCnt);
24 | console.log('stepgapLEN : ' + stepGapLength);*/
25 | }
26 |
27 |
28 | return previousLastIndex - stepGapLength;
29 | }
30 |
31 |
32 |
33 |
34 |
35 | /*
36 | * match information
37 | *
38 | * 0 : as you are aware, match[0] is just the whole match
39 | *
40 | * 1~2 : withKey
41 | * 1 : front of key
42 | * 2 : only key
43 | *
44 | * 3 : final area (the very end of json, the final of the loop below, whole match)
45 | *
46 | * 4~7 : withNoKey
47 | * 4 : whole match
48 | * 5 : front of 'one value of array' - [[
49 | * 6 : only down front of 'one value of array' - }]
50 | * 7 : one value - "aaa", 5, true...
51 | * 8 : {}, [] (empty object or array)
52 |
53 | * */
54 |
55 |
56 | function calculateSteps(original, key) {
57 |
58 | let stepAreas = [];
59 | let keySteps = [];
60 |
61 | let idx = 0;
62 |
63 | try {
64 |
65 | let rx = new RegExp('(?:' + Pattern.steps.withKey + ')|' +
66 | '(' + Pattern.commons.spaceOrEndBracketOrNot + '$)|' +
67 | '(?:' + Pattern.steps.withNoKey(true) + ')', 'g');
68 |
69 | let stepMilestone = null;
70 | let match = {};
71 |
72 | while ((match = rx.exec(original)) !== null) {
73 |
74 | let step = idx > 0 ? stepAreas[idx - 1]['step'] : 0;
75 |
76 | /* one value of array */
77 | if (match[4]) {
78 |
79 | //console.log('4 : ');
80 | //console.log(match);
81 | if (match[5]) {
82 | step += (match[5].match(new RegExp(Pattern.steps.asc, "g")) || []).length;
83 | step -= (match[5].match(new RegExp(Pattern.steps.desc, "g")) || []).length;
84 | }
85 |
86 | let previousLastIndex = null;
87 |
88 | if (match[6]) {
89 | const downArea = match[6];
90 | const downAreaLength = downArea.length;
91 |
92 | previousLastIndex = match.index + downAreaLength;
93 |
94 | if (stepMilestone >= step) {
95 |
96 | if (stepMilestone === step) {
97 |
98 | keySteps.push(previousLastIndex);
99 | stepMilestone = null;
100 |
101 | } else {
102 |
103 | keySteps.push(adjustPreviousLastIndex(previousLastIndex, downArea, stepMilestone - step));
104 | stepMilestone = null;
105 | }
106 | }
107 | }
108 |
109 | stepAreas.push({
110 | step: step,
111 | previousLastIndex: previousLastIndex,
112 | key: null,
113 | noKey: match[0],
114 | debugInfo: match
115 | });
116 |
117 | idx += 1;
118 |
119 | continue;
120 | }
121 |
122 | /* final area : all JSONs end at this point with the command 'break' */
123 | if (match[3]) {
124 |
125 | //console.log('3 : ');
126 | //console.log(match);
127 | let previousLastIndex = null;
128 |
129 | if (key === stepAreas[stepAreas.length - 1].key) {
130 |
131 | previousLastIndex = match.index + match[3].length;
132 |
133 | keySteps.push(adjustPreviousLastIndex(previousLastIndex, match[3], stepAreas[stepAreas.length - 1].step));
134 | stepMilestone = null;
135 | }
136 |
137 | if (stepMilestone !== null) {
138 |
139 | previousLastIndex = match.index + match[3].length;
140 |
141 | keySteps.push(adjustPreviousLastIndex(previousLastIndex, match[3], stepMilestone));
142 | stepMilestone = null;
143 | }
144 |
145 | const finalStep = step - (match[0].match(new RegExp(Pattern.steps.desc, "g")) || []).length;
146 |
147 | stepAreas.push({
148 | step: finalStep,
149 | previousLastIndex: previousLastIndex,
150 | key: null,
151 | noKey: null,
152 | //debugInfo: match,
153 | });
154 |
155 | // Fail to calculate steps
156 | if (finalStep !== 0) {
157 | throw new Error('The final step should be 0.')
158 | }
159 |
160 | break;
161 |
162 | }
163 |
164 | /* Key area */
165 |
166 | //console.log('normal : ');
167 | //console.log(match);
168 |
169 | let downArea = match[1].match(new RegExp('^' + Pattern.commons.spaceOrEndBracketOrNot, "g"))[0];
170 | let descCnt = (match[1].match(new RegExp(Pattern.steps.desc, "g")) || []).length;
171 | let ascCnt = (match[1].match(new RegExp(Pattern.steps.asc, "g")) || []).length;
172 |
173 |
174 | step += ascCnt;
175 | step -= descCnt;
176 |
177 |
178 | let previousLastIndex = match.index + downArea.length;
179 | let stepGapLength = 0;
180 |
181 | if (stepMilestone >= step) {
182 |
183 | if (stepMilestone === step) {
184 |
185 | keySteps.push(previousLastIndex);
186 | stepMilestone = null;
187 |
188 | } else {
189 |
190 | keySteps.push(adjustPreviousLastIndex(previousLastIndex, downArea, stepMilestone - step + ascCnt));
191 | stepMilestone = null;
192 | }
193 | }
194 |
195 | if (key === match[2] && stepMilestone == null) {
196 | stepMilestone = step;
197 | }
198 |
199 | stepAreas.push({
200 | step: step,
201 | previousLastIndex: previousLastIndex,
202 | key: match[2],
203 | noKey: null,
204 | //debugInfo: match
205 | });
206 |
207 | idx += 1;
208 | }
209 |
210 | }catch (e) {
211 | console.log('The error has occurred at idx : ' + idx)
212 | console.log(stepAreas)
213 | console.log(keySteps)
214 | throw e;
215 | }finally {
216 | /* console.log(stepAreas)
217 | console.log(keySteps)*/
218 | }
219 |
220 |
221 | return keySteps;
222 | }
223 |
224 |
225 | function getMaterials(original, key, value) {
226 |
227 | if (typeof value == "string") {
228 | value = '"' + value + '"';
229 | }
230 |
231 | let extractedAreas = [];
232 |
233 | let rx = new RegExp(Pattern.jsonOutput(Util.Text.escapeRegex(key)), 'g');
234 |
235 | let matches = [];
236 | let match = {};
237 |
238 | let calculateStepsDone = false;
239 | let keySteps = [];
240 |
241 | let idx = 0;
242 | while ((match = rx.exec(original)) !== null) {
243 |
244 | //console.log(match)
245 |
246 | const matchedKeyValue = match[0];
247 |
248 | const matchedGroupNumber = getMatchedGroupNumber(match);
249 |
250 | const newMatchedKeyValue = matchedKeyValue.replace(new RegExp(Util.Text.escapeRegex(match[matchedGroupNumber]) + '$'), value);
251 |
252 | const startIndex = match.index;
253 | let lastIndex = match.index + match[0].length;
254 |
255 |
256 | if (extractedAreas.find(x => x.startIndex < startIndex && x.lastIndex > startIndex)) {
257 | continue;
258 | }
259 |
260 | if (matchedGroupNumber === 5 || matchedGroupNumber === 6) {
261 |
262 | if (!calculateStepsDone) {
263 |
264 | keySteps = calculateSteps(original, key);
265 | calculateStepsDone = true;
266 |
267 | }
268 | lastIndex = keySteps[idx];
269 |
270 | }
271 |
272 | extractedAreas.push({
273 | value: value,
274 | //aaa : match[matchedGroupNumber],
275 | matchedKeyValue: matchedKeyValue,
276 | newMatchedKeyValue: newMatchedKeyValue,
277 | startIndex: startIndex,
278 | lastIndex: lastIndex,
279 | });
280 |
281 | idx += 1;
282 | }
283 |
284 | //console.log('※ getMaterials');
285 | //console.log(keySteps);
286 | //console.log(extractedAreas);
287 |
288 | return extractedAreas;
289 | }
290 |
291 | function sculpt(original, materials) {
292 |
293 | materials.reverse().forEach(function (val, idx) {
294 | original = Util.Text.replaceBetween(original, val.startIndex, val.lastIndex, val.newMatchedKeyValue);
295 | });
296 |
297 | return original;
298 |
299 | }
300 |
301 | /*
302 | * match information
303 | *
304 | * 0 : as you are aware, match[0] is just the whole match
305 | *
306 | * 1~3 : withKey
307 | * 1 : front of key
308 | * 2 : only key
309 | * 3 : only value
310 | *
311 | * 4 : final area (the very end of json, the final of the loop below, whole match)
312 | *
313 | * 5~8 : withNoKey
314 | * 5 : whole match
315 | * 6 : front of 'one value of array' - [[
316 | * 7 : only down front of 'one value of array' - }]
317 | * 8 : one value - "aaa", 5, true...
318 | * 9 : {}, [] (empty object or array)
319 | *
320 | * */
321 |
322 | /**
323 | * Extract every single key and value and their meta data, which consists of 'step', 'order' and 'ancestors'.
324 | *
325 | * @param {string} original JSON string to parse.
326 | * @return {array} True if the DOM is a valid DOM node.
327 | * @internal
328 | */
329 |
330 | function getAbsoluteKeyValueMetaData(original) {
331 |
332 | let stepAreas = [];
333 | let idx = 0;
334 |
335 | try {
336 |
337 | let rx = new RegExp('(?:' + Pattern.jsonOutput2() + ')|' +
338 | '(' + Pattern.commons.spaceOrEndBracketOrNot + '$)|' +
339 | '(?:' + Pattern.steps.withNoKey(true) + ')', 'g');
340 |
341 | let match = {};
342 |
343 | let ancestors = [];
344 |
345 | let previousKey = null;
346 | let previousStep = 0;
347 |
348 | // To get an order in an array, we use steps of array.
349 | // arrayStepStore.push(ancestors[ancestors.length - 1]['step']) means that the param below 'order' has been +1 increased, and the step value itself is used to remove ancestors of the current key or value's own.
350 | let arrayStepStore = [];
351 |
352 | let ancestorCandidateKey = null;
353 | let ancestorCandidateStep = 0;
354 | let ancestorCandidateValue = null;
355 |
356 | ancestors.push({key: 'ORIGIN', step: ancestorCandidateStep});
357 |
358 | while ((match = rx.exec(original)) !== null) {
359 |
360 | let step = previousStep;
361 |
362 | /* withNoKey */
363 | if (match[5]) {
364 |
365 | let order = null;
366 |
367 | if (match[6]) {
368 | step += (match[6].match(new RegExp(Pattern.steps.asc, "g")) || []).length;
369 | step -= (match[6].match(new RegExp(Pattern.steps.desc, "g")) || []).length;
370 |
371 |
372 | //if (ancestors.length > 1) {
373 | if (/,/.test(match[6])) {
374 | // console.log('idx : ' + idx + ' / step : ' + ancestors[ancestors.length - 1]['step'])
375 | arrayStepStore.push(ancestors[ancestors.length - 1]['step']);
376 |
377 | order = arrayStepStore.filter(x => x === ancestors[ancestors.length - 1]['step']).length;
378 | if (order === 0) {
379 | order = null;
380 | }
381 | }
382 | if (/\[/.test(match[6])) {
383 |
384 | if (ancestorCandidateStep < step) {
385 | // the previous ancestor is not fake, which means they had array or object values. If they had one string or number thing, they are fake ancestors.
386 | if (ancestorCandidateValue == '') {
387 | ancestors.push({key: ancestorCandidateKey, step: ancestorCandidateStep});
388 | }
389 | } else if (ancestorCandidateStep >= step) {
390 | ancestors = ancestors.filter((x) => x.step < step);
391 | }
392 |
393 | arrayStepStore = arrayStepStore.filter(x => x !== ancestors[ancestors.length - 1]['step']);
394 | arrayStepStore.push(ancestors[ancestors.length - 1]['step']);
395 |
396 | order = 1;
397 | }
398 | }
399 |
400 | stepAreas.push({
401 | // type: 'withNoKey',
402 | step: step,
403 | order: order,
404 | key: null,
405 | // match[9] : empty object or array
406 | value: match[9] ? match[9] : match[8],
407 | ancestors: [...ancestors],
408 | //debugInfo: match
409 | });
410 |
411 | previousStep = step;
412 | previousKey = null;
413 |
414 |
415 | /* final area : all JSONs end at this point with the command 'break' */
416 | } else if (match[4]) {
417 |
418 | if (idx === 0) {
419 | stepAreas.push({
420 | step: null,
421 | order: null,
422 | key: null,
423 | value: null,
424 | ancestors: null,
425 | etc: original,
426 | //debugInfo: match
427 | });
428 |
429 | break;
430 | }
431 |
432 | const finalStep = step - (match[0].match(new RegExp(Pattern.steps.desc, "g")) || []).length;
433 |
434 | stepAreas.push({
435 | // type: 'final',
436 | step: finalStep,
437 | order: null,
438 | key: null,
439 | value: null,
440 | ancestors: null,
441 | etc: match[4]
442 | //debugInfo: match
443 | });
444 |
445 | // Fail to calculate steps
446 | if (finalStep !== 0) {
447 | throw new Error('The final step should be 0.')
448 | }
449 |
450 | break;
451 |
452 | /* withKey */
453 | } else {
454 |
455 | let order = null;
456 |
457 | step += (match[1].match(new RegExp(Pattern.steps.asc, "g")) || []).length;
458 | step -= (match[1].match(new RegExp(Pattern.steps.desc, "g")) || []).length;
459 |
460 | if (ancestorCandidateStep < step) {
461 | // the previous ancestor is not fake, which means they had array or object values. If they had one string or number thing, they are fake ancestors.
462 | if (ancestorCandidateValue == '') {
463 | ancestors.push({
464 | key: ancestorCandidateKey,
465 | step: ancestorCandidateStep
466 | });
467 | }
468 | } else if (ancestorCandidateStep >= step) {
469 | ancestors = ancestors.filter((x) => x.step < step);
470 | }
471 |
472 | // if (ancestors.length > 0) {
473 | if (/,/.test(match[1])) {
474 |
475 | if (/{/.test(match[1])) {
476 | arrayStepStore.push(ancestors[ancestors.length - 1]['step']);
477 | }
478 | order = arrayStepStore.filter(x => x === ancestors[ancestors.length - 1]['step']).length;
479 | if (order === 0) {
480 | order = null;
481 | }
482 | }
483 | if (/\[/.test(match[1])) {
484 |
485 | arrayStepStore = arrayStepStore.filter(x => x !== ancestors[ancestors.length - 1]['step']);
486 | arrayStepStore.push(ancestors[ancestors.length - 1]['step']);
487 |
488 | if (/,/.test(match[1])) {
489 | arrayStepStore.push(ancestors[ancestors.length - 1]['step']);
490 | order = arrayStepStore.filter(x => x === ancestors[ancestors.length - 1]['step']).length;
491 | } else {
492 | order = 1;
493 | }
494 |
495 | }
496 | // }
497 |
498 | stepAreas.push({
499 | // type: 'withKey',
500 | step: step,
501 | order: order,
502 | key: match[2],
503 | value: match[3],
504 | ancestors: [...ancestors],
505 | //debugInfo: match
506 | });
507 |
508 | previousStep = step;
509 | previousKey = match[2];
510 |
511 | ancestorCandidateStep = previousStep;
512 | ancestorCandidateKey = previousKey;
513 | ancestorCandidateValue = match[3];
514 | }
515 |
516 | idx += 1;
517 | }
518 | }catch (e) {
519 | console.log('The error has occurred at idx : ' + idx)
520 | console.log(stepAreas);
521 | throw e;
522 | }finally {
523 | //console.log(stepAreas);
524 | }
525 |
526 | return stepAreas;
527 | }
528 |
529 | function arraysEqual(a, b) {
530 | a = Array.isArray(a) ? a : [];
531 | b = Array.isArray(b) ? b : [];
532 | return a.length === b.length && a.every((el, ix) => el === b[ix]);
533 | }
534 |
535 | function s(x, y) {
536 | var pre = ['string', 'number', 'bool']
537 | if (typeof x !== typeof y) return pre.indexOf(typeof y) - pre.indexOf(typeof x);
538 |
539 | if (x === y) return 0;
540 | else return (x > y) ? 1 : -1;
541 |
542 | }
543 |
544 | function deepCompare(original, original2) {
545 |
546 | const keySteps = getAbsoluteKeyValueMetaData(original).map((x) => JSON.stringify(x)).sort(s);
547 | const keySteps2 = getAbsoluteKeyValueMetaData(original2).map((x) => JSON.stringify(x)).sort(s);
548 |
549 | return arraysEqual(keySteps, keySteps2)
550 | }
551 |
552 |
553 | export default {
554 |
555 | getMaterials, sculpt, deepCompare
556 | }
--------------------------------------------------------------------------------
/src/util.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Private : Utils
3 | * */
4 | import Pattern from './pattern';
5 |
6 | const Text = {
7 |
8 | replaceBetween(from, start, end, what) {
9 | return from.substring(0, start) + what + from.substring(end);
10 | },
11 | escapeRegex(v) {
12 | return v.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
13 | },
14 |
15 |
16 | };
17 |
18 | export default {
19 | Text
20 | }
--------------------------------------------------------------------------------
/test/answer.js:
--------------------------------------------------------------------------------
1 | const n1 = "{\"problems\":[{\"classes\":[{\"medications\":[{\"medicationsClasses\":[{\"Mike {[Gentleman]}\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"a\",\"strength\":\"500 mg\"}],\"Mike {[Gentleman]}\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":{\"self\":{\"Mike {[Gentleman]}\":\"33\",\"names\":[\"aa\"]}}}]}],\"Judy\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":[\"Mike {[Gentleman]}\"]}],\"associatedDrug#2\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\"}],\"friends\":[{\"Mike {[Gentleman]}\":null},{\"Mike {[Gentleman]}\":[[\"c[ 3\\\"5ool\",35],[\"ca],[1\\\"3lm\"],53]},\"Jackson\",\"Mike {[Gentleman]}\",{\"problems\":[{\"aclasses\":[{\"medications\":[{\"medicationsClasses\":[{\"Mike {[Gentleman]}\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"a\",\"strength\":\"500 mg\"}],\"Mike {[Gentleman]}\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":{\"self\":{\"Mike {[Gentleman]}\":\"33\",\"names\":[\"aa\"]}}},{\"problems\":[{\"xxclasses\":[{\"yyclassNameMissed\":[{\"medicationsClasses\":[{\"Mike {[Gentleman]}\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"a\",\"strength\":\"500 mg\"}],\"Mike {[Gentleman]}\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":{\"self\":{\"Mike {[Gentleman]}\":\"33\",\"names\":[\"aa\"]}}}]}],\"Judy\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":[\"Mike {[Gentleman]}\"]}],\"associatedDrug#2\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\"}],\"friends\":[{\"Mike {[Gentleman]}\":null},{\"Mike {[Gentleman]}\":[[\"c[ 3\\\"5ool\",35],[\"ca],[1\\\"3lm\"],53]},\"Jackson\",\"Mike {[Gentleman]}\",{\"problems\":[{\"classes\":[{\"medications\":[{\"medicationsClasses\":[{\"Mike {[Gentleman]}\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"a\",\"strength\":\"500 mg\"}],\"Mike {[Gentleman]}\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":{\"self\":{\"Mike {[Gentleman]}\":\"33\",\"names\":[\"aa\"]}}}]}],\"Judy\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":[\"Mike {[Gentleman]}\"]}],\"associatedDrug#2\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\"}],\"friends\":[{\"Mike {[Gentleman]}\":null},{\"Mike {[Gentleman]}\":[[\"c[ 3\\\"5ool\",35],[\"ca],[1\\\"3lm\"],53]},\"Jackson\",\"Mike {[Gentleman]}\"]}]}]}],\"classNameMissed\":[{\"Mike {[Gentleman]}\":\"missing_value\"}]}],\"className\":[{}]}]}]}]}]}],\"yyclassNameMissed2\":[{\"Mike {[Gentleman]}\":\"missing_value\"}]}],\"xxclasses2\":[{}]}]}]}],\"Judy\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":[\"Mike {[Gentleman]}\"]}],\"associatedDrug#2\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\"}],\"friends\":[{\"Mike {[Gentleman]}\":null},{\"Mike {[Gentleman]}\":[[\"c[ 3\\\"5ool\",35],[\"ca],[1\\\"3lm\"],53]},\"Jackson\",\"Mike {[Gentleman]}\"]}]}]}],\"classNameMissed\":[{\"Mike {[Gentleman]}\":\"missing_value\"}]}],\"className\":[{}]}]}]}]}]}],\"classNameMissed\":[{\"Mike {[Gentleman]}\":\"missing_value\"}]}],\"className\":[{}]}]}"
2 |
3 | const n2 = "{\"problems\":[{\"classes\":[{\"medications\":[{\"medicationsClasses\":[{\"Mike {[Gentleman]}\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"a\",\"strength\":\"500 mg\"}],\"Mike {[Gentleman]}\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":{\"self\":null}}]}],\"Judy\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":[\"Mike {[Gentleman]}\"]}],\"associatedDrug#2\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\"}],\"friends\":[{\"Mike {[Gentleman]}\":null},{\"Mike {[Gentleman]}\":[[\"c[ 3\\\"5ool\",35],[\"ca],[1\\\"3lm\"],53]},\"Jackson\",\"Mike {[Gentleman]}\",{\"problems\":[{\"aclasses\":[{\"medications\":[{\"medicationsClasses\":[{\"Mike {[Gentleman]}\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"a\",\"strength\":\"500 mg\"}],\"Mike {[Gentleman]}\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":{\"self\":null}},{\"problems\":[{\"xxclasses\":[{\"yyclassNameMissed\":[{\"medicationsClasses\":[{\"Mike {[Gentleman]}\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"a\",\"strength\":\"500 mg\"}],\"Mike {[Gentleman]}\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":{\"self\":null}}]}],\"Judy\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":[\"Mike {[Gentleman]}\"]}],\"associatedDrug#2\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\"}],\"friends\":[{\"Mike {[Gentleman]}\":null},{\"Mike {[Gentleman]}\":[[\"c[ 3\\\"5ool\",35],[\"ca],[1\\\"3lm\"],53]},\"Jackson\",\"Mike {[Gentleman]}\",{\"problems\":[{\"classes\":[{\"medications\":[{\"medicationsClasses\":[{\"Mike {[Gentleman]}\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"a\",\"strength\":\"500 mg\"}],\"Mike {[Gentleman]}\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":{\"self\":null}}]}],\"Judy\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":[\"Mike {[Gentleman]}\"]}],\"associatedDrug#2\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\"}],\"friends\":[{\"Mike {[Gentleman]}\":null},{\"Mike {[Gentleman]}\":[[\"c[ 3\\\"5ool\",35],[\"ca],[1\\\"3lm\"],53]},\"Jackson\",\"Mike {[Gentleman]}\"]}]}]}],\"classNameMissed\":[{\"Mike {[Gentleman]}\":\"missing_value\"}]}],\"className\":[{}]}]}]}]}]}],\"yyclassNameMissed2\":[{\"Mike {[Gentleman]}\":\"missing_value\"}]}],\"xxclasses2\":[{}]}]}]}],\"Judy\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":[\"Mike {[Gentleman]}\"]}],\"associatedDrug#2\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\"}],\"friends\":[{\"Mike {[Gentleman]}\":null},{\"Mike {[Gentleman]}\":[[\"c[ 3\\\"5ool\",35],[\"ca],[1\\\"3lm\"],53]},\"Jackson\",\"Mike {[Gentleman]}\"]}]}]}],\"classNameMissed\":[{\"Mike {[Gentleman]}\":\"missing_value\"}]}],\"className\":[{}]}]}]}]}]}],\"classNameMissed\":[{\"Mike {[Gentleman]}\":\"missing_value\"}]}],\"className\":[{}]}]}";
4 |
5 | const n3 = "{\"problems\":[{\"classes\":[{\"medications\":[{\"medicationsClasses\":[{\"Mike {[Gentleman]}\":null,\"Judy\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":[\"Mike {[Gentleman]}\"]}],\"associatedDrug#2\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\"}],\"friends\":[{\"Mike {[Gentleman]}\":null},{\"Mike {[Gentleman]}\":null},\"Jackson\",\"Mike {[Gentleman]}\",{\"problems\":[{\"aclasses\":[{\"medications\":[{\"medicationsClasses\":[{\"Mike {[Gentleman]}\":null,\"Judy\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":[\"Mike {[Gentleman]}\"]}],\"associatedDrug#2\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\"}],\"friends\":[{\"Mike {[Gentleman]}\":null},{\"Mike {[Gentleman]}\":null},\"Jackson\",\"Mike {[Gentleman]}\"]}]}]}],\"classNameMissed\":[{\"Mike {[Gentleman]}\":null}]}],\"className\":[{}]}]}]}]}]}],\"classNameMissed\":[{\"Mike {[Gentleman]}\":null}]}],\"className\":[{}]}]}";
6 |
7 | const n4 = "{\"problems\":[{\"classes\":[{\"medications\":[{\"medicationsClasses\":[{\"Mike {[Gentleman]}\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"a\",\"strength\":\"500 mg\"}],\"Mike {[Gentleman]}\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":{\"self\":{\"Mike {[Gentleman]}\":\"33\",\"names\":[\"aa\"]}}}]}],\"Judy\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":[\"Mike {[Gentleman]}\"]}],\"associatedDrug#2\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\"}],\"friends\":[{\"Mike {[Gentleman]}\":null},{\"Mike {[Gentleman]}\":[[\"c[ 3\\\"5ool\",35],[\"ca],[1\\\"3lm\"],53]},\"Jackson\",\"Mike {[Gentleman]}\",{\"problems\":[{\"aclasses\":[{\"medications\":[{\"medicationsClasses\":[{\"Mike {[Gentleman]}\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"a\",\"strength\":\"500 mg\"}],\"Mike {[Gentleman]}\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":{\"self\":{\"Mike {[Gentleman]}\":\"33\",\"names\":[\"aa\"]}}},{\"problems\":[{\"xxclasses\":[{\"yyclassNameMissed\":[{\"medicationsClasses\":[{\"Mike {[Gentleman]}\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"a\",\"strength\":\"500 mg\"}],\"Mike {[Gentleman]}\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":{\"self\":{\"Mike {[Gentleman]}\":\"33\",\"names\":[\"aa\"]}}}]}],\"Judy\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":[\"Mike {[Gentleman]}\"]}],\"associatedDrug#2\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\"}],\"friends\":[{\"Mike {[Gentleman]}\":null},{\"Mike {[Gentleman]}\":[[\"c[ 3\\\"5ool\",35],[\"ca],[1\\\"3lm\"],53]},\"Jackson\",\"Mike {[Gentleman]}\",{\"problems\":[{\"classes\":[{\"medications\":[{\"medicationsClasses\":[{\"Mike {[Gentleman]}\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"a\",\"strength\":\"500 mg\"}],\"Mike {[Gentleman]}\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":{\"self\":{\"Mike {[Gentleman]}\":\"33\",\"names\":[\"aa\"]}}}]}],\"Judy\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":[\"Mike {[Gentleman]}\"]}],\"associatedDrug#2\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\"}],\"friends\":[{\"Mike {[Gentleman]}\":null},{\"Mike {[Gentleman]}\":[[\"c[ 3\\\"5ool\",35],[\"ca],[1\\\"3lm\"],53]},\"Jackson\",\"Mike {[Gentleman]}\"]}]}]}],\"classNameMissed\":[{\"Mike {[Gentleman]}\":\"missing_value\"}]}],\"className\":true}]}]}]}]}],\"yyclassNameMissed2\":[{\"Mike {[Gentleman]}\":\"missing_value\"}]}],\"xxclasses2\":[{}]}]}]}],\"Judy\":[{\"associatedDrug\":[{\"name\":\"asprin\",\"dose\":\"\",\"strength\":\"500 mg\",\"friends\":[\"Mike {[Gentleman]}\"]}],\"associatedDrug#2\":[{\"name\":\"somethingElse\",\"dose\":\"\",\"strength\":\"500 mg\"}],\"friends\":[{\"Mike {[Gentleman]}\":null},{\"Mike {[Gentleman]}\":[[\"c[ 3\\\"5ool\",35],[\"ca],[1\\\"3lm\"],53]},\"Jackson\",\"Mike {[Gentleman]}\"]}]}]}],\"classNameMissed\":[{\"Mike {[Gentleman]}\":\"missing_value\"}]}],\"className\":true}]}]}]}]}],\"classNameMissed\":[{\"Mike {[Gentleman]}\":\"missing_value\"}]}],\"className\":true}]}";
8 |
9 | export default {
10 | n1, n2, n3, n4
11 | }
--------------------------------------------------------------------------------
/test/sample.js:
--------------------------------------------------------------------------------
1 | const str_1 = '{\n' +
2 | ' "prob\\"lems": [{\n' +
3 | ' "classes": [{\n' +
4 | ' "medications": [{\n' +
5 | ' "medicationsClasses": [{\n' +
6 | ' "Mike {[Gentleman]}": [{\n' +
7 | ' "associatedDrug": [{\n' +
8 | ' "name": "asprin",\n' +
9 | ' "dose": "a",\n' +
10 | ' "strength": "500 mg"\n' +
11 | ' }],\n' +
12 | ' "Mike {[Gentleman]}": [{\n' +
13 | ' "name": "somethingElse",\n' +
14 | ' "dose": "",\n' +
15 | ' "strength": "500 mg",\n' +
16 | ' "friends": {\n' +
17 | ' "self": {\n' +
18 | ' "Mike {[Gentleman]}": "33",\n' +
19 | ' "names": ["aa"]\n' +
20 | ' }\n' +
21 | ' }\n' +
22 | ' }]\n' +
23 | ' }],\n' +
24 | ' "Judy": [{\n' +
25 | ' "associatedDrug": [{\n' +
26 | ' "name": "asprin",\n' +
27 | ' "dose": "",\n' +
28 | ' "strength": "500 mg",\n' +
29 | ' "friends": ["Mike {[Gentleman]}"]\n' +
30 | ' }],\n' +
31 | ' "associatedDrug#2": [{\n' +
32 | ' "name": "somethingElse",\n' +
33 | ' "dose": "",\n' +
34 | ' "strength": "500 mg"\n' +
35 | ' }],\n' +
36 | ' "friends": [{"Mike {[Gentleman]}": null}, {"Mike {[Gentleman]}": [["c[ 3\\"5ool", 35], ["ca],[1\\"3lm"], 53]}, "Jackson", "Mike {[Gentleman]}"]\n' +
37 | ' }]\n' +
38 | ' }]\n' +
39 | ' }],\n' +
40 | ' "classNameMissed": [{\n' +
41 | ' "Mike {[Gentleman]}": "missing_value"\n' +
42 | ' }]\n' +
43 | ' }],\n' +
44 | ' "className": [{}]\n' +
45 | ' }]\n' +
46 | ' }';
47 |
48 | const obj_1 ={
49 | "problems": [
50 | {
51 | "classes": [
52 | {
53 | "medications": [
54 | {
55 | "medicationsClasses": [
56 | {
57 | "Mike {[Gentleman]}": [
58 | {
59 | "associatedDrug": [
60 | {
61 | "name": "asprin",
62 | "dose": "a",
63 | "strength": "500 mg"
64 | }
65 | ],
66 | "Mike {[Gentleman]}": [
67 | {
68 | "name": "somethingElse",
69 | "dose": "",
70 | "strength": "500 mg",
71 | "friends": {
72 | "self": {
73 | "Mike {[Gentleman]}": "33",
74 | "names": [
75 | "aa"
76 | ]
77 | }
78 | }
79 | }
80 | ]
81 | }
82 | ],
83 | "Judy": [
84 | {
85 | "associatedDrug": [
86 | {
87 | "name": "asprin",
88 | "dose": "",
89 | "strength": "500 mg",
90 | "friends": [
91 | "Mike {[Gentleman]}"
92 | ]
93 | }
94 | ],
95 | "associatedDrug#2": [
96 | {
97 | "name": "somethingElse",
98 | "dose": "",
99 | "strength": "500 mg"
100 | }
101 | ],
102 | "friends": [
103 | {
104 | "Mike {[Gentleman]}": null
105 | },
106 | {
107 | "Mike {[Gentleman]}": [
108 | [
109 | "c[ 3\"5ool",
110 | 35
111 | ],
112 | [
113 | "ca],[1\"3lm"
114 | ],
115 | 53
116 | ]
117 | },
118 | "Jackson",
119 | "Mike {[Gentleman]}",
120 | {
121 | "problems": [
122 | {
123 | "aclasses": [
124 | {
125 | "medications": [
126 | {
127 | "medicationsClasses": [
128 | {
129 | "Mike {[Gentleman]}": [
130 | {
131 | "associatedDrug": [
132 | {
133 | "name": "asprin",
134 | "dose": "a",
135 | "strength": "500 mg"
136 | }
137 | ],
138 | "Mike {[Gentleman]}": [
139 | {
140 | "name": "somethingElse",
141 | "dose": "",
142 | "strength": "500 mg",
143 | "friends": {
144 | "self": {
145 | "Mike {[Gentleman]}": "33",
146 | "names": [
147 | "aa"
148 | ]
149 | }
150 | }
151 | },
152 | {
153 | "problems": [
154 | {
155 | "xxclasses": [
156 | {
157 | "yyclassNameMissed": [
158 | {
159 | "medicationsClasses": [
160 | {
161 | "Mike {[Gentleman]}": [
162 | {
163 | "associatedDrug": [
164 | {
165 | "name": "asprin",
166 | "dose": "a",
167 | "strength": "500 mg"
168 | }
169 | ],
170 | "Mike {[Gentleman]}": [
171 | {
172 | "name": "somethingElse",
173 | "dose": "",
174 | "strength": "500 mg",
175 | "friends": {
176 | "self": {
177 | "Mike {[Gentleman]}": "33",
178 | "names": [
179 | "aa"
180 | ]
181 | }
182 | }
183 | }
184 | ]
185 | }
186 | ],
187 | "Judy": [
188 | {
189 | "associatedDrug": [
190 | {
191 | "name": "asprin",
192 | "dose": "",
193 | "strength": "500 mg",
194 | "friends": [
195 | "Mike {[Gentleman]}"
196 | ]
197 | }
198 | ],
199 | "associatedDrug#2": [
200 | {
201 | "name": "somethingElse",
202 | "dose": "",
203 | "strength": "500 mg"
204 | }
205 | ],
206 | "friends": [
207 | {
208 | "Mike {[Gentleman]}": null
209 | },
210 | {
211 | "Mike {[Gentleman]}": [
212 | [
213 | "c[ 3\"5ool",
214 | 35
215 | ],
216 | [
217 | "ca],[1\"3lm"
218 | ],
219 | 53
220 | ]
221 | },
222 | "Jackson",
223 | "Mike {[Gentleman]}",
224 | {
225 | "problems": [
226 | {
227 | "classes": [
228 | {
229 | "medications": [
230 | {
231 | "medicationsClasses": [
232 | {
233 | "Mike {[Gentleman]}": [
234 | {
235 | "associatedDrug": [
236 | {
237 | "name": "asprin",
238 | "dose": "a",
239 | "strength": "500 mg"
240 | }
241 | ],
242 | "Mike {[Gentleman]}": [
243 | {
244 | "name": "somethingElse",
245 | "dose": "",
246 | "strength": "500 mg",
247 | "friends": {
248 | "self": {
249 | "Mike {[Gentleman]}": "33",
250 | "names": [
251 | "aa"
252 | ]
253 | }
254 | }
255 | }
256 | ]
257 | }
258 | ],
259 | "Judy": [
260 | {
261 | "associatedDrug": [
262 | {
263 | "name": "asprin",
264 | "dose": "",
265 | "strength": "500 mg",
266 | "friends": [
267 | "Mike {[Gentleman]}"
268 | ]
269 | }
270 | ],
271 | "associatedDrug#2": [
272 | {
273 | "name": "somethingElse",
274 | "dose": "",
275 | "strength": "500 mg"
276 | }
277 | ],
278 | "friends": [
279 | {
280 | "Mike {[Gentleman]}": null
281 | },
282 | {
283 | "Mike {[Gentleman]}": [
284 | [
285 | "c[ 3\"5ool",
286 | 35
287 | ],
288 | [
289 | "ca],[1\"3lm"
290 | ],
291 | 53
292 | ]
293 | },
294 | "Jackson",
295 | "Mike {[Gentleman]}"
296 | ]
297 | }
298 | ]
299 | }
300 | ]
301 | }
302 | ],
303 | "classNameMissed": [
304 | {
305 | "Mike {[Gentleman]}": "missing_value"
306 | }
307 | ]
308 | }
309 | ],
310 | "className": [
311 | {}
312 | ]
313 | }
314 | ]
315 | }
316 | ]
317 | }
318 | ]
319 | }
320 | ]
321 | }
322 | ],
323 | "yyclassNameMissed2": [
324 | {
325 | "Mike {[Gentleman]}": "missing_value"
326 | }
327 | ]
328 | }
329 | ],
330 | "xxclasses2": [
331 | {}
332 | ]
333 | }
334 | ]
335 | }
336 | ]
337 | }
338 | ],
339 | "Judy": [
340 | {
341 | "associatedDrug": [
342 | {
343 | "name": "asprin",
344 | "dose": "",
345 | "strength": "500 mg",
346 | "friends": [
347 | "Mike {[Gentleman]}"
348 | ]
349 | }
350 | ],
351 | "associatedDrug#2": [
352 | {
353 | "name": "somethingElse",
354 | "dose": "",
355 | "strength": "500 mg"
356 | }
357 | ],
358 | "friends": [
359 | {
360 | "Mike {[Gentleman]}": null
361 | },
362 | {
363 | "Mike {[Gentleman]}": [
364 | [
365 | "c[ 3\"5ool",
366 | 35
367 | ],
368 | [
369 | "ca],[1\"3lm"
370 | ],
371 | 53
372 | ]
373 | },
374 | "Jackson",
375 | "Mike {[Gentleman]}"
376 | ]
377 | }
378 | ]
379 | }
380 | ]
381 | }
382 | ],
383 | "classNameMissed": [
384 | {
385 | "Mike {[Gentleman]}": "missing_value"
386 | }
387 | ]
388 | }
389 | ],
390 | "className": [
391 | {}
392 | ]
393 | }
394 | ]
395 | }
396 | ]
397 | }
398 | ]
399 | }
400 | ]
401 | }
402 | ],
403 | "classNameMissed": [
404 | {
405 | "Mike {[Gentleman]}": "missing_value"
406 | }
407 | ]
408 | }
409 | ],
410 | "className": [
411 | {}
412 | ]
413 | }
414 | ]
415 | };
416 |
417 | export default {
418 | str_1, obj_1
419 | }
--------------------------------------------------------------------------------
/test/test.js:
--------------------------------------------------------------------------------
1 | import Pattern from '../src/controller'
2 | import Sample from './sample'
3 | import Answer from './answer'
4 |
5 | //const assert = require('assert');
6 | var assert = require('chai').assert;
7 |
8 | function expect(result) {
9 | return {
10 | toBe: function(expected) {
11 | if (result !== expected) {
12 | throw new Error(result + ' is not equal to ' + expected);
13 | }
14 | }
15 | }
16 | }
17 |
18 | function checkProperties(doc, key, value) {
19 | for (var propertyName in doc) {
20 | if (typeof doc[propertyName] == "object") {
21 | checkProperties(doc[propertyName]);
22 | } else {
23 | if (propertyName == key) {
24 | doc[propertyName] = value;
25 | //print(doc[propertyName]);
26 | }
27 | }
28 | }
29 | }
30 |
31 | function getObjects(obj, key, newVal) {
32 | var newValue = newVal;
33 | var objects = [];
34 | for (var i in obj) {
35 | if (!obj.hasOwnProperty(i)) continue;
36 | if (typeof obj[i] == 'object') {
37 | objects = objects.concat(getObjects(obj[i], key, newValue));
38 | } else if (i == key) {
39 | obj[key] = newValue;
40 | }
41 | }
42 | return obj;
43 | }
44 |
45 |
46 | describe('BDD style', function() {
47 |
48 | before(function(){
49 |
50 | });
51 | //...
52 |
53 | after(function(){
54 |
55 | });
56 |
57 | beforeEach(function() {
58 |
59 | });
60 |
61 | afterEach(function() {
62 |
63 | });
64 |
65 | describe('Sample file checker', function() {
66 |
67 | it('Check if a sample is a correct JSON', function() {
68 | expect(JSON.stringify(JSON.parse(JSON.stringify(Sample.obj_1))))
69 | .toBe(Answer.n1);
70 | });
71 | });
72 |
73 | describe('Bulk update', function() {
74 |
75 | it('self : null', function() {
76 | expect(Pattern.sculptJson(Answer.n1, 'self', null))
77 | .toBe(Answer.n2);
78 | });
79 |
80 | it('Mike {[Gentleman]} : null', function() {
81 | expect(Pattern.sculptJson(Answer.n1, 'Mike {[Gentleman]}', null))
82 | .toBe(Answer.n3);
83 | });
84 |
85 | it('className : true', function() {
86 | expect(Pattern.sculptJson(Answer.n1, 'className', true))
87 | .toBe(Answer.n4);
88 | });
89 |
90 | /* it('Normal way - Mike {[Gentleman]} : null', function() {
91 | expect(getObjects(JSON.parse(Answer.n1), 'Mike {[Gentleman]}', null))
92 | .toBe(JSON.parse(Answer.n3));
93 | });*/
94 | });
95 |
96 |
97 | });
--------------------------------------------------------------------------------
/webpack.config.babel.js:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 |
3 | module.exports = {
4 | entry: {
5 | preload: './target/entry.js'
6 | },
7 | output: {
8 | path: path.join(__dirname, 'dist'),
9 | publicPath: '../dist/',
10 | filename: 'json-knife.bundle.js',
11 | chunkFilename: '[id].bundle.js',
12 | libraryTarget: 'var',
13 | library: 'Pattern'
14 | }
15 | };
--------------------------------------------------------------------------------