Skip to content

Commit

Permalink
Npm (#100)
Browse files Browse the repository at this point in the history
* added deserializeAsString, remove, toString functions

* enhancing remove logic

* npm features added. Test to be updated

* adding tests in progress

---------

Co-authored-by: Gupta <shubhendushekhar.gupta@delta.com>
  • Loading branch information
SubhenduShekhar and Gupta authored Dec 11, 2023
1 parent ef5b46c commit 052a319
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 20 deletions.
85 changes: 66 additions & 19 deletions npm/src/cjson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,36 @@ import { Json, isContentJson } from "./utils/json";
import { AbsolutePathConstraintError, CJSONContentInsteadOfFilePath } from "./utils/errors";
import { refineRelativePaths, refineRuntimeVals } from "./utils/refinery";


/**
* Coded JSON is an extended format of JSON formatted data storage, which gives
* you more previledge to organize data into more structured format.
*
* Here is an example for `CJSON` format:
*
* ```
* {
"source": $import "./source.json",
"target": {
"fruit": "Apple",
"size": "Large",
"color": "Red",
"secColor": $.target.color,
"colorList": [ $.target.color, $.target.secColor ],
// You can add comments like this
"digitCheck": 1.5,
"digitImport": $.target.digitCheck,
"digitArrayImport": [ $.target.digitCheck, $.target.digitImport ]
}
}
* ```
*
* The above `CJSON` snipped will be deserialized in JSON format and can be used
* as same as other JSON files.
*
* For other details, please refer to official page: https://subhendushekhar.github.io/cjson/
*/
export class Cjson extends Is {
private obj: JSON | undefined;
private obj: any;
private filePath: string ;
private content: string = "";
public json: Json | undefined = undefined;
Expand Down Expand Up @@ -93,7 +120,7 @@ export class Cjson extends Is {
* Deserializes the keywords.
* @returns `JSON` if no errors. Else `undefined`
*/
public deserialize() : JSON | undefined {
public deserialize() : any {
this.decodeKeywords();
this.decodeRelativePaths(this.content);

Expand Down Expand Up @@ -191,21 +218,41 @@ export class Cjson extends Is {
this.refineObj(content);
return this.obj;
}
/**
* Converts JSON object to string. Just a wrapper over `JSON.stringify()`
* @param obj JSON object
* @returns JSON string
*/
public static toString(obj: any) {
if(obj === null) return "{}";
else if(!isContentJson(JSON.stringify(obj))) throw new Error("Object is not a JSON");
else return JSON.stringify(obj);
}
/**
* Deserializes `CJSON` content and returns content as string.
*
* Content will be of pure JSON content and can be parsed as `JSON`
* @returns `JSON` equivalent of `CJSON` content in `string`
*/
public deserializeAsString() : string {
this.deserialize();
return this.content;
}
/**
* Removes a key:value from the CJSON context. Key will be JPath in `$.full.path` format
*
* The function automatically deserializes before removing. So, no need to explicitely deserialize it.
* @param key JPath to the key to be removed.
* @returns Resultant content in `JSON` object
*/
public remove(key: string) {
this.deserialize();
return this.json?.removeWithKey(key, this.content);
}
}

// var a = `
// {
// "source": $import "C:\\Users\\Home\\OneDrive\\Desktop\\projects\\cjson\\tests\\test-files\\source.json",
// "target": {
// "fruit": "Apple",
// "size": "Large",
// "color": "Red"
// }
// }
// `
// var a = "C:\\Users\\Home\\OneDrive\\Desktop\\projects\\cjson\\tests\\test-files\\targetRelativeCalls.cjson"

// var cjson = new Cjson(a);

// var b = cjson.deserialize();
// console.log(b);

var cjson = new Cjson("C:\\Users\\Home\\OneDrive\\Desktop\\projects\\cjson\\tests\\test-files\\pure.json");
var cjsonRemoved = cjson.remove("$.quiz.sport.q1.question");

console.log(JSON.stringify(cjsonRemoved));
52 changes: 52 additions & 0 deletions npm/src/utils/json.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import * as file from './file';
import Keywords from './keywords';
import { regexRefinery } from './refinery';

/**
* Checks for `JSON` content
Expand Down Expand Up @@ -163,4 +165,54 @@ export class Json {
}
return this.jsonValues;
}
private removeWithSucComma(key: string, value: string, content: string) {
var uniqueKeys = content.match(Keywords.removeWithSucComa(key, regexRefinery(value)))?.filter((value, index, array) => { return array.indexOf(value) === index });
if(uniqueKeys !== undefined) {
for(let i = 0; i < uniqueKeys?.length; i ++) {
var value = regexRefinery(uniqueKeys[i]);
content = content.replace(new RegExp(value, "g"), "");
}
}
return content;
}
private removeWithPreComma(key: string, value: string, content: string) {
var uniqueKeys = content.match(Keywords.removeWithPreComa(key, regexRefinery(value)))?.filter((value, index, array) => { return array.indexOf(value) === index });
if(uniqueKeys !== undefined) {
for(let i = 0; i < uniqueKeys?.length; i ++) {
var value = regexRefinery(uniqueKeys[i]);
content = content.replace(new RegExp(value, "g"), "");
}
}
return content;
}
private getAllKeyValueMatch(key: string, obj: any) {
if(key.split(".").length === 1) {
let stringObj: string = JSON.stringify(obj);
let con = this.removeWithPreComma(key, obj[key], stringObj);
con = this.removeWithSucComma(key, obj[key], con);
return con;
}
else {
let curKey: string = key.split(".")[0];
var a = this.getAllKeyValueMatch(key.replace(curKey + ".", ""), obj[curKey]);
if(a !== undefined)
obj[curKey] = JSON.parse(a);
else
obj[curKey] = a;
return JSON.stringify(obj);
}
}
/**
* Removes a key:value from the JSON context. Key will be JPath in `$.full.path` format
*
* The function automatically deserializes before removing. So, no need to explicitely deserialize it.
* @param key JPath to the key
* @param content JSON `string` content from which to be removed.
* @returns Resultant content in `JSON` object
*/
public removeWithKey(key: string, content: string) {
if(key.startsWith(Keywords.relativeJPath))
key = key.replace(Keywords.relativeJPath, "");
return JSON.parse(this.getAllKeyValueMatch(key, JSON.parse(content)));
}
}
2 changes: 2 additions & 0 deletions npm/src/utils/keywords.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ export default class Keywords {

public static pathRegex: RegExp = new RegExp("[A-Za-z0-9:\\.]+", "g");

public static removeWithSucComa = (key: string, value: string): RegExp => new RegExp("\"" + key.split(".")[key.split(".").length - 1] + "\":\\s*\"" + value + "\",+", "g");
public static removeWithPreComa = (key: string, value: string): RegExp => new RegExp(",+\"" + key.split(".")[key.split(".").length - 1] + "\":\\s*\"" + value + "\"", "g");
}
12 changes: 11 additions & 1 deletion npm/src/utils/refinery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,18 @@ export function refineRelativePaths(content: string, uniqueKeys: string[]) {
*/
export function refineRuntimeVals(content: string, uniqueKeys: string[]) {
uniqueKeys?.map(eachKey => {

content = content.replace(new RegExp(eachKey, "g"), "\"<-" + eachKey.split("<")[1].split(">")[0] + "->\"");
});
return content;
}

export function regexRefinery(content: string) {
return content.replace(/\./g, "\\.")
.replace(/\[/g, "\\[")
.replace(/\?/g, "\\?")
.replace(/\*/g, "\\*")
.replace(/\+/g, "\\+")
.replace(/\{/g, "\\{")
.replace(/\$/g, "\\$")
.replace(/\^/g, "\\^");
}

0 comments on commit 052a319

Please sign in to comment.