Skip to content

Instantly share code, notes, and snippets.

@mahsumurebe
Last active November 1, 2021 19:45
Show Gist options
  • Save mahsumurebe/073a7cac94849cbb8ca69259ee68689c to your computer and use it in GitHub Desktop.
Save mahsumurebe/073a7cac94849cbb8ca69259ee68689c to your computer and use it in GitHub Desktop.
JSON to dart class, json
type convertFN = (key: string, value: any) => void;
type convertibleTypes = (key: string, value: any) => void | string | number;
const convertibleTypeList = {
Number: (_key: string, value: any) => value % 1 === 0 ? 'int' : 'double',
String: 'String',
Boolean: 'bool',
Undefined: 'null',
Null: 'null',
};
function firstUp(str: string) {
let arr = str.split('');
arr[0] = arr[0].toUpperCase();
return arr.join('');
}
function camelize(str, firstUpper = false) {
const regExp = /[-_]\w/ig;
const camelize = str.replace(regExp, (match) => {
return match[1].toUpperCase();
});
if (firstUpper)
return firstUp(camelize);
return camelize;
}
function getType(x: any) {
// @ts-ignore
return Object.prototype.toString.call(x).match(/\[object (.*)\]/)[1];
}
function getT(variableValue: any, key, value) {
let t = convertibleTypeList[getType(variableValue)] ?? firstUp(typeof variableValue);
if (getType(t) === 'Function')
return t(key, value);
return t;
}
function _toClass(obj: { [key: string]: any }[], className = 'CLASS_NAME', parentClass = undefined): string {
const variableUsesCount: { [key: string]: number } = {};
const variables: { [variableName: string]: { isNullable: boolean, type: string, name: string, class: boolean } } = {};
const nullKeys = [];
let anotherClasses = {};
for (const objElement of obj) {
for (const variableName of Object.keys(objElement)) {
variableUsesCount[variableName] = (variableUsesCount[variableName] ?? 0) + 1;
const variableValue = objElement[variableName];
const type = getT(variableValue, variableName, variableValue);
let isNullable = variableValue == null || Object.keys(objElement).length > variableUsesCount[variableName];
if (type === 'Object' && !Array.isArray(variableValue)) {
const cName = camelize((parentClass ? parentClass+'_':'')+variableName, true);
anotherClasses[cName]=(_toClass([variableValue], camelize(variableName, true), cName));
variables[variableName] = {
name: camelize(variableName, false),
isNullable,
type: cName,
class: true,
};
} else if (Array.isArray(variableValue)) {
if (variableValue.length === 0) {
variables[variableName] = {
class: false,
name: camelize(variableName, false),
type: `List<dynamic>`,
isNullable: false,
};
} else {
let type = getT(variableValue[0], variableValue[0], variableName);
let isNullable = variableValue.some(o => o === null || o === undefined);
if (type !== 'Object') {
variables[variableName] = {
class: false,
name: camelize(variableName, false),
type: type === 'null' ? variables[variableName]?.type ?? 'dynamic' : `List<${type}>`,
isNullable,
};
} else {
const cName = camelize((parentClass ? parentClass+'_':'')+variableName, true);
anotherClasses[cName]=(toClass(variableValue, cName,cName));
variables[variableName] = {
class: true,
name: variableName,
type: cName,
isNullable,
};
}
}
} else {
if (isNullable)
nullKeys.push(variableName);
variables[variableName] = {
class: false,
name: camelize(variableName),
isNullable,
type: type === 'null' ? variables[variableName]?.type ?? 'dynamic' : type,
};
}
}
}
return `
${Object.values(anotherClasses).join('\n')}
class ${camelize(className, true)} {
${Object.keys(variables).map(variableName => {
const variable = variables[variableName];
const out = [];
out.push(variable.type + (variable.isNullable ? '?' : ''));
out.push(variable.name);
return out.join(' ');
}).join(';\n ') + (Object.keys(variables).length > 0 ? ';' : '')}
${camelize(className, true)}.fromJSON(Map<String, dynamic> data):
${Object.keys(variables).map(variableName => {
const variable = variables[variableName];
const out = [];
out.push(variable.name);
out.push('=');
if (variable.class) {
if (variable.isNullable) {
out.push(`data['${variableName}'] == null ? ${variable.type}.fromJSON(data['${variableName}']) : null`);
} else {
out.push(`${variable.type}.fromJSON(data['${variableName}'])`);
}
} else {
out.push(`data['${variableName}']`);
}
return out.join(' ');
}).join(',\n ')};
}
`.replace(/\n+/g,'\n');
}
function toClass(arg: any, className = 'CLASS_NAME', parent=null) {
if (Array.isArray(arg)) {
return _toClass(arg, className, parent);
} else if (typeof arg === 'object') {
return _toClass([arg], className, parent);
} else {
throw Error('Param must be JSON object or array.');
}
}
const json = {}
console.log(toClass(json, 'Template'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment