Skip to content

Commit fe9f03b

Browse files
committed
Implement deserialization of JSON data extensions
1 parent 8896af3 commit fe9f03b

2 files changed

Lines changed: 82 additions & 2 deletions

File tree

‎extensions/ql-vscode/src/model-editor/extension-serialization.ts‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import Ajv from "ajv";
22

33
import { load as loadYaml } from "js-yaml";
4+
import JSON5 from "json5";
45
import { readFile } from "fs-extra";
56
import type { Method } from "./method";
67
import type {
@@ -461,15 +462,16 @@ function modelExtensionFileToJson(
461462
}`;
462463
}
463464

464-
function deserializeToObject(contents: string, filename: string) {
465+
function deserializeToObject(contents: string, filename: string): unknown {
465466
const format = getFormatFromFileName(filename);
466467
switch (format) {
467468
case ExtensionFormat.Yaml:
468469
return loadYaml(contents, {
469470
filename,
470471
});
471472
case ExtensionFormat.Json:
472-
throw new Error(`JSON format not supported yet`);
473+
// Use a parser that can handle comments
474+
return JSON5.parse(contents);
473475
default:
474476
assertNever(format);
475477
}

‎extensions/ql-vscode/test/unit-tests/model-editor/extension-serialization.test.ts‎

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,6 +1616,84 @@ describe("loadDataExtensionFromString", () => {
16161616
],
16171617
} satisfies Record<string, ModeledMethod[]>);
16181618
});
1619+
it("loads from a JSON string", () => {
1620+
const data = loadDataExtensionFromString(
1621+
`// Header comment
1622+
{
1623+
"extensions": [
1624+
{
1625+
"addsTo": {
1626+
"pack": "codeql/java-all",
1627+
"extensible": "sourceModel"
1628+
},
1629+
"data": []
1630+
},
1631+
{
1632+
"addsTo": {
1633+
"pack": "codeql/java-all",
1634+
"extensible": "sinkModel"
1635+
},
1636+
/* Multi-
1637+
* line
1638+
* comment
1639+
*/
1640+
"data": [
1641+
["org.sql2o", "Connection", true, "createQuery", "(String)", "", "Argument[0]", "sql", "manual"],
1642+
["com.github", "CodeQL", true, "doThing", "(int,int)", "", "Argument[1]", "foo", "df-generated"]
1643+
]
1644+
},
1645+
{
1646+
"addsTo": {
1647+
"pack": "codeql/java-all",
1648+
"extensible": "summaryModel"
1649+
},
1650+
"data": []
1651+
},
1652+
{
1653+
"addsTo": {
1654+
"pack": "codeql/java-all",
1655+
"extensible": "neutralModel"
1656+
},
1657+
"data": []
1658+
}
1659+
]
1660+
}
1661+
`,
1662+
"test.model.json",
1663+
QueryLanguage.Java,
1664+
);
1665+
1666+
expect(data).toEqual({
1667+
"org.sql2o.Connection#createQuery(String)": [
1668+
{
1669+
input: "Argument[0]",
1670+
kind: "sql",
1671+
type: "sink",
1672+
provenance: "manual",
1673+
signature: "org.sql2o.Connection#createQuery(String)",
1674+
endpointType: EndpointType.Method,
1675+
packageName: "org.sql2o",
1676+
typeName: "Connection",
1677+
methodName: "createQuery",
1678+
methodParameters: "(String)",
1679+
},
1680+
],
1681+
"com.github.CodeQL#doThing(int,int)": [
1682+
{
1683+
input: "Argument[1]",
1684+
kind: "foo",
1685+
type: "sink",
1686+
provenance: "df-generated",
1687+
signature: "com.github.CodeQL#doThing(int,int)",
1688+
endpointType: EndpointType.Method,
1689+
packageName: "com.github",
1690+
typeName: "CodeQL",
1691+
methodName: "doThing",
1692+
methodParameters: "(int,int)",
1693+
},
1694+
],
1695+
} satisfies Record<string, ModeledMethod[]>);
1696+
});
16191697

16201698
it("returns undefined if given a string", () => {
16211699
expect(() =>

0 commit comments

Comments
 (0)