firebase2graphql (v0.0.2): support array types in firebase json (close #1829) (#1900)

This commit is contained in:
Rishichandra Wawhal 2019-04-03 17:11:28 +05:30 committed by Shahidh K Muhammed
parent 5f02ebdefa
commit abfe7ae88f
5 changed files with 99 additions and 24 deletions

View File

@ -1,7 +1,7 @@
{
"name": "firebase2graphql",
"description": "A CLI tool to get GraphQL over Firebase data dump",
"version": "0.0.1-alpha8",
"version": "0.0.2",
"author": "Hasura",
"bin": {
"firebase2graphql": "./bin/run",

View File

@ -6,6 +6,8 @@ const {
isRandomList,
isList,
isObjectList,
makeFirebaseListFromObj,
makeFirebaseListFromArr,
} = require('./utils');
const throwError = require('../error');
@ -13,16 +15,18 @@ const handleTableCandidate = (obj, tableName, tableDetectedCallback, isRootLevel
const rowArray = [];
const flattenObject = (object, row, parent) => {
if (isObjectList(object)) {
const firebaseList = makeFirebaseListFromObj(object);
const dummyRow = {...row};
for (var objListKey in object) {
for (var objListKey in firebaseList) {
row[getPrimaryKeyName(dummyRow)] = objListKey;
const newRow = {...flattenObject(object[objListKey], row)};
const newRow = {...flattenObject(firebaseList[objListKey], row)};
if (newRow && Object.keys(newRow).length > 0) {
rowArray.push(newRow);
}
}
} else if (isList(object)) {
for (var listKey in object) {
const firebaseObject = makeFirebaseListFromArr(object);
for (var listKey in firebaseObject) {
const dummyRow = {...row};
dummyRow[getPrimaryKeyName(dummyRow, null, 'self')] = uuid();
dummyRow._value = listKey;
@ -33,28 +37,30 @@ const handleTableCandidate = (obj, tableName, tableDetectedCallback, isRootLevel
} else {
for (var objectKey in object) {
const value = object[objectKey];
if (value === null || value.constructor.name !== 'Object') {
if (value === null || !['Object', 'Array'].includes(value.constructor.name)) {
row[objectKey] = value;
} else if (value.constructor.name === 'Object') {
} else if (['Object', 'Array'].includes(value.constructor.name)) {
const pkeyMap = getParentPrimaryKeyMap(row);
if (isList(value)) {
const firebaseList = makeFirebaseListFromArr(value);
tableDetectedCallback(
null,
{
tableName: parent || tableName,
name: objectKey,
pkeys: pkeyMap,
data: Object.keys(value).map(item => ({_value: item})),
data: Object.keys(firebaseList).map(item => ({_value: item})),
}
);
} else if (isObjectList(value)) {
const firebaseList = makeFirebaseListFromObj(value);
tableDetectedCallback(
null,
{
tableName: parent || tableName,
name: objectKey,
pkeys: pkeyMap,
data: handleTableCandidate(value, `${parent || tableName}_${objectKey}`, tableDetectedCallback, false),
data: handleTableCandidate(firebaseList, `${parent || tableName}_${objectKey}`, tableDetectedCallback, false),
}
);
} else if (Object.keys(value).length !== 0) {
@ -75,7 +81,8 @@ const handleTableCandidate = (obj, tableName, tableDetectedCallback, isRootLevel
};
if (!isObjectList(obj)) {
if (isList(obj)) {
for (var listKey in obj) {
const firebaseObject = makeFirebaseListFromArr(obj);
for (var listKey in firebaseObject) {
rowArray.push({
_value: listKey,
_id: uuid(),

View File

@ -42,15 +42,50 @@ const isList = obj => {
if (Object.keys(obj).length === 0) {
return false;
}
for (var objKey in obj) {
if (obj[objKey] === null) {
return false;
}
if (obj[objKey].constructor.name !== 'Boolean' || !obj[objKey]) {
if (obj.constructor.name === 'Array') {
let arrayElementDataType = null;
for (let _i = obj.length - 1; _i >= 0; _i--) {
if (arrayElementDataType === null) {
arrayElementDataType = typeof obj[_i];
} else if (arrayElementDataType !== typeof obj[_i]) {
return false;
}
}
return true;
}
for (var objkey in obj) {
if (obj[objkey] === null) {
return false;
}
if (obj[objkey].constructor.name !== 'Boolean' || !obj[objkey]) {
return false;
}
}
return true;
};
const makeFirebaseListFromObj = obj => {
if (obj.constructor.name === 'Array') {
const firebaseList = {};
for (var i = obj.length - 1; i >= 0; i--) {
const element = obj[i];
firebaseList[i.toString()] = element;
}
return firebaseList;
}
return obj;
};
const makeFirebaseListFromArr = obj => {
if (obj.constructor.name === 'Array') {
const firebaseList = {};
for (var i = obj.length - 1; i >= 0; i--) {
const element = obj[i];
firebaseList[element] = true;
}
return firebaseList;
}
return obj;
};
const isObjectList = obj => {
@ -58,28 +93,45 @@ const isObjectList = obj => {
return false;
}
const listChildStructure = {};
for (var key in obj) {
if (obj[key] === null) {
const checkElementConsistency = element => {
if (element === null) {
return false;
}
if (typeof obj[key] !== 'object') {
if (typeof element !== 'object') {
return false;
}
if (Object.keys(obj[key]).length === 0) {
if (Object.keys(obj).length === 0) {
return false;
}
for (var childKey in obj[key]) {
for (var childKey in element) {
if (!listChildStructure[childKey]) {
if (obj[key][childKey] !== null && obj[key][childKey] !== undefined) {
listChildStructure[childKey] = typeof obj[key][childKey];
if (element[childKey] !== null && element[childKey] !== undefined) {
listChildStructure[childKey] = typeof element[childKey];
}
} else if (obj[key][childKey] !== null && obj[key][childKey] !== undefined) {
if (typeof obj[key][childKey] !== listChildStructure[childKey]) {
} else if (element[childKey] !== null && element[childKey] !== undefined) {
if (typeof element[childKey] !== listChildStructure[childKey]) {
return false;
}
}
}
return true;
};
if (obj.constructor.name === 'Array') {
for (let _i = obj.length - 1; _i >= 0; _i--) {
let element = obj[_i];
let consistent = checkElementConsistency(element);
if (!consistent) {
return false;
}
}
return true;
}
for (var key in obj) {
const element = obj[key];
let consistent = checkElementConsistency(element);
if (!consistent) {
return false;
}
}
return true;
};
@ -91,4 +143,6 @@ module.exports = {
isRandomList,
isList,
isObjectList,
makeFirebaseListFromObj,
makeFirebaseListFromArr,
};

View File

@ -17,10 +17,10 @@ const getDataType = (data, column) => {
if (data.constructor.name === 'Date') {
return 'timestamptz';
}
if (data.constructor.name === 'Object') {
if (data.constructor.name === 'Object' || data.constructor.name === 'Array') {
return 'json';
}
throwError(`Message: invalid data type given for column ${column}: ${typeof data}`);
throwError(`Message: invalid data type given for column ${column}: ${data.constructor.name}`);
};
const isForeign = (name, db) => {

View File

@ -0,0 +1,14 @@
module.exports = {
appointment: {
'-LMlfYiyfmR7RxODd2lF': {
'appointment-notes': {
images: [
'https://firebasestorage.googleapis.comd2e34932caf',
],
'notes-content': 'testing........',
},
'created-time': 1537358052,
'work-request-id': '-LMlf80ePhwjG4Rkh8tY',
},
},
};