Merge branch 'master' into BUDI-9016/extract-componenterrors-from-client
This commit is contained in:
commit
2a7d7d5ac2
|
@ -107,4 +107,15 @@ describe("Test isolated vm directly", () => {
|
||||||
)
|
)
|
||||||
expect(result).toEqual([])
|
expect(result).toEqual([])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("should ensure error results are cleared between runs", () => {
|
||||||
|
const context = {}
|
||||||
|
// throw error
|
||||||
|
// Ensure the first execution throws an error
|
||||||
|
expect(() => runJSWithIsolatedVM(`test.foo.bar = 123`, context)).toThrow()
|
||||||
|
|
||||||
|
// Ensure the error is not persisted across VMs
|
||||||
|
const secondResult = runJSWithIsolatedVM(`return {}`, context)
|
||||||
|
expect(secondResult).toEqual({})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -186,6 +186,7 @@ export class IsolatedVM implements VM {
|
||||||
|
|
||||||
code = `
|
code = `
|
||||||
try {
|
try {
|
||||||
|
results = {}
|
||||||
results['${this.runResultKey}']=${this.codeWrapper(code)}
|
results['${this.runResultKey}']=${this.codeWrapper(code)}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
results['${this.runErrorKey}']=e
|
results['${this.runErrorKey}']=e
|
||||||
|
|
|
@ -1,22 +1,52 @@
|
||||||
import csv from "csvtojson"
|
import csv from "csvtojson"
|
||||||
|
|
||||||
export async function jsonFromCsvString(csvString: string) {
|
export async function jsonFromCsvString(csvString: string) {
|
||||||
const castedWithEmptyValues = await csv({ ignoreEmpty: true }).fromString(
|
const possibleDelimiters = [",", ";", ":", "|", "~", "\t", " "]
|
||||||
csvString
|
|
||||||
)
|
|
||||||
|
|
||||||
|
for (let i = 0; i < possibleDelimiters.length; i++) {
|
||||||
|
let headers: string[] | undefined = undefined
|
||||||
|
let headerMismatch = false
|
||||||
|
|
||||||
|
try {
|
||||||
// By default the csvtojson library casts empty values as empty strings. This
|
// By default the csvtojson library casts empty values as empty strings. This
|
||||||
// is causing issues on conversion. ignoreEmpty will remove the key completly
|
// is causing issues on conversion. ignoreEmpty will remove the key completly
|
||||||
// if empty, so creating this empty object will ensure we return the values
|
// if empty, so creating this empty object will ensure we return the values
|
||||||
// with the keys but empty values
|
// with the keys but empty values
|
||||||
const result = await csv({ ignoreEmpty: false }).fromString(csvString)
|
const result = await csv({
|
||||||
result.forEach((r, i) => {
|
ignoreEmpty: false,
|
||||||
for (const [key] of Object.entries(r).filter(([, value]) => value === "")) {
|
delimiter: possibleDelimiters[i],
|
||||||
if (castedWithEmptyValues[i][key] === undefined) {
|
}).fromString(csvString)
|
||||||
r[key] = null
|
for (const [, row] of result.entries()) {
|
||||||
|
// The purpose of this is to find rows that have been split
|
||||||
|
// into the wrong number of columns - Any valid .CSV file will have
|
||||||
|
// the same number of colums in each row
|
||||||
|
// If the number of columms in each row is different to
|
||||||
|
// the number of headers, this isn't the right delimiter
|
||||||
|
const columns = Object.keys(row)
|
||||||
|
if (headers == null) {
|
||||||
|
headers = columns
|
||||||
}
|
}
|
||||||
|
if (headers.length === 1 || headers.length !== columns.length) {
|
||||||
|
headerMismatch = true
|
||||||
|
break
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
|
for (const header of headers) {
|
||||||
|
if (row[header] === undefined || row[header] === "") {
|
||||||
|
row[header] = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (headerMismatch) {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
return result
|
return result
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// Splitting on the wrong delimiter sometimes throws CSV parsing error
|
||||||
|
// (eg unterminated strings), which tells us we've picked the wrong delimiter
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Error("Unable to determine delimiter")
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,5 +29,34 @@ describe("csv", () => {
|
||||||
expect(Object.keys(r)).toEqual(["id", "optional", "title"])
|
expect(Object.keys(r)).toEqual(["id", "optional", "title"])
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const possibleDelimeters = [",", ";", ":", "|", "~", "\t", " "]
|
||||||
|
|
||||||
|
const csvArray = [
|
||||||
|
["id", "title"],
|
||||||
|
["1", "aaa"],
|
||||||
|
["2", "bbb"],
|
||||||
|
["3", "c ccc"],
|
||||||
|
["", ""],
|
||||||
|
[":5", "eee5:e"],
|
||||||
|
]
|
||||||
|
|
||||||
|
test.each(possibleDelimeters)(
|
||||||
|
"Should parse with delimiter %s",
|
||||||
|
async delimiter => {
|
||||||
|
const csvString = csvArray
|
||||||
|
.map(row => row.map(col => `"${col}"`).join(delimiter))
|
||||||
|
.join("\n")
|
||||||
|
const result = await jsonFromCsvString(csvString)
|
||||||
|
|
||||||
|
expect(result).toEqual([
|
||||||
|
{ id: "1", title: "aaa" },
|
||||||
|
{ id: "2", title: "bbb" },
|
||||||
|
{ id: "3", title: "c ccc" },
|
||||||
|
{ id: null, title: null },
|
||||||
|
{ id: ":5", title: "eee5:e" },
|
||||||
|
])
|
||||||
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue