Files
elasticsearch-js/scripts/utils/genMain.js
Tomas Della Vedova 358474bca8 Feat: Support bundlers (#783)
With this change, we support code bundlers, such as webpack.
Fixes: https://github.com/elastic/elasticsearch-js/issues/781
2019-03-19 09:53:43 +01:00

166 lines
5.0 KiB
JavaScript

/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/* eslint-disable no-template-curly-in-string */
'use strict'
const { readdirSync } = require('fs')
const dedent = require('dedent')
const deepmerge = require('deepmerge')
function genFactory (folder) {
// get all the API files
const apiFiles = readdirSync(folder)
const types = apiFiles
.map(file => {
const name = file
.slice(0, -3)
.replace(/\.([a-z])/g, k => k[1].toUpperCase())
.replace(/_([a-z])/g, k => k[1].toUpperCase())
return file
.slice(0, -3) // remove `.js` extension
.split('.')
.reverse()
.reduce((acc, val) => {
const obj = {
[val]: acc === null
? `ApiMethod<RequestParams.${name[0].toUpperCase() + name.slice(1)}>`
: acc
}
if (isSnakeCased(val)) {
obj[camelify(val)] = acc === null
? `ApiMethod<RequestParams.${name[0].toUpperCase() + name.slice(1)}>`
: acc
}
return obj
}, null)
})
.reduce((acc, val) => deepmerge(acc, val), {})
const apis = apiFiles
.map(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
? `lazyLoad('${file.slice(0, -3)}', opts)` // `${name}(opts)`
: acc
}
if (isSnakeCased(val)) {
obj[camelify(val)] = acc === null
? `lazyLoad('${file.slice(0, -3)}', opts)` // `${name}(opts)`
: acc
}
return obj
}, null)
})
.reduce((acc, val) => deepmerge(acc, val), {})
// serialize the API object
const apisStr = JSON.stringify(apis, null, 2)
// split & join to fix the indentation
.split('\n')
.join('\n ')
// remove useless quotes
.replace(/"/g, '')
// serialize the type object
const typesStr = Object.keys(types)
.map(key => `${key}: ${JSON.stringify(types[key], null, 2)}`)
.join('\n')
// remove useless quotes and commas
.replace(/"/g, '')
.replace(/,/g, '')
const fn = dedent`
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
'use strict'
const assert = require('assert')
function ESAPI (opts) {
assert(opts.makeRequest, 'Missing makeRequest function')
assert(opts.ConfigurationError, 'Missing ConfigurationError class')
assert(opts.result, 'Missing default result object')
const apis = ${apisStr}
return apis
}
// It's unlikely that a user needs all of our APIs,
// and since require is a sync operation that takes time
// (given the amount of APIs we have), let's lazy load them,
// so a given API file will be required only
// if the user actually needs that API.
// The following implementation takes advantage
// of js closures to have a simple cache with the least overhead.
function lazyLoad (file, opts) {
var fn = null
return function _lazyLoad (params, options, callback) {
if (fn === null) {
fn = require(${'`./api/${file}.js`'})(opts)
}
return fn(params, options, callback)
}
}
module.exports = ESAPI
`
// new line at the end of file
return { fn: fn + '\n', types: typesStr }
}
// from snake_case to camelCase
function camelify (str) {
return str.replace(/_([a-z])/g, k => k[1].toUpperCase())
}
function isSnakeCased (str) {
return !!~str.indexOf('_')
}
module.exports = genFactory