Support bracket-notation in auto complete when needed

This commit is contained in:
Nick O'Leary 2023-12-11 21:18:44 +00:00
parent b9c1dedab3
commit 7197153fd5
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
2 changed files with 32 additions and 13 deletions

View File

@ -110,26 +110,39 @@
} }
} }
const contextAutoComplete = function(options) { const contextAutoComplete = function(options) {
const cache = {} const cache = {}
const knownKeys = {} const knownKeys = {}
const getContextKeysFromRuntime = function(scope, store, searchKey, done) { const getContextKeysFromRuntime = function(scope, store, searchKey, done) {
knownKeys[store] = knownKeys[store] || new Set() 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` const url = `context/${scope}/${encodeURIComponent(searchKey)}?store=${store}&keysOnly`
if (cache[url]) { if (cache[url]) {
console.log('CACHED', url) // console.log('CACHED', url)
done() done()
} else { } else {
console.log('GET', url) // console.log('GET', url)
$.getJSON(url, function(data) { $.getJSON(url, function(data) {
console.log(data)
cache[url] = true cache[url] = true
const keys = data[store] || [] const result = data[store] || {}
const keys = result.keys || []
const keyPrefix = searchKey + (searchKey.length > 0 ? '.' : '') const keyPrefix = searchKey + (searchKey.length > 0 ? '.' : '')
keys.forEach(key => { 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() done()
}) })
@ -158,7 +171,7 @@
const searchKey = keyParts.join('.') const searchKey = keyParts.join('.')
getContextKeysFromRuntime(scope, store, searchKey, function() { getContextKeysFromRuntime(scope, store, searchKey, function() {
if (knownKeys[store].has(key)) { if (knownKeys[store].has(key) || key.endsWith(']')) {
getContextKeysFromRuntime(scope, store, key, function() { getContextKeysFromRuntime(scope, store, key, function() {
done(knownKeys[store]) done(knownKeys[store])
}) })
@ -173,7 +186,12 @@
const matches = [] const matches = []
keys.forEach(v => { keys.forEach(v => {
let optVal = 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) { if (valMatch.found) {
const element = $('<div>',{style: "display: flex"}); const element = $('<div>',{style: "display: flex"});
const valEl = $('<div/>',{style:"font-family: var(--red-ui-monospace-font); white-space:nowrap; overflow: hidden; flex-grow:1"}); const valEl = $('<div/>',{style:"font-family: var(--red-ui-monospace-font); white-space:nowrap; overflow: hidden; flex-grow:1"});

View File

@ -101,14 +101,15 @@ var api = module.exports = {
} }
if (ctx) { if (ctx) {
if (key) { if (key) {
console.log('GET KEY', key)
store = store || availableStores.default; store = store || availableStores.default;
ctx.get(key,store,function(err, v) { ctx.get(key,store,function(err, v) {
if (opts.keysOnly) { if (opts.keysOnly) {
if (typeof v === 'object') { if (Array.isArray(v)) {
resolve({ [store]: Object.keys(v) }) resolve({ [store]: { format: `array[${v.length}]`}})
} else if (typeof v === 'object') {
resolve({ [store]: { keys: Object.keys(v), format: 'Object' } })
} else { } else {
resolve({ [store]: [] }) resolve({ [store]: { keys: [] }})
} }
} }
var encoded = util.encodeObject({msg:v}); var encoded = util.encodeObject({msg:v});
@ -146,7 +147,7 @@ var api = module.exports = {
} }
return return
} }
result[store] = keys result[store] = { keys }
c--; c--;
if (c === 0) { if (c === 0) {
if (!errorReported) { if (!errorReported) {