123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- var fs = require('fs');
- var path = require('path');
- /**
- * Generate service clients
- *
- * Pass optional path to target directory.
- * The directory must include the apis/ folder and service customizations at
- * `lib/services`. Clients will be generated in `clients/`.
- *
- * If parameter is not passed the repository root will be used.
- */
- function ClientCreator(basePath) {
- basePath = basePath || path.join(__dirname, '..');
- this._metadataPath = path.join(basePath, 'apis', 'metadata.json');
- this._apisFolderPath = path.join(basePath, 'apis');
- this._clientFolderPath = path.join(basePath, 'clients');
- this._serviceCustomizationsFolderPath = path.join(basePath, 'lib', 'services');
- this._packageJsonPath = path.join(basePath, 'package.json');
- // Lazy loading values on usage to avoid side-effects in constructor
- this._apiFileNames = null;
- this._metadata = null;
- }
- ClientCreator.prototype.loadMetadata = function loadMetadata() {
- if (this._metadata) {
- return this._metadata;
- }
- var metadataFile = fs.readFileSync(this._metadataPath);
- this.metadata = JSON.parse(metadataFile);
- return this.metadata;
- };
- ClientCreator.prototype.getAllApiFilenames = function getAllApiFilenames() {
- if (this._apiFileNames) {
- return this._apiFileNames;
- }
- var apiFileNames = fs.readdirSync(this._apisFolderPath);
- // filter out metadata
- this._apiFileNames = apiFileNames.filter(function(name) {
- return name !== 'metadata.json';
- });
- return this._apiFileNames;
- };
- ClientCreator.prototype.getAllApiFilenamesForService = function getAllApiFilenamesForService(modelName) {
- var serviceRegex = new RegExp('(^' + modelName + '-([\\d]{4}-[\\d]{2}-[\\d]{2})\\.([\\w]+))\\.json$');
- var modelRegex = /(([\d]{4}-[\d]{2}-[\d]{2})\.([\w]+))\.json$/;
- var models = {};
- var versions = {};
- this.getAllApiFilenames().filter(function(name) {
- return name.search(serviceRegex) === 0;
- }).forEach(function(name) {
- var matches = name.match(serviceRegex);
- if (!matches) {
- return;
- }
- var model = matches[1];
- var version = matches[2];
- var modelType = matches[3];
- if (!versions.hasOwnProperty(version)) {
- versions[version] = {};
- }
- var versionInfo = versions[version];
- switch (modelType) {
- case 'min':
- versionInfo.api = model;
- break;
- case 'paginators':
- versionInfo.paginators = model;
- break;
- case 'waiters2':
- versionInfo.waiters = model;
- break;
- default:
- return;
- }
- });
- models.versions = versions;
- return models;
- };
- ClientCreator.prototype.customizationsExist = function customizationsExist(serviceName) {
- var customizationsFolder = this._serviceCustomizationsFolderPath;
- return fs.existsSync(path.join(customizationsFolder, serviceName + '.js'));
- };
- ClientCreator.prototype.generateClientFileSource = function generateClientFileSource(serviceMetadata, specifiedVersion) {
- var clientFolderPath = this._clientFolderPath;
- var className = serviceMetadata.name;
- var serviceName = className.toLowerCase();
- var modelName = serviceMetadata.prefix || serviceName;
- specifiedVersion = specifiedVersion || '*';
- // get models for the service
- var models = this.getAllApiFilenamesForService(modelName);
- var modelVersions = models && models.versions;
- if (!modelVersions) {
- throw new Error('Unable to get models for ' + modelName);
- }
- var obsoleteVersions = serviceMetadata.versions || [];
- var versionNumbers = Object.keys(modelVersions);
- var tab = ' ';
- var code = '';
- code += 'require(\'../lib/node_loader\');\n';
- code += 'var AWS = require(\'../lib/core\');\n';
- code += 'var Service = AWS.Service;\n';
- code += 'var apiLoader = AWS.apiLoader;\n\n';
- code += 'apiLoader.services[\'' + serviceName +'\'] = {};\n';
- code += 'AWS.' + className + ' = Service.defineService(\'' + serviceName + '\', [\'' + [].concat(obsoleteVersions, versionNumbers).sort().join('\', \'') + '\']);\n';
- // pull in service customizations
- if (this.customizationsExist(serviceName)) {
- code += 'require(\'../lib/services/' + serviceName + '\');\n';
- }
- versionNumbers.forEach(function(version) {
- // check version
- if (specifiedVersion !== '*' && specifiedVersion !== version) {
- return;
- }
- var versionInfo = modelVersions[version];
- if (!versionInfo.hasOwnProperty('api')) {
- throw new Error('No API model for ' + serviceName + '-' + version);
- }
- code += 'Object.defineProperty(apiLoader.services[\'' + serviceName +'\'], \'' + version + '\', {\n';
- code += tab + 'get: function get() {\n';
- code += tab + tab + 'var model = require(\'../apis/' + versionInfo.api + '.json\');\n';
- if (versionInfo.hasOwnProperty('paginators')) {
- code += tab + tab + 'model.paginators = require(\'../apis/' + versionInfo.paginators + '.json\').pagination;\n';
- }
- if (versionInfo.hasOwnProperty('waiters')) {
- code += tab + tab + 'model.waiters = require(\'../apis/' + versionInfo.waiters + '.json\').waiters;\n';
- }
- code += tab + tab + 'return model;\n';
- code += tab + '},\n';
- code += tab + 'enumerable: true,\n';
- code += tab + 'configurable: true\n';
- code += '});\n';
- });
- code += '\n';
- code += 'module.exports = AWS.' + className + ';\n';
- return {
- code: code,
- path: path.join(clientFolderPath, serviceName + '.js'),
- service: serviceName,
- };
- };
- ClientCreator.prototype.tabs = function tabs(count) {
- var tab = '';
- for (var i = 0; i < count; i++) {
- tab += ' ';
- }
- return tab;
- };
- ClientCreator.prototype.generateDefinePropertySource = function generateDefinePropertySource(objName, serviceName, className) {
- var tabs = this.tabs;
- var code = '';
- code += 'var ' + serviceName + ' = null;\n';
- code += 'Object.defineProperty(' + objName + ', \'' + className + '\', {\n';
- code += tabs(1) + 'get: function get() {\n';
- code += tabs(2) + 'return ' + serviceName + ' || require(\'./' + serviceName + '\');\n';
- code += tabs(1) + '},\n';
- code += tabs(1) + 'set: function set(svc) {\n';
- code += tabs(2) + serviceName + ' = svc;\n';
- code += tabs(1) + '},\n';
- code += tabs(1) + 'enumerable: true,\n';
- code += tabs(1) + 'configurable: true\n';
- code += '});\n';
- return code;
- };
- ClientCreator.prototype.generateAllServicesSource = function generateAllServicesSource(services, fileName) {
- var metadata = this.loadMetadata();
- var self = this;
- var code = '';
- code += 'require(\'../lib/node_loader\');\n';
- code += 'module.exports = {\n';
- services.forEach(function(service, idx) {
- var className = metadata[service].name;
- var tab = ' ';
- var isLast = idx === services.length - 1;
- code += self.tabs(1) + className + ': require(\'./' + service + '\')' + (isLast ? '' : ',') + '\n';
- });
- code += '};';
- return {
- code: code,
- path: path.join(this._clientFolderPath, fileName + '.js'),
- service: fileName
- };
- };
- ClientCreator.prototype.getDefaultServices = function getDefaultServices() {
- var metadata = this.loadMetadata();
- var services = [];
- for (var key in metadata) {
- if (!metadata.hasOwnProperty(key)) {
- continue;
- }
- var className = metadata[key].name;
- var serviceName = className.toLowerCase();
- services.push(serviceName);
- }
- return services;
- };
- ClientCreator.prototype.writeClientServices = function writeClientServices() {
- var metadata = this.loadMetadata();
- var services = [];
- var corsServices = [];
- for (var key in metadata) {
- if (!metadata.hasOwnProperty(key)) {
- continue;
- }
- var clientInfo = this.generateClientFileSource(metadata[key]);
- fs.writeFileSync(clientInfo.path, clientInfo.code);
- services.push(clientInfo.service);
- // check if service supports CORS
- if (metadata[key].cors === true) {
- corsServices.push(clientInfo.service);
- }
- }
- var allClientInfo = this.generateAllServicesSource(services, 'all');
- fs.writeFileSync(allClientInfo.path, allClientInfo.code);
- var browserClientInfo = this.generateAllServicesSource(corsServices, 'browser_default');
- fs.writeFileSync(browserClientInfo.path, browserClientInfo.code);
- };
- module.exports = ClientCreator;
|