From 2d7dfdd7a054032169030e4e3a384389a464e1d6 Mon Sep 17 00:00:00 2001 From: delvedor Date: Thu, 8 Nov 2018 19:36:24 +0100 Subject: [PATCH] Updated scripts --- package.json | 3 +- scripts/es-docker.sh | 12 +++++ scripts/run.js | 8 ++-- scripts/utils/clone-es.js | 3 +- scripts/utils/genMain.js | 99 ++++++++++++++++++--------------------- scripts/utils/generate.js | 11 +++-- 6 files changed, 74 insertions(+), 62 deletions(-) create mode 100755 scripts/es-docker.sh diff --git a/package.json b/package.json index fcb3feaa3..5fda757e3 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "lint": "standard", "lint:fix": "standard --fix", "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": { "name": "Tomas Della Vedova", @@ -31,6 +31,7 @@ }, "devDependencies": { "dedent": "^0.7.0", + "deepmerge": "^2.2.1", "into-stream": "^4.0.0", "js-yaml": "^3.12.0", "minimist": "^1.2.0", diff --git a/scripts/es-docker.sh b/scripts/es-docker.sh new file mode 100755 index 000000000..655b09cce --- /dev/null +++ b/scripts/es-docker.sh @@ -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" \ diff --git a/scripts/run.js b/scripts/run.js index 73af7f447..0dc1ec61b 100644 --- a/scripts/run.js +++ b/scripts/run.js @@ -26,13 +26,15 @@ function start (opts) { log.text = 'Cleaning API folder...' rimraf.sync(join(apiOutputFolder, '*.js')) - cloneAndCheckout({ log, tag: opts.tag }, (err, apiFolder) => { + cloneAndCheckout({ log, tag: opts.tag }, (err, { apiFolder, xPackFolder }) => { if (err) { log.fail(err.message) return } - const files = readdirSync(apiFolder) - files.forEach(generateApiFile(apiFolder, log)) + + readdirSync(apiFolder).forEach(generateApiFile(apiFolder, log)) + readdirSync(xPackFolder).forEach(generateApiFile(xPackFolder, log)) + writeFileSync( mainOutputFile, genFactory(apiOutputFolder), diff --git a/scripts/utils/clone-es.js b/scripts/utils/clone-es.js index 02452cda3..4d424c00a 100644 --- a/scripts/utils/clone-es.js +++ b/scripts/utils/clone-es.js @@ -7,6 +7,7 @@ const Git = require('simple-git') const esRepo = 'https://github.com/elastic/elasticsearch.git' const esFolder = join(__dirname, '..', '..', 'elasticsearch') 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) { const { log, tag } = opts @@ -51,7 +52,7 @@ function cloneAndCheckout (opts, callback) { } return pull(checkout) } - callback(null, apiFolder) + callback(null, { apiFolder, xPackFolder }) }) } diff --git a/scripts/utils/genMain.js b/scripts/utils/genMain.js index 7d6bd00c3..350a5904f 100644 --- a/scripts/utils/genMain.js +++ b/scripts/utils/genMain.js @@ -2,37 +2,33 @@ const { readdirSync } = require('fs') const dedent = require('dedent') +const deepmerge = require('deepmerge') function genFactory (folder) { - const apiToCamel = {} // get all the API files - const apis = readdirSync(folder) + const apiFiles = readdirSync(folder) + const apis = apiFiles .map(file => { - const chunks = file.split('.') - // if the api has not a namespace - if (chunks.length === 2) { - return { name: chunks[0], group: null, file } - } else { - const [group, name] = chunks - return { name, group, file } - } + const name = format(file.slice(0, -3)) + return file + .slice(0, -3) // remove `.js` extension + .split('.') + .reverse() + .reduce((acc, val) => { + 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) => { - 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 - }, {}) + .reduce((acc, val) => deepmerge(acc, val), {}) // serialize the API object const apisStr = JSON.stringify(apis, null, 2) @@ -47,6 +43,8 @@ function genFactory (folder) { const assert = require('assert') + ${generateApiRequire(apiFiles)} + function ESAPI (opts) { assert(opts.makeRequest, 'Missing makeRequest function') assert(opts.ConfigurationError, 'Missing ConfigurationError class') @@ -54,7 +52,6 @@ function genFactory (folder) { const apis = ${apisStr} - ${generateDefinedProperties(apiToCamel).join('\n\n ')} return apis } @@ -66,33 +63,13 @@ function genFactory (folder) { return fn + '\n' } -// generates an array of Object.defineProperties -// to allow the use of camelCase APIs -// instead of snake_cased -function generateDefinedProperties (apiToCamel) { - const arr = [] - for (const api in apiToCamel) { - const obj = api === '__root' - ? 'apis' - : `apis.${api}` - const code = ` - Object.defineProperties(${obj}, { - ${apiToCamel[api].map(createGetter).join(',\n ')} +function generateApiRequire (apiFiles) { + return apiFiles + .map(file => { + const name = format(file.slice(0, -3)) + return `const ${name} = require('./api/${file}')` }) - `.trim() - arr.push(code) - } - - return arr - - function createGetter (api) { - return ` - ${camelify(api)}: { - get: function () { return this.${api} }, - enumerable: true - } - `.trim() - } + .join('\n') } // from snake_case to camelCase @@ -100,6 +77,22 @@ function camelify (str) { 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) { return !!~str.indexOf('_') } diff --git a/scripts/utils/generate.js b/scripts/utils/generate.js index e143919e4..a6d09ad3f 100644 --- a/scripts/utils/generate.js +++ b/scripts/utils/generate.js @@ -410,7 +410,7 @@ function genUrlValidation (paths, api) { if (chunks[i] === camelCased) { code += `params['${chunks[i]}'] == null${i === len - 1 ? '' : ' || '}` } else { - code += `(params['${chunks[i]}'] == null || params['${camelCased}')${i === len - 1 ? '' : ' || '}` + code += `(params['${chunks[i]}'] == null || params['${camelCased}'])${i === len - 1 ? '' : ' || '}` } } code += `)) { @@ -442,16 +442,19 @@ function generateDocumentation (api, op) { doc += ` * Perform a [${op}](${api.documentation}) request\n *\n` Object.keys(parts).forEach(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 => { 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) { - 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 += ' */'