Skip to content

Commit

Permalink
fix: lifecycle selection and attribute handling
Browse files Browse the repository at this point in the history
Issue: conversion function cannot contain javascript Template literals (Template strings) #39
  • Loading branch information
mbehr1 committed Jan 7, 2024
1 parent 536517d commit b819bcb
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 126 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@
},
"dependencies": {
"@vscode/extension-telemetry": "^0.8.4",
"dlt-logs-utils": "0.0.2",
"dlt-logs-utils": "^0.1.0",
"jju": "github:mbehr1/jju#3aa4169df926e99083fdd511d7c20b5bd9ba789f",
"js-yaml": "^4.1.0",
"json5": "2.2.3",
Expand Down
10 changes: 7 additions & 3 deletions src/extension/fbaEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -966,13 +966,17 @@ export class FBAEditorProvider implements vscode.CustomTextEditorProvider, vscod
*/
static mergeAttributes(mainAttrs: any[], newAttrs: any[] | undefined) {
console.warn(`FBAEditorProvider.mergeAttributes mainAttrs=${JSON.stringify(mainAttrs)} newAttrs=${JSON.stringify(newAttrs)}`)
// attributes are arrays of objects with a single key (the name)
// attributes are arrays of objects with a single key (the name) (and the fbUid as 2nd key)
if (newAttrs === undefined) {
return
}
const mainKeys = mainAttrs.map((a) => Object.keys(a)[0])
const mainKeys = mainAttrs.map((a) => {
const { fbUid: _a, ...aWoFbUid } = a
return Object.keys(aWoFbUid)[0]
})
for (const newKeyObj of newAttrs) {
const newKey = Object.keys(newKeyObj)[0]
const { fbUid: _a, ...newKeyObjWoFbUid } = newKeyObj
const newKey = Object.keys(newKeyObjWoFbUid)[0]
if (!mainKeys.includes(newKey)) {
mainAttrs.push(newKeyObj)
}
Expand Down
58 changes: 1 addition & 57 deletions src/extension/fbaNBRQRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,65 +17,9 @@ import { DocData, FBAEditorProvider } from './fbaEditor'
import { FBBadge } from './fbaFormat'
import { arrayEquals, getMemberParent, MemberPath } from './util'
import * as uv0 from 'dlt-logs-utils'
import { RQ, rqUriDecode, rqUriEncode } from 'dlt-logs-utils/dist/restQuery'
import { NotebookCellOutput } from 'vscode'

interface RQCmd {
cmd: string
param: any
}

interface RQ {
path: string
commands: RQCmd[]
}

const rqUriDecode = (rq: string): RQ => {
const res: RQ = {
path: '',
commands: [],
}
if (!rq || rq.length === 0) {
return res
}

const indexOfQ = rq?.indexOf('?')
if (indexOfQ > 0) {
res.path = rq.slice(0, indexOfQ + 1) // + '\n'

const options = rq.slice(indexOfQ + 1)
const optionArr = options.split('&')
for (const commandStr of optionArr) {
const eqIdx = commandStr.indexOf('=')
const command = commandStr.slice(0, eqIdx)
const commandParams = decodeURIComponent(commandStr.slice(eqIdx + 1))
res.commands.push({ cmd: command, param: commandParams })
}
} else {
res.path = rq
}

return res
}

const rqUriEncode = (rq: RQ): string => {
let toRet = rq.path
if (rq.commands.length > 0) {
if (!toRet.endsWith('?')) {
toRet += '?'
}
toRet += rq.commands.map((rqCmd) => rqCmd.cmd + '=' + encodeURIComponent(rqCmd.param)).join('&')
/*
for (const [idx, rqCmd] of rq.commands.entries()) {
const cmdStr = rqCmd.cmd + '=' + encodeURIComponent(rqCmd.param)
if (idx > 0) {
toRet += '&'
}
toRet += cmdStr
}*/
}
return toRet
}

class FBANBRQCell extends vscode.NotebookCellData {
constructor(kind: vscode.NotebookCellKind, value: string, languageId: string, metadata?: object) {
super(kind, value, languageId)
Expand Down
2 changes: 1 addition & 1 deletion src/webview/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^14.4.3",
"dlt-logs-utils": "0.0.2",
"dlt-logs-utils": "^0.1.0",
"dompurify": "^2.4.0",
"jju": "github:mbehr1/jju#3aa4169df926e99083fdd511d7c20b5bd9ba789f",
"js-yaml": "^4.1.0",
Expand Down
21 changes: 13 additions & 8 deletions src/webview/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -373,10 +373,10 @@ export default class App extends Component {
}

handleInputChange(object, event, propsField) {
console.warn(`handleInputChange this=`, this)
console.warn(`handleInputChange object=`, object)
console.warn(`handleInputChange event=`, event)
console.warn(`handleInputChange propsField=`, propsField)
console.log(`handleInputChange this=`, this)
console.log(`handleInputChange object=`, object)
console.log(`handleInputChange event=`, event)
console.log(`handleInputChange propsField=`, propsField)

// if propsField is provided this determines the field to update (e.g. object.props[propsField]=...)
const target = event.target
Expand Down Expand Up @@ -429,9 +429,10 @@ export default class App extends Component {
/*object.props[propsFieldName] = value; */ didUpdate = true
} else {
// for attributes object contains just one key: (the name)
if (Object.keys(object).length === 1) {
const { fbUid: _a, ...objectWoFbUid } = object
if (Object.keys(objectWoFbUid).length === 1) {
console.log(`App.handleInputChange found attribute like object to update: ${JSON.stringify(object)}`)
const curValue = object[Object.keys(object)[0]]
const curValue = object[Object.keys(objectWoFbUid)[0]]
if (typeof curValue === 'object') {
const attrObj = curValue
console.log(`App.handleInputChange found object inside attribute to update: ${JSON.stringify(attrObj)}`)
Expand All @@ -453,7 +454,11 @@ export default class App extends Component {
object[key] = value
didUpdate = true
} else {
console.warn(`handleInputChange didn't found key '${key}' in object to update to value '${value}'!`)
console.warn(
`handleInputChange didn't found key '${key}' in object to update to value '${JSON.stringify(
value,
)}' in object: '${JSON.stringify(object)}'!`,
)
}
}
}
Expand Down Expand Up @@ -580,7 +585,7 @@ export default class App extends Component {

// reset attributes:
this.state.attributes.forEach((attribute) => {
const attrName = Object.keys(attribute)[0]
const attrName = Object.keys(attribute).find((key) => key !== 'fbUid')
const attrObj = attribute[attrName]
if ('value' in attrObj) {
attrObj['value'] = null
Expand Down
64 changes: 32 additions & 32 deletions src/webview/src/components/dataProviderEditDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -289,24 +289,24 @@ export default function DataProviderEditDialog(props) {
dataSource?.startsWith('ext:mbehr1.dlt-logs')
? dataSource
: props.applyMode
? // eslint-disable-next-line no-template-curly-in-string
`ext:mbehr1.dlt-logs/get/docs/0/filters?delete=${encodeURIComponent('{"tmpFb":1}')}&disableAll=view${
attributes.findIndex((attr) => attr.hasOwnProperty('lifecycles')) >= 0
? `&add=${encodeURIComponent(
// eslint-disable-next-line no-template-curly-in-string
'{"lifecycles":"${attributes.lifecycles.id}","name":"not selected lifecycles","not":true,"tmpFb":1,"type":1}',
)}`
: ''
}`
: // eslint-disable-next-line no-template-curly-in-string
`ext:mbehr1.dlt-logs/get/docs/0/filters?query=${encodeURIComponent(
`[{${
? // eslint-disable-next-line no-template-curly-in-string
`ext:mbehr1.dlt-logs/get/docs/0/filters?delete=${encodeURIComponent('{"tmpFb":1}')}&disableAll=view${
attributes.findIndex((attr) => attr.hasOwnProperty('lifecycles')) >= 0
? // eslint-disable-next-line no-template-curly-in-string
'"lifecycles":"${attributes.lifecycles.id}",'
? `&add=${encodeURIComponent(
// eslint-disable-next-line no-template-curly-in-string
'{"lifecycles":"${attributes.lifecycles.id}","name":"not selected lifecycles","not":true,"tmpFb":1,"type":1}',
)}`
: ''
}"name":"not selected lifecycles","not":true,"type":1}]`,
)}`
}`
: // eslint-disable-next-line no-template-curly-in-string
`ext:mbehr1.dlt-logs/get/docs/0/filters?query=${encodeURIComponent(
`[{${
attributes.findIndex((attr) => attr.hasOwnProperty('lifecycles')) >= 0
? // eslint-disable-next-line no-template-curly-in-string
'"lifecycles":"${attributes.lifecycles.id}",'
: ''
}"name":"not selected lifecycles","not":true,"type":1}]`,
)}`
}
onChange={(newValue) => {
setDataSource(newValue)
Expand All @@ -325,24 +325,24 @@ export default function DataProviderEditDialog(props) {
dataSource?.startsWith('ext:mbehr1.dlt-logs')
? dataSource
: props.applyMode
? // eslint-disable-next-line no-template-curly-in-string
`ext:mbehr1.dlt-logs/get/docs/0/filters?delete=${encodeURIComponent('{"tmpFb":1}')}&disableAll=view${
attributes.findIndex((attr) => attr.hasOwnProperty('lifecycles')) >= 0
? `&add=${encodeURIComponent(
// eslint-disable-next-line no-template-curly-in-string
'{"lifecycles":"${attributes.lifecycles.id}","name":"not selected lifecycles","not":true,"tmpFb":1,"type":1}',
)}`
: ''
}`
: // eslint-disable-next-line no-template-curly-in-string
`ext:mbehr1.dlt-logs/get/docs/0/filters?query=${encodeURIComponent(
`[{${
? // eslint-disable-next-line no-template-curly-in-string
`ext:mbehr1.dlt-logs/get/docs/0/filters?delete=${encodeURIComponent('{"tmpFb":1}')}&disableAll=view${
attributes.findIndex((attr) => attr.hasOwnProperty('lifecycles')) >= 0
? // eslint-disable-next-line no-template-curly-in-string
'"lifecycles":"${attributes.lifecycles.id}",'
? `&add=${encodeURIComponent(
// eslint-disable-next-line no-template-curly-in-string
'{"lifecycles":"${attributes.lifecycles.id}","name":"not selected lifecycles","not":true,"tmpFb":1,"type":1}',
)}`
: ''
}"name":"not selected lifecycles","not":true,"type":1}]`,
)}`
}`
: // eslint-disable-next-line no-template-curly-in-string
`ext:mbehr1.dlt-logs/get/docs/0/filters?query=${encodeURIComponent(
`[{${
attributes.findIndex((attr) => attr.hasOwnProperty('lifecycles')) >= 0
? // eslint-disable-next-line no-template-curly-in-string
'"lifecycles":"${attributes.lifecycles.id}",'
: ''
}"name":"not selected lifecycles","not":true,"type":1}]`,
)}`
}
open={manualEditOpen}
onChange={(newValue) => {
Expand Down
87 changes: 71 additions & 16 deletions src/webview/src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import jp from 'jsonpath'
// provide JSON5.parse for conversion functions:
import JSON5 from 'json5'
import * as uv0 from 'dlt-logs-utils'
import { rqUriDecode, rqUriEncode } from 'dlt-logs-utils/dist/restQuery'

// eslint-disable-next-line no-undef
if (!globalThis.JSON5) {
Expand Down Expand Up @@ -137,17 +138,20 @@ export async function triggerRestQueryDetails(dataSourceObj, attributes) {
attrKey = attrName.slice(dotPos + 1)
attrName = attrName.slice(0, dotPos)
}
console.log(`triggerRestQueryDetails attrName='${attrName}' attrKey='${attrKey}'`)
const attribute = attributes?.find((attr) => Object.keys(attr)[0] === attrName)
// console.log(`triggerRestQueryDetails attrName='${attrName}' attrKey='${attrKey}'`)
const attribute = attributes?.find((attr) => {
const name = Object.keys(attr).find((key) => key !== 'fbUid')
return name === attrName
})
if (attribute !== undefined) {
const attrValue = attribute[attrName].value
const attrKeyValue = Array.isArray(attrValue)
? attrValue.map((e) => (attrKey ? e[attrKey] : e))
: attrKey
? attrValue && attrKey in attrValue
? attrValue[attrKey]
: null
: attrValue
? attrValue && attrKey in attrValue
? attrValue[attrKey]
: null
: attrValue
if (typeof attrKeyValue === 'string') {
// console.log(`attrKeyValue='${attrKeyValue}'`, attribute);
return wrapStringInQuotes ? `"${attrKeyValue}"` : attrKeyValue
Expand All @@ -156,7 +160,7 @@ export async function triggerRestQueryDetails(dataSourceObj, attributes) {
return JSON.stringify(attrKeyValue)
}
}
return `<unknown attribute:${attrName}>`
return wrapStringInQuotes ? `"<unknown attribute:${attrName}>"` : `<unknown attribute:${attrName}>`
}
return wrapStringInQuotes ? `"${p1}"` : p1
}
Expand All @@ -169,13 +173,64 @@ export async function triggerRestQueryDetails(dataSourceObj, attributes) {
// -> JSON representation otherwise (e.g. for arrays [...])
// problem is that arrays should not be "" quoted.

requestStr = reqSource.replace(/"\$\{(.*?)\}"/g, (match, p1, offset) => replaceAttr(match, p1, offset, true))
// replace the URI encoded ones as well, but uri encode them then:
requestStr = requestStr.replace(/%22%24%7B(.*?)%7D%22/g, (match, p1, offset) =>
encodeURIComponent(replaceAttr(match, p1, offset, true)),
)
// support uri encoded attrs like ${attributes.*} (w.o. being double enquoted) as well:
requestStr = requestStr.replace(/%24%7B(.*?)%7D/g, (match, p1, offset) => encodeURIComponent(replaceAttr(match, p1, offset, false)))
// to reduce risk we limit the new handling of replacing ${attribute..*} only to requests with "conversionFunction" inside:
if (!reqSource.includes('conversionFunction')) {
requestStr = reqSource.replace(/"\$\{(.*?)\}"/g, (match, p1, offset) => replaceAttr(match, p1, offset, true))
// replace the URI encoded ones as well, but uri encode them then:
requestStr = requestStr.replace(/%22%24%7B(.*?)%7D%22/g, (match, p1, offset) =>
encodeURIComponent(replaceAttr(match, p1, offset, true)),
)
// support uri encoded attrs like ${attributes.*} (w.o. being double enquoted) as well:
requestStr = requestStr.replace(/%24%7B(.*?)%7D/g, (match, p1, offset) => encodeURIComponent(replaceAttr(match, p1, offset, false)))
} else {
// console.log(`triggerRestQueryDetails got conversionFunction. Replacing attributes in requestStr='${reqSource}'`)
// we only want attributes in the form of "${attributes.name}" to be replaced within filter expression (apid, ctid,... but not within reportOptions...)
try {
const rq = rqUriDecode(reqSource)
// console.log(`triggerRestQueryDetails got rq.path=${rq.path} rq.cmds.length=${rq.commands.length}`)
// scan all cmds for filter and replace attributes:
for (const cmd of rq.commands) {
if (cmd.param?.includes('${attributes.')) {
switch (cmd.cmd) {
case 'report':
case 'query':
// filters are the array
const filters = JSON5.parse(cmd.param)
if (Array.isArray(filters)) {
for (const filter of filters) {
if (typeof filter === 'object') {
for (const key of Object.keys(filter)) {
const val = filter[key]
if (typeof val === 'string' && val.includes('${attributes.')) {
console.log(`triggerRestQueryDetails replacing attributes in filter[${key}] from '${val}'`)
// todo optimize! need to replace to object/array/string and not a string representation of it...
filter[key] = JSON.parse(
JSON.stringify(val).replace(/"\$\{(.*?)\}"/g, (match, p1, offset) => replaceAttr(match, p1, offset, true)),
)
console.log(`triggerRestQueryDetails replacing attributes in filter[${key}] to '${filter[key]}'`)
}
}
} else {
console.warn(`triggerRestQueryDetails got non object filter=${filter}`)
}
}
cmd.param = JSON.stringify(filters)
} else {
console.warn(`triggerRestQueryDetails got non array filters=${filters}`)
}
break
default:
// replace all attributes in the cmd.param:
cmd.param = cmd.param.replace(/"\$\{(.*?)\}"/g, (match, p1, offset) => replaceAttr(match, p1, offset, true))
}
}
}
requestStr = rqUriEncode(rq)
} catch (e) {
console.warn(`triggerRestQueryDetails replacing attributes failed with ${e} using initial str`)
requestStr = reqSource
}
}
}

const res = await triggerRestQuery(requestStr)
Expand Down Expand Up @@ -237,8 +292,8 @@ export async function triggerRestQueryDetails(dataSourceObj, attributes) {
answer.convResult !== undefined
? answer.convResult
: answer.jsonPathResult !== undefined
? answer.jsonPathResult
: answer.restQueryResult
? answer.jsonPathResult
: answer.restQueryResult
// console.log(`triggerRestQueryDetails got result='${JSON.stringify(answer.result)}'`);
} catch (e) {
console.log(`triggerRestQueryDetails got error=`, e)
Expand Down
8 changes: 4 additions & 4 deletions src/webview/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4259,10 +4259,10 @@ dir-glob@^3.0.1:
dependencies:
path-type "^4.0.0"

dlt-logs-utils@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/dlt-logs-utils/-/dlt-logs-utils-0.0.2.tgz#b5d8a205c8eee876101fa00e76e6526bd809de8e"
integrity sha512-ApjoO5ng57axu6KEa7tHU8nv1dgpa4yYMmFRCshCW85+44Wzv+1iEIuoV0LiID+9Hay9wt0czwdDBOa1qn74ug==
dlt-logs-utils@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/dlt-logs-utils/-/dlt-logs-utils-0.1.0.tgz#440cad79bf2d045d27e5c1b6210db7ff3bbba85a"
integrity sha512-XlAolmR4UfDGimvlhzwW0N2xF7g70MibyforFLC76c5sTbgYd49IUSQY67C1wJSEcX3KqxQ5rcSCX7wk8B2Mjg==

dlv@^1.1.3:
version "1.1.3"
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2285,10 +2285,10 @@ dir-glob@^3.0.0, dir-glob@^3.0.1:
dependencies:
path-type "^4.0.0"

dlt-logs-utils@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/dlt-logs-utils/-/dlt-logs-utils-0.0.2.tgz#b5d8a205c8eee876101fa00e76e6526bd809de8e"
integrity sha512-ApjoO5ng57axu6KEa7tHU8nv1dgpa4yYMmFRCshCW85+44Wzv+1iEIuoV0LiID+9Hay9wt0czwdDBOa1qn74ug==
dlt-logs-utils@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/dlt-logs-utils/-/dlt-logs-utils-0.1.0.tgz#440cad79bf2d045d27e5c1b6210db7ff3bbba85a"
integrity sha512-XlAolmR4UfDGimvlhzwW0N2xF7g70MibyforFLC76c5sTbgYd49IUSQY67C1wJSEcX3KqxQ5rcSCX7wk8B2Mjg==

doctrine@^3.0.0:
version "3.0.0"
Expand Down

0 comments on commit b819bcb

Please sign in to comment.