11import isArray from "lodash/isArray"
22import isObject from "lodash/isObject"
3- import get from "lodash/get"
4- import last from "lodash/last"
53import mapValues from "lodash/mapValues"
4+ import isPlainObject from "lodash/isPlainObject"
65import toArray from "lodash/toArray"
76import isString from "lodash/isString"
8- import YAML from "js-yaml"
97
10- //eslint-disable-next-line no-unused-vars
11- export function getKeywordsForPath ( { path, prefix, currentLine, editorValue, keywordMap } ) {
8+ export default function getKeywordsForPath ( { system, path, keywordMap} ) {
129 keywordMap = Object . assign ( { } , keywordMap )
1310
1411 // is getting path was not successful stop here and return no candidates
@@ -23,21 +20,34 @@ export function getKeywordsForPath({ path, prefix, currentLine, editorValue, key
2320 ]
2421 }
2522
26- if ( last ( path ) === "$ref" ) {
27- let context = getContextType ( path )
28- let $refsForContext = $refablesForPath ( editorValue , [ context ] )
29- return $refsForContext
30- }
31-
3223 if ( path [ path . length - 2 ] === "tags" && path . length > 2 ) {
3324 // 'path.length > 2' excludes top-level 'tags'
34- return getGlobalCompletions ( editorValue , [ "tags" ] , "name" )
25+ return system . specSelectors . tags ( ) . map ( tag => ( {
26+ score : 0 ,
27+ meta : "local" ,
28+ value : tag . get ( "name" ) ,
29+ } ) ) . toJS ( )
3530 }
3631
3732 let reversePath = path . slice ( 0 ) . reverse ( )
3833 if ( reversePath [ 1 ] === "security" && isNumeric ( reversePath [ 0 ] ) ) {
3934 // **.security[x]
40- return getGlobalCompletions ( editorValue , [ "securityDefinitions" ] , "name" )
35+ return system . specSelectors . securityDefinitions ( ) . keySeq ( ) . map ( sec => ( {
36+ score : 0 ,
37+ meta : "local" ,
38+ caption : sec ,
39+ snippet : `${ sec } : []`
40+ } ) ) . toJS ( )
41+ }
42+
43+ if ( reversePath [ 0 ] === "security" ) {
44+ // **.security:
45+ return system . specSelectors . securityDefinitions ( ) . keySeq ( ) . map ( sec => ( {
46+ score : 0 ,
47+ meta : "local" ,
48+ caption : sec ,
49+ snippet : `\n- ${ sec } : []`
50+ } ) ) . toJS ( )
4151 }
4252
4353 // traverse down the keywordMap for each key in the path until there is
@@ -65,20 +75,18 @@ export function getKeywordsForPath({ path, prefix, currentLine, editorValue, key
6575 // suggest for array items
6676 if ( isArray ( keywordMap ) ) {
6777 if ( isArray ( keywordMap [ 0 ] ) ) {
68- let indent = ""
6978 return keywordMap [ 0 ] . map ( item => {
7079 return {
7180 name : "array" ,
72- value : indent + "- " + item ,
81+ value : "- " + item ,
7382 score : 300 ,
7483 meta : "array item"
7584 }
7685 } )
7786 } else {
78- let indent = ""
7987 return [ {
8088 name : "array" ,
81- value : indent + "- " ,
89+ value : "- " ,
8290 score : 300 ,
8391 meta : "array item"
8492 } ]
@@ -92,8 +100,7 @@ export function getKeywordsForPath({ path, prefix, currentLine, editorValue, key
92100
93101 // for each key in keywordMap map construct a completion candidate and
94102 // return the array
95- return formatKeywordMap ( keywordMap )
96- . map ( constructAceCompletion . bind ( null , "keyword" ) )
103+ return suggestionFromSchema ( keywordMap )
97104}
98105
99106function getChild ( object , key ) {
@@ -119,96 +126,45 @@ function getChild(object, key) {
119126 }
120127}
121128
122- function formatKeywordMap ( map ) {
123- let res = mapValues ( map , ( val , key ) => {
124- return val . __value === undefined ? key : val . __value
125- } )
129+ function suggestionFromSchema ( map ) {
130+ const res = toArray ( mapValues ( map , ( val , key ) => {
131+ const keyword = val . __value === undefined ? key : val . __value
132+ const meta = isPlainObject ( val ) ? "object" : "keyword"
126133
127- return toArray ( res )
134+ return constructAceCompletion ( meta , keyword )
135+ } ) )
136+ return res
128137}
129138
130139function constructAceCompletion ( meta , keyword ) {
131140 if ( keyword . slice ( 0 , 2 ) === "__" ) {
132141 return { }
133142 }
134143
135- return {
136- name : keyword ,
137- value : keyword ,
138- score : 300 ,
139- meta : meta || "keyword"
144+ // Give keywords, that extra colon
145+ let snippet
146+ switch ( meta ) {
147+ case "keyword" :
148+ snippet = `${ keyword } : `
149+ break
150+ case "object" :
151+ snippet = `${ keyword } :\n `
152+ break
153+ default :
154+ snippet = keyword
140155 }
141- }
142156
143- function $refablesForPath ( specStr , path ) {
144- let refs = Object . keys ( getJSFromYaml ( specStr , path ) || { } )
157+ // snippet's treat `$` as special characters
158+ snippet = snippet . replace ( "$" , "\\$" )
145159
146- let completions = refs . map ( ref => {
147- return {
148- score : 0 ,
149- meta : "local" ,
150- value : `'#/${ path . join ( "/" ) } /${ ref } '` ,
151- caption : ref
152- }
153- } )
154-
155- return completions || [ ]
156- }
157-
158- function getGlobalCompletions ( specStr , path , prop ) {
159- let items = getJSFromYaml ( specStr , path ) || [ ]
160- if ( isArray ( items ) ) {
161- return items
162- . filter ( item => ! ! item )
163- . map ( item => prop ? item [ prop ] : item )
164- . map ( name => {
165- if ( ! name ) { return { } }
166- return {
167- score : 0 ,
168- meta : "local" ,
169- value : name
170- }
171- } )
172-
173- } else {
174- return Object . keys ( mapValues ( items , ( item ) => {
175- return prop ? item [ prop ] : item
176- } ) ) . map ( name => {
177- if ( ! name ) { return { } }
178- return {
179- score : 0 ,
180- meta : "local" ,
181- value : name
182- }
183- } )
160+ return {
161+ snippet,
162+ caption : keyword ,
163+ score : 300 ,
164+ meta,
184165 }
185166}
186167
187- function getJSFromYaml ( yaml , path = [ ] ) {
188- let obj = YAML . safeLoad ( yaml )
189- let sub = get ( obj , path )
190- return sub
191- }
192-
193168function isNumeric ( obj ) {
194169 return ! isNaN ( obj )
195170}
196-
197- export function getContextType ( path ) {
198- let contextTypes = {
199- "paths" : "pathitems" ,
200- "definitions" : "definitions" ,
201- "schema" : "definitions" ,
202- "parameters" : "parameters" ,
203- "responses" : "responses"
204- }
205-
206- for ( var i = path . length - 1 ; i > - 1 ; i -- ) {
207- let tag = path [ i ]
208-
209- if ( contextTypes [ tag ] ) {
210- return contextTypes [ tag ]
211- }
212- }
213- return null
214- }
0 commit comments