client-creator.js (7869B)
1 var fs = require('fs'); 2 var path = require('path'); 3 4 // Generate service clients 5 function ClientCreator() { 6 this._metadata = require('../apis/metadata'); 7 this._apisFolderPath = path.join(__dirname, '..', 'apis'); 8 this._clientFolderPath = path.join(__dirname, '..', 'clients'); 9 this._serviceCustomizationsFolderPath = path.join(__dirname, '..', 'lib', 'services'); 10 this._packageJsonPath = path.join(__dirname, '..', 'package.json'); 11 this._apiFileNames = null; 12 } 13 14 ClientCreator.prototype.getAllApiFilenames = function getAllApiFilenames() { 15 if (this._apiFileNames) { 16 return this._apiFileNames; 17 } 18 var apiFileNames = fs.readdirSync(this._apisFolderPath); 19 // filter out metadata 20 this._apiFileNames = apiFileNames.filter(function(name) { 21 return name !== 'metadata.json'; 22 }); 23 return this._apiFileNames; 24 }; 25 26 ClientCreator.prototype.getAllApiFilenamesForService = function getAllApiFilenamesForService(modelName) { 27 var serviceRegex = new RegExp('(^' + modelName + '-([\\d]{4}-[\\d]{2}-[\\d]{2})\\.([\\w]+))\\.json$'); 28 var modelRegex = /(([\d]{4}-[\d]{2}-[\d]{2})\.([\w]+))\.json$/; 29 30 var models = {}; 31 var versions = {}; 32 this.getAllApiFilenames().filter(function(name) { 33 return name.search(serviceRegex) === 0; 34 }).forEach(function(name) { 35 var matches = name.match(serviceRegex); 36 if (!matches) { 37 return; 38 } 39 var model = matches[1]; 40 var version = matches[2]; 41 var modelType = matches[3]; 42 if (!versions.hasOwnProperty(version)) { 43 versions[version] = {}; 44 } 45 var versionInfo = versions[version]; 46 switch (modelType) { 47 case 'min': 48 versionInfo.api = model; 49 break; 50 case 'paginators': 51 versionInfo.paginators = model; 52 break; 53 case 'waiters2': 54 versionInfo.waiters = model; 55 break; 56 default: 57 return; 58 } 59 }); 60 models.versions = versions; 61 return models; 62 }; 63 64 ClientCreator.prototype.customizationsExist = function customizationsExist(serviceName) { 65 var customizationsFolder = this._serviceCustomizationsFolderPath; 66 return fs.existsSync(path.join(customizationsFolder, serviceName + '.js')); 67 }; 68 69 ClientCreator.prototype.generateClientFileSource = function generateClientFileSource(serviceMetadata, specifiedVersion) { 70 var clientFolderPath = this._clientFolderPath; 71 var className = serviceMetadata.name; 72 var serviceName = className.toLowerCase(); 73 var modelName = serviceMetadata.prefix || serviceName; 74 specifiedVersion = specifiedVersion || '*'; 75 76 // get models for the service 77 var models = this.getAllApiFilenamesForService(modelName); 78 79 var modelVersions = models && models.versions; 80 if (!modelVersions) { 81 throw new Error('Unable to get models for ' + modelName); 82 } 83 var obsoleteVersions = serviceMetadata.versions || []; 84 var versionNumbers = Object.keys(modelVersions); 85 var tab = ' '; 86 var code = ''; 87 code += 'require(\'../lib/node_loader\');\n'; 88 code += 'var AWS = require(\'../lib/core\');\n'; 89 code += 'var Service = require(\'../lib/service\');\n'; 90 code += 'var apiLoader = require(\'../lib/api_loader\');\n\n'; 91 code += 'apiLoader.services[\'' + serviceName +'\'] = {};\n'; 92 code += 'AWS.' + className + ' = Service.defineService(\'' + serviceName + '\', [\'' + [].concat(obsoleteVersions, versionNumbers).sort().join('\', \'') + '\']);\n'; 93 // pull in service customizations 94 if (this.customizationsExist(serviceName)) { 95 code += 'require(\'../lib/services/' + serviceName + '\');\n'; 96 } 97 versionNumbers.forEach(function(version) { 98 // check version 99 if (specifiedVersion !== '*' && specifiedVersion !== version) { 100 return; 101 } 102 var versionInfo = modelVersions[version]; 103 if (!versionInfo.hasOwnProperty('api')) { 104 throw new Error('No API model for ' + serviceName + '-' + version); 105 } 106 code += 'Object.defineProperty(apiLoader.services[\'' + serviceName +'\'], \'' + version + '\', {\n'; 107 code += tab + 'get: function get() {\n'; 108 code += tab + tab + 'var model = require(\'../apis/' + versionInfo.api + '.json\');\n' 109 if (versionInfo.hasOwnProperty('paginators')) { 110 code += tab + tab + 'model.paginators = require(\'../apis/' + versionInfo.paginators + '.json\').pagination;\n'; 111 } 112 if (versionInfo.hasOwnProperty('waiters')) { 113 code += tab + tab + 'model.waiters = require(\'../apis/' + versionInfo.waiters + '.json\').waiters;\n'; 114 } 115 code += tab + tab + 'return model;\n'; 116 code += tab + '},\n'; 117 code += tab + 'enumerable: true,\n'; 118 code += tab + 'configurable: true\n'; 119 code += '});\n'; 120 }); 121 122 code += '\n'; 123 code += 'module.exports = AWS.' + className + ';\n'; 124 return { 125 code: code, 126 path: path.join(clientFolderPath, serviceName + '.js'), 127 service: serviceName, 128 } 129 }; 130 131 ClientCreator.prototype.tabs = function tabs(count) { 132 var tab = ''; 133 for (var i = 0; i < count; i++) { 134 tab += ' '; 135 } 136 return tab; 137 } 138 139 ClientCreator.prototype.generateDefinePropertySource = function generateDefinePropertySource(objName, serviceName, className) { 140 var tabs = this.tabs; 141 var code = ''; 142 code += 'var ' + serviceName + ' = null;\n'; 143 code += 'Object.defineProperty(' + objName + ', \'' + className + '\', {\n'; 144 code += tabs(1) + 'get: function get() {\n'; 145 code += tabs(2) + 'return ' + serviceName + ' || require(\'./' + serviceName + '\');\n'; 146 code += tabs(1) + '},\n'; 147 code += tabs(1) + 'set: function set(svc) {\n'; 148 code += tabs(2) + serviceName + ' = svc;\n'; 149 code += tabs(1) + '},\n'; 150 code += tabs(1) + 'enumerable: true,\n'; 151 code += tabs(1) + 'configurable: true\n'; 152 code += '});\n'; 153 154 return code; 155 }; 156 157 ClientCreator.prototype.generateAllServicesSource = function generateAllServicesSource(services, fileName) { 158 var metadata = this._metadata; 159 var self = this; 160 var code = ''; 161 code += 'require(\'../lib/node_loader\');\n'; 162 code += 'var AWS = require(\'../lib/core\');\n\n'; 163 code += 'module.exports = {\n'; 164 165 services.forEach(function(service, idx) { 166 var className = metadata[service].name; 167 var tab = ' '; 168 var isLast = idx === services.length - 1; 169 //code += self.generateDefinePropertySource('AWS', service, className); 170 code += self.tabs(1) + className + ': require(\'./' + service + '\')' + (isLast ? '' : ',') + '\n'; 171 }); 172 code += '};'; 173 return { 174 code: code, 175 path: path.join(this._clientFolderPath, fileName + '.js'), 176 service: fileName 177 }; 178 }; 179 180 ClientCreator.prototype.getDefaultServices = function getDefaultServices() { 181 var metadata = this._metadata; 182 var services = []; 183 for (var key in metadata) { 184 if (!metadata.hasOwnProperty(key)) { 185 continue; 186 } 187 var className = metadata[key].name; 188 var serviceName = className.toLowerCase(); 189 services.push(serviceName); 190 } 191 return services; 192 }; 193 194 ClientCreator.prototype.writeClientServices = function writeClientServices() { 195 var metadata = this._metadata; 196 var services = []; 197 var corsServices = []; 198 for (var key in metadata) { 199 if (!metadata.hasOwnProperty(key)) { 200 continue; 201 } 202 var clientInfo = this.generateClientFileSource(metadata[key]); 203 fs.writeFileSync(clientInfo.path, clientInfo.code); 204 services.push(clientInfo.service); 205 // check if service supports CORS 206 if (metadata[key].cors === true) { 207 corsServices.push(clientInfo.service); 208 } 209 } 210 var allClientInfo = this.generateAllServicesSource(services, 'all'); 211 fs.writeFileSync(allClientInfo.path, allClientInfo.code); 212 var browserClientInfo = this.generateAllServicesSource(corsServices, 'browser_default'); 213 fs.writeFileSync(browserClientInfo.path, browserClientInfo.code); 214 }; 215 216 module.exports = ClientCreator;