From 7a831270107d170df7baf677bbf1904992c998d0 Mon Sep 17 00:00:00 2001 From: Lauri Nevala Date: Fri, 18 Dec 2020 12:43:00 +0200 Subject: [PATCH] Improve parsing Signed-off-by: Lauri Nevala --- .../+custom-resources/crd-resources.tsx | 4 +- .../utils/__tests__/jsonPath.test.tsx | 25 ++++++++++--- src/renderer/utils/jsonPath.ts | 37 +++++++++++++------ 3 files changed, 46 insertions(+), 20 deletions(-) diff --git a/src/renderer/components/+custom-resources/crd-resources.tsx b/src/renderer/components/+custom-resources/crd-resources.tsx index dd0752efea..2c6e9fd193 100644 --- a/src/renderer/components/+custom-resources/crd-resources.tsx +++ b/src/renderer/components/+custom-resources/crd-resources.tsx @@ -93,11 +93,9 @@ export class CrdResources extends React.Component { crdInstance.getName(), isNamespaced && crdInstance.getNs(), ...extraColumns.map((column) => { - const pathExpression = parseJsonPath(column.jsonPath.slice(1)); - return { renderBoolean: true, - children: jsonPath.value(crdInstance, pathExpression), + children: jsonPath.value(crdInstance, parseJsonPath(column.jsonPath.slice(1))), }; } ), diff --git a/src/renderer/utils/__tests__/jsonPath.test.tsx b/src/renderer/utils/__tests__/jsonPath.test.tsx index f456cc3a15..b069857893 100644 --- a/src/renderer/utils/__tests__/jsonPath.test.tsx +++ b/src/renderer/utils/__tests__/jsonPath.test.tsx @@ -4,8 +4,26 @@ describe("parseJsonPath", () => { test("should convert \. to use indexed notation", () => { const res = parseJsonPath(".metadata.labels.kubesphere\\.io/alias-name"); - expect(res).toBe(".metadata['labels']['kubesphere.io/alias-name']"); + expect(res).toBe(".metadata.labels['kubesphere.io/alias-name']"); + }); + test("should convert '-' to use indexed notation", () => { + const res = parseJsonPath(".metadata.labels.alias-name"); + + expect(res).toBe(".metadata.labels['alias-name']"); + }); + + test("should handle scenario when both \ and indexed notation is present", () => { + const rest = parseJsonPath(".metadata.labels\\.serving['some.other.item']"); + + expect(rest).toBe(".metadata['labels.serving']['some.other.item']"); + }); + + + test("should not touch given jsonPath if no invalid characters", () => { + const res = parseJsonPath(".status.conditions[?(@.type=='Ready')].status"); + + expect(res).toBe(".status.conditions[?(@.type=='Ready')].status"); }); test("strips '\' away from the result", () => { @@ -14,9 +32,4 @@ describe("parseJsonPath", () => { expect(res).toBe(".metadata.labels['serving.knative.dev/configuration']"); }); - test("should not touch given jsonPath if no invalid characters", () => { - const res = parseJsonPath(".status.conditions[?(@.type=='Ready')].status"); - - expect(res).toBe(".status.conditions[?(@.type=='Ready')].status"); - }); }); diff --git a/src/renderer/utils/jsonPath.ts b/src/renderer/utils/jsonPath.ts index d3ba34e6ce..f9db610be6 100644 --- a/src/renderer/utils/jsonPath.ts +++ b/src/renderer/utils/jsonPath.ts @@ -2,20 +2,35 @@ export function parseJsonPath(jsonPath: string) { let pathExpression = jsonPath; - if (!jsonPath.includes("[") && jsonPath.includes("\\")) { - // convert cases where \. is present to use indexed notation, - // for example: .metadata.labels.kubesphere\.io/alias-name -> .metadata['labels']['kubesphere\.io/alias-name'] - const columnArr = jsonPath.split(/(?<=\w)\./); + if (jsonPath.match(/[\\-]/g)) { // search for '\' and '-' + // convert cases where \. or - is present to use indexed notation, + // for example: .metadata.labels.kubesphere\.io/alias-name -> .metadata.labels.['kubesphere\.io/alias-name'] - columnArr.forEach((value, index) => { - if (index == 0) { - pathExpression = `${value}`; - } else { - pathExpression += `['${value}']`; - } - }); + const [first, ...rest] = jsonPath.split(/(?<=\w)\./); // split jsonPath by '.' (\. cases are ignored) + + pathExpression = `${convertToIndexNotation(first, true)}${rest.map(value => convertToIndexNotation(value)).join("")}`; } // strip '\' characters from the result return pathExpression.replace(/\\/g, ""); +} + +function convertToIndexNotation(key: string, firstItem = false) { + if (key.match(/[\\-]/g)) { // check if found '\' and '-' in key + if (key.includes("[")) { // handle cases where key contains [...] + const keyToConvert = key.match(/^.*(?=\[)/g); // get the text from the key before '[' + + if (keyToConvert && keyToConvert[0].match(/[\\-]/g)) { // check if that part contains illegal characters + return key.replace(keyToConvert[0], `['${keyToConvert[0]}']`); // surround key with '[' and ']' + } else { + return `.${key}`; // otherwise return as is with leading '.' + } + } + + return `['${key}']`; + } else { // no illegal chracters found, do not touch + const prefix = firstItem ? "" : "."; + + return `${prefix}${key}`; + } } \ No newline at end of file