Skip to content

Instantly share code, notes, and snippets.

@gmcdev
Created April 18, 2020 20:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gmcdev/25db72b90fa1d041734177056d9b4151 to your computer and use it in GitHub Desktop.
Save gmcdev/25db72b90fa1d041734177056d9b4151 to your computer and use it in GitHub Desktop.
/**
*
*
* Proxy Data Export
*/
const assignObjToScopeByParams = (obj, scopes, matchParamsByScopes, depth) => {
// create clean nested-scope objects for parameters that are objects
const prepareNestScopes = () => {
return scopes.map(() => {
return {}
})
}
// apply nested-scope objects back to master scopes
const applyNestedScopes = (key, nestedScopes) => {
for (let s = 0; s <= depth; s++) {
scopes[s][key] = nestedScopes[s]
}
}
// apply non-object values up to the nest-depth of this recursion
const updateScopes = (key, value) => {
for (let s = 0; s <= depth; s++) {
scopes[s][key] = value
}
}
const matchParams = matchParamsByScopes[depth]
Object.keys(obj).map(param => {
if (!matchParams || matchParams.includes(param)) {
if (typeof obj[param] === 'object') {
const nestDepth = depth + 1
applyNestedScopes(param, assignObjToScopeByParams(obj[param], prepareNestScopes(), matchParamsByScopes, nestDepth))
} else {
updateScopes(param, obj[param])
}
}
})
log(`..finished a recursion depth ${depth}:`)
log(scopes)
log('\n\n\n')
return scopes
}
const exportAsJson = async ({ spreadsheetId, sheetIds, rowIds, columns, assetIds, assets }) => {
log(`Exporting sheet-data as filtered JSON`)
// get all sheet-ids of the required spreadsheet-id
const sheets = await sheetsApi.getSheets({ spreadsheetId })
let ssObj = { [spreadsheetId]: {} },
sidsObj = {},
ridsObj = {},
colsObj = {},
aidsObj = {},
assetsObj = {}
const scopes = [ssObj[spreadsheetId], sidsObj, ridsObj, colsObj, aidsObj, assetsObj]
const matchParamsPerScopes = [[spreadsheetId], sheetIds.map(sid => sid.toString()), rowIds, columns, assetIds, assets]
const ss = {
[spreadsheetId]: {}
}
await Promise.all(
// Each SHEET:
sheets.map(async sheet => {
const sheetId = sheet.properties.sheetId
// ssObj[spreadsheetId][sheetId] = {}
// sidsObj[sheetId] = {}
// if no sheet-ids are requested, or this sheet-id is requested
if (!sheetIds || sheetIds.includes(sheetId)) {
// try to load the proxied JSON for this sheet-id
let rows
try {
rows = await json.load({ spreadsheetId, sheetId })
} catch (err) {
return log(` ~no proxied data exists for sheet-id ${sheetId}`)
}
ss[spreadsheetId] = {
[sheetId]: rows
}
}
})
)
const hydratedScopes = assignObjToScopeByParams(ss, scopes, matchParamsPerScopes, 0)
log(hydratedScopes)
let result
matchParamsPerScopes.find((mp, i) => {
if (!mp || !mp.length) {
result = hydratedScopes[i - 1]
return true
}
})
return result
}
@nicohsieh
Copy link

nicohsieh commented Apr 18, 2020

An attempt with a simplified scenario:

const originalObj = {
	spreadsheetId1: {
		sheetIds: {
			noise: 1,
			rowIds: {
				noise: 11,
				columns: {
					assetIds: {
						something: 'interesting1-1',
					},
				},
			},
		},
		sheetIds2: {
			noise: 1,
			rowIds: {
				noise: 11,
				columns: {
					assetIds: {
						something: 'interesting1-2',
					},
				},
			},
		},
	},
	spreadsheetId2: {
		sheetIds: {
			noise: 2,
			rowIds: {
				noise: 2,
				columns: {
					randomStuff: 222,
					assetIds: {
						something: 'interesting2-1',
						hey: 'yo',
					},
				},
			},
		},
		sheetIds2: {
			noise: 22,
			rowIds: {
				noise: 22,
				columns: {
					assetIds: {
						something: 'interesting2-2',
					},
				},
			},
		},
	},
}

const params = [
	'spreadsheetId1,spreadsheetId2',
	'sheetIds,sheetIds2',
	'rowIds',
	'columns',
	'assetIds',
] //spreadsheetId, sheetIds, rowIds, columns, assetIds, assets,

// it not desination, replace the previous

const findStuff = (obj, params, depth = 0) => {
	const keys = params[depth].split(',')
	console.log('keys', keys)
	let result = []
	keys.forEach(key => {
		const value = obj[key]

		if (typeof value === 'object') {
			result.push(value)

			if (depth < params.length - 1) {
				const newDepth = depth + 1
				findStuff(value, params, newDepth)
			}
		} else if (typeof value === 'undefined') {
			// not an object, game over for the thread X_X
			result.push(null)
		} else {
			// not an object, game over for the thread X_X
			result.push(value)
		}
	})
	console.log('------------------------')
	console.log('depth', depth)
	console.log('result', result)
	// This is the end
	// TODO: not happy about this, should be able to just return the final value
	if (depth === params.length - 1) {
		arr.push(...result)
	}
}

const arr = []
findStuff(originalObj, params, 0)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment