Updated scripts

This commit is contained in:
delvedor
2018-11-08 19:36:24 +01:00
parent 869b50fca9
commit 2d7dfdd7a0
6 changed files with 74 additions and 62 deletions

View File

@ -19,7 +19,7 @@
"lint": "standard", "lint": "standard",
"lint:fix": "standard --fix", "lint:fix": "standard --fix",
"generate": "node scripts/run.js", "generate": "node scripts/run.js",
"elasticsearch": "docker run --rm -e \"node.attr.testattr=test\" -e \"path.repo=/tmp\" -e \"repositories.url.allowed_urls=http://snapshot.*\" -p 9200:9200 docker.elastic.co/elasticsearch/elasticsearch:6.4.0" "elasticsearch": "./scripts/es-docker.sh"
}, },
"author": { "author": {
"name": "Tomas Della Vedova", "name": "Tomas Della Vedova",
@ -31,6 +31,7 @@
}, },
"devDependencies": { "devDependencies": {
"dedent": "^0.7.0", "dedent": "^0.7.0",
"deepmerge": "^2.2.1",
"into-stream": "^4.0.0", "into-stream": "^4.0.0",
"js-yaml": "^3.12.0", "js-yaml": "^3.12.0",
"minimist": "^1.2.0", "minimist": "^1.2.0",

12
scripts/es-docker.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash
exec docker run \
--rm \
-e "node.attr.testattr=test" \
-e "path.repo=/tmp" \
-e "repositories.url.allowed_urls=http://snapshot.*" \
-p 9200:9200 \
docker.elastic.co/elasticsearch/elasticsearch:6.4.0
# -e "xpack.security.enabled=true" \
# -e "ELASTIC_PASSWORD=passw0rd" \

View File

@ -26,13 +26,15 @@ function start (opts) {
log.text = 'Cleaning API folder...' log.text = 'Cleaning API folder...'
rimraf.sync(join(apiOutputFolder, '*.js')) rimraf.sync(join(apiOutputFolder, '*.js'))
cloneAndCheckout({ log, tag: opts.tag }, (err, apiFolder) => { cloneAndCheckout({ log, tag: opts.tag }, (err, { apiFolder, xPackFolder }) => {
if (err) { if (err) {
log.fail(err.message) log.fail(err.message)
return return
} }
const files = readdirSync(apiFolder)
files.forEach(generateApiFile(apiFolder, log)) readdirSync(apiFolder).forEach(generateApiFile(apiFolder, log))
readdirSync(xPackFolder).forEach(generateApiFile(xPackFolder, log))
writeFileSync( writeFileSync(
mainOutputFile, mainOutputFile,
genFactory(apiOutputFolder), genFactory(apiOutputFolder),

View File

@ -7,6 +7,7 @@ const Git = require('simple-git')
const esRepo = 'https://github.com/elastic/elasticsearch.git' const esRepo = 'https://github.com/elastic/elasticsearch.git'
const esFolder = join(__dirname, '..', '..', 'elasticsearch') const esFolder = join(__dirname, '..', '..', 'elasticsearch')
const apiFolder = join(esFolder, 'rest-api-spec', 'src', 'main', 'resources', 'rest-api-spec', 'api') const apiFolder = join(esFolder, 'rest-api-spec', 'src', 'main', 'resources', 'rest-api-spec', 'api')
const xPackFolder = join(esFolder, 'x-pack', 'plugin', 'src', 'test', 'resources', 'rest-api-spec', 'api')
function cloneAndCheckout (opts, callback) { function cloneAndCheckout (opts, callback) {
const { log, tag } = opts const { log, tag } = opts
@ -51,7 +52,7 @@ function cloneAndCheckout (opts, callback) {
} }
return pull(checkout) return pull(checkout)
} }
callback(null, apiFolder) callback(null, { apiFolder, xPackFolder })
}) })
} }

View File

@ -2,37 +2,33 @@
const { readdirSync } = require('fs') const { readdirSync } = require('fs')
const dedent = require('dedent') const dedent = require('dedent')
const deepmerge = require('deepmerge')
function genFactory (folder) { function genFactory (folder) {
const apiToCamel = {}
// get all the API files // get all the API files
const apis = readdirSync(folder) const apiFiles = readdirSync(folder)
const apis = apiFiles
.map(file => { .map(file => {
const chunks = file.split('.') const name = format(file.slice(0, -3))
// if the api has not a namespace return file
if (chunks.length === 2) { .slice(0, -3) // remove `.js` extension
return { name: chunks[0], group: null, file } .split('.')
} else { .reverse()
const [group, name] = chunks .reduce((acc, val) => {
return { name, group, file } const obj = {
[val]: acc === null
? `${name}(opts)`
: acc
} }
if (isSnakeCased(val)) {
obj[camelify(val)] = acc === null
? `${name}(opts)`
: acc
}
return obj
}, null)
}) })
.reduce((acc, obj) => { .reduce((acc, val) => deepmerge(acc, val), {})
const { group, name, file } = obj
// create a namespace if present
if (group) {
acc[group] = acc[group] || {}
acc[group][name] = `require('./api/${file}')(opts)`
} else {
acc[name] = `require('./api/${file}')(opts)`
}
// save the snake_cased APIs for later use
if (isSnakeCased(name)) {
apiToCamel[group || '__root'] = apiToCamel[group || '__root'] || []
apiToCamel[group || '__root'].push(name)
}
return acc
}, {})
// serialize the API object // serialize the API object
const apisStr = JSON.stringify(apis, null, 2) const apisStr = JSON.stringify(apis, null, 2)
@ -47,6 +43,8 @@ function genFactory (folder) {
const assert = require('assert') const assert = require('assert')
${generateApiRequire(apiFiles)}
function ESAPI (opts) { function ESAPI (opts) {
assert(opts.makeRequest, 'Missing makeRequest function') assert(opts.makeRequest, 'Missing makeRequest function')
assert(opts.ConfigurationError, 'Missing ConfigurationError class') assert(opts.ConfigurationError, 'Missing ConfigurationError class')
@ -54,7 +52,6 @@ function genFactory (folder) {
const apis = ${apisStr} const apis = ${apisStr}
${generateDefinedProperties(apiToCamel).join('\n\n ')}
return apis return apis
} }
@ -66,33 +63,13 @@ function genFactory (folder) {
return fn + '\n' return fn + '\n'
} }
// generates an array of Object.defineProperties function generateApiRequire (apiFiles) {
// to allow the use of camelCase APIs return apiFiles
// instead of snake_cased .map(file => {
function generateDefinedProperties (apiToCamel) { const name = format(file.slice(0, -3))
const arr = [] return `const ${name} = require('./api/${file}')`
for (const api in apiToCamel) {
const obj = api === '__root'
? 'apis'
: `apis.${api}`
const code = `
Object.defineProperties(${obj}, {
${apiToCamel[api].map(createGetter).join(',\n ')}
}) })
`.trim() .join('\n')
arr.push(code)
}
return arr
function createGetter (api) {
return `
${camelify(api)}: {
get: function () { return this.${api} },
enumerable: true
}
`.trim()
}
} }
// from snake_case to camelCase // from snake_case to camelCase
@ -100,6 +77,22 @@ function camelify (str) {
return str.replace(/_([a-z])/g, k => k[1].toUpperCase()) return str.replace(/_([a-z])/g, k => k[1].toUpperCase())
} }
// from 'hello.world to helloWorld
function undot (str) {
return str.replace(/\.([a-z])/g, k => k[1].toUpperCase())
}
function safeWords (str) {
if (str === 'delete') {
return '_delete'
}
return str
}
function format (str) {
return safeWords(undot(camelify(str)))
}
function isSnakeCased (str) { function isSnakeCased (str) {
return !!~str.indexOf('_') return !!~str.indexOf('_')
} }

View File

@ -410,7 +410,7 @@ function genUrlValidation (paths, api) {
if (chunks[i] === camelCased) { if (chunks[i] === camelCased) {
code += `params['${chunks[i]}'] == null${i === len - 1 ? '' : ' || '}` code += `params['${chunks[i]}'] == null${i === len - 1 ? '' : ' || '}`
} else { } else {
code += `(params['${chunks[i]}'] == null || params['${camelCased}')${i === len - 1 ? '' : ' || '}` code += `(params['${chunks[i]}'] == null || params['${camelCased}'])${i === len - 1 ? '' : ' || '}`
} }
} }
code += `)) { code += `)) {
@ -442,16 +442,19 @@ function generateDocumentation (api, op) {
doc += ` * Perform a [${op}](${api.documentation}) request\n *\n` doc += ` * Perform a [${op}](${api.documentation}) request\n *\n`
Object.keys(parts).forEach(part => { Object.keys(parts).forEach(part => {
const obj = parts[part] const obj = parts[part]
doc += ` * @param {${obj.type}} ${part} - ${obj.description.replace(/\u00A0/g, ' ')}\n` const description = obj.description || ''
doc += ` * @param {${obj.type}} ${part} - ${description.replace(/\u00A0/g, ' ')}\n`
}) })
Object.keys(params).forEach(param => { Object.keys(params).forEach(param => {
const obj = params[param] const obj = params[param]
doc += ` * @param {${obj.type}} ${param} - ${obj.description.replace(/\u00A0/g, ' ')}\n` const description = obj.description || ''
doc += ` * @param {${obj.type}} ${param} - ${description.replace(/\u00A0/g, ' ')}\n`
}) })
if (body) { if (body) {
doc += ` * @param {${body.type || 'object'}} body - ${body.description.replace(/\u00A0/g, ' ')}\n` const description = body.description || ''
doc += ` * @param {${body.type || 'object'}} body - ${description.replace(/\u00A0/g, ' ')}\n`
} }
doc += ' */' doc += ' */'