diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js index 6ceb3dee1..cb834c454 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js @@ -110,26 +110,39 @@ } } - - const contextAutoComplete = function(options) { const cache = {} const knownKeys = {} const getContextKeysFromRuntime = function(scope, store, searchKey, done) { knownKeys[store] = knownKeys[store] || new Set() + if (searchKey.length > 0) { + try { + RED.utils.normalisePropertyExpression(searchKey) + } catch (err) { + // Not a valid context key, so don't try looking up + done() + return + } + } const url = `context/${scope}/${encodeURIComponent(searchKey)}?store=${store}&keysOnly` if (cache[url]) { - console.log('CACHED', url) + // console.log('CACHED', url) done() } else { - console.log('GET', url) + // console.log('GET', url) $.getJSON(url, function(data) { + console.log(data) cache[url] = true - const keys = data[store] || [] + const result = data[store] || {} + const keys = result.keys || [] const keyPrefix = searchKey + (searchKey.length > 0 ? '.' : '') keys.forEach(key => { - knownKeys[store].add(keyPrefix + key) + if (/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(key)) { + knownKeys[store].add(keyPrefix + key) + } else { + knownKeys[store].add(searchKey + "[\""+key.replace(/"/,"\\\"")+"\"]") + } }) done() }) @@ -158,7 +171,7 @@ const searchKey = keyParts.join('.') getContextKeysFromRuntime(scope, store, searchKey, function() { - if (knownKeys[store].has(key)) { + if (knownKeys[store].has(key) || key.endsWith(']')) { getContextKeysFromRuntime(scope, store, key, function() { done(knownKeys[store]) }) @@ -173,7 +186,12 @@ const matches = [] keys.forEach(v => { let optVal = v - const valMatch = getMatch(optVal, val); + let valMatch = getMatch(optVal, val); + if (!valMatch.found && val.length > 0 && val.endsWith('.')) { + // Search key ends in '.' - but doesn't match. Check again + // with [" at the end instead so we match bracket notation + valMatch = getMatch(optVal, val.substring(0, val.length - 1) + '["') + } if (valMatch.found) { const element = $('
',{style: "display: flex"}); const valEl = $('
',{style:"font-family: var(--red-ui-monospace-font); white-space:nowrap; overflow: hidden; flex-grow:1"}); diff --git a/packages/node_modules/@node-red/runtime/lib/api/context.js b/packages/node_modules/@node-red/runtime/lib/api/context.js index b8fed5d88..f27075577 100644 --- a/packages/node_modules/@node-red/runtime/lib/api/context.js +++ b/packages/node_modules/@node-red/runtime/lib/api/context.js @@ -101,14 +101,15 @@ var api = module.exports = { } if (ctx) { if (key) { - console.log('GET KEY', key) store = store || availableStores.default; ctx.get(key,store,function(err, v) { if (opts.keysOnly) { - if (typeof v === 'object') { - resolve({ [store]: Object.keys(v) }) + if (Array.isArray(v)) { + resolve({ [store]: { format: `array[${v.length}]`}}) + } else if (typeof v === 'object') { + resolve({ [store]: { keys: Object.keys(v), format: 'Object' } }) } else { - resolve({ [store]: [] }) + resolve({ [store]: { keys: [] }}) } } var encoded = util.encodeObject({msg:v}); @@ -146,7 +147,7 @@ var api = module.exports = { } return } - result[store] = keys + result[store] = { keys } c--; if (c === 0) { if (!errorReported) {