Skip to content

Commit

Permalink
refactor: add object expression utilities (#3363)
Browse files Browse the repository at this point in the history
Here added utilities to update expressions partially for example in
graphql json body we need to update separately query and variables
expressions but store as single body expression.
  • Loading branch information
TrySound authored May 15, 2024
1 parent d81b727 commit 1d0a8ed
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 0 deletions.
53 changes: 53 additions & 0 deletions packages/sdk/src/expression.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
lintExpression,
transpileExpression,
getExpressionIdentifiers,
parseObjectExpression,
generateObjectExpression,
} from "./expression";

describe("lint expression", () => {
Expand Down Expand Up @@ -322,6 +324,57 @@ describe("transpile expression", () => {
});
});

describe("object expression transformations", () => {
test("parse object expression", () => {
expect(parseObjectExpression(`{ a: 0, b: "", c: $c + 1 }`)).toEqual(
new Map([
["a", `0`],
["b", `""`],
["c", `$c + 1`],
])
);
});

test("parse unsupported syntax", () => {
expect(parseObjectExpression(``)).toEqual(new Map());
expect(parseObjectExpression(`0`)).toEqual(new Map());
expect(parseObjectExpression(`{ a: 0, ...spread }`)).toEqual(
new Map([["a", "0"]])
);
expect(parseObjectExpression(`{ a: 0, [b]: 0 }`)).toEqual(
new Map([["a", "0"]])
);
expect(parseObjectExpression(`{ "a-b": 0 }`)).toEqual(
new Map([["a-b", "0"]])
);
});

test("generate object expression", () => {
expect(
generateObjectExpression(
new Map([
["a", `0`],
["b-c", `""`],
["d", `$d`],
])
)
).toMatchInlineSnapshot(`
"{
"a": 0,
"b-c": "",
"d": $d,
}"
`);
});

test("generate empty object expression", () => {
expect(generateObjectExpression(new Map())).toMatchInlineSnapshot(`
"{
}"
`);
});
});

test("encode/decode variable names", () => {
expect(encodeDataSourceVariable("my--id")).toEqual(
"$ws$dataSource$my__DASH____DASH__id"
Expand Down
56 changes: 56 additions & 0 deletions packages/sdk/src/expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,62 @@ export const transpileExpression = ({
return expression;
};

/**
* parse object expression into key value map
* where each value is expression
*/
export const parseObjectExpression = (expression: string) => {
const map = new Map<string, string>();
let root;
try {
root = parseExpressionAt(expression, 0, { ecmaVersion: "latest" });
} catch (error) {
return map;
}
if (root.type !== "ObjectExpression") {
return map;
}
for (const property of root.properties) {
if (property.type === "SpreadElement") {
continue;
}
if (property.computed) {
continue;
}
let key;
if (property.key.type === "Identifier") {
key = property.key.name;
} else if (
property.key.type === "Literal" &&
typeof property.key.value === "string"
) {
key = property.key.value;
} else {
continue;
}
const valueExpression = expression.slice(
property.value.start,
property.value.end
);
map.set(key, valueExpression);
}
return map;
};

/**
* generate key value map into object expression
* after updating individual value expressions
*/
export const generateObjectExpression = (map: Map<string, string>) => {
let generated = "{\n";
for (const [key, valueExpression] of map) {
const keyExpression = JSON.stringify(key);
generated += ` ${keyExpression}: ${valueExpression},\n`;
}
generated += `}`;
return generated;
};

const dataSourceVariablePrefix = "$ws$dataSource$";

// data source id is generated with nanoid which has "-" in alphabeta
Expand Down

0 comments on commit 1d0a8ed

Please sign in to comment.