-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Webpack support #1117
[WIP] Webpack support #1117
Changes from 3 commits
8b6b242
8011561
dcc6109
c409c0b
fbd7a7a
e59bfca
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
var fs = require('fs'); | ||
var util = require('util'); | ||
var path = require('path'); | ||
|
||
var AWS = require('../'); | ||
var apis = require('../lib/api_loader'); | ||
var metadata = require('../apis/metadata'); | ||
|
||
var defaultServices = 'acm,apigateway,applicationautoscaling,autoscaling,cloudformation,cloudfront,cloudhsm,cloudtrail,cloudwatch,cloudwatchlogs,cloudwatchevents,codecommit,codedeploy,codepipeline,cognitoidentity,cognitoidentityserviceprovider,cognitosync,configservice,devicefarm,directconnect,dynamodb,dynamodbstreams,ec2,ecr,ecs,elasticache,elasticbeanstalk,elastictranscoder,elb,emr,firehose,gamelift,inspector,iotdata,kinesis,kms,lambda,marketplacecommerceanalytics,mobileanalytics,machinelearning,opsworks,rds,redshift,route53,route53domains,s3,ses,sns,sqs,ssm,storagegateway,sts,waf'; | ||
var sanitizeRegex = /[^a-zA-Z0-9,-]/; | ||
|
||
var serviceClasses = {}; | ||
Object.keys(AWS).forEach(function(name) { | ||
if (AWS[name].serviceIdentifier) { | ||
serviceClasses[AWS[name].serviceIdentifier] = AWS[name]; | ||
} | ||
}); | ||
|
||
function getServiceHeader(service) { | ||
if (service === 'all') { | ||
return Object.keys(serviceClasses).map(function(name) { | ||
return getServiceHeader(name); | ||
}).join('\n'); | ||
} | ||
|
||
if (!serviceClasses[service]) return null; | ||
var versions = serviceClasses[service].apiVersions.map(function(version) { | ||
return version.indexOf('*') >= 0 ? null : version; | ||
}).filter(function(c) { return c !== null; }); | ||
|
||
var file = util.format( | ||
'AWS.apiLoader.services[\'%s\'] = {};\n' + | ||
'AWS.%s = AWS.Service.defineService(\'%s\', %s);\n', | ||
service, apis.serviceName(service), service, util.inspect(versions)); | ||
var svcPath = path.join(__dirname, '..', 'lib', 'services', service + '.js'); | ||
if (fs.existsSync(svcPath)) { | ||
file += 'require(\'./services/' + service + '\');\n'; | ||
} | ||
|
||
return file; | ||
} | ||
|
||
function getService(service, version) { | ||
if (service === 'all') { | ||
return Object.keys(serviceClasses).map(function(name) { | ||
var out = serviceClasses[name].apiVersions.map(function(svcVersion) { | ||
if (svcVersion.indexOf('*') >= 0) return null; | ||
return getService(name, svcVersion); | ||
}).filter(function(c) { return c !== null; }).join('\n'); | ||
|
||
return out; | ||
}).join('\n'); | ||
} | ||
|
||
var svc, api; | ||
if (!serviceClasses[service]) { | ||
return null; | ||
} | ||
|
||
try { | ||
var ClassName = serviceClasses[service]; | ||
svc = new ClassName({apiVersion: version, endpoint: 'localhost'}); | ||
api = apis.load(service, svc.api.apiVersion); | ||
} catch (e) { | ||
return null; | ||
} | ||
|
||
var serviceFileName = metadata[service].prefix || service; | ||
var lines = []; | ||
var line = util.format( | ||
'AWS.apiLoader.services[\'%s\'][\'%s\'] = %s;\n', | ||
service, svc.api.apiVersion, 'require(\'../apis/' + serviceFileName + '-' + svc.api.apiVersion + '.min\')'); | ||
lines.push(line); | ||
if (Object.prototype.hasOwnProperty.call(api, 'paginators')) { | ||
line = util.format( | ||
'AWS.apiLoader.services[\'%s\'][\'%s\'].paginators = %s;\n', | ||
service, svc.api.apiVersion, 'require(\'../apis/' + serviceFileName + '-' + svc.api.apiVersion + '.paginators\').pagination'); | ||
lines.push(line); | ||
} | ||
if (Object.prototype.hasOwnProperty.call(api, 'waiters')) { | ||
line = util.format( | ||
'AWS.apiLoader.services[\'%s\'][\'%s\'].waiters = %s;\n', | ||
service, svc.api.apiVersion, 'require(\'../apis/' + serviceFileName + '-' + svc.api.apiVersion + '.waiters2\').waiters'); | ||
lines.push(line); | ||
} | ||
|
||
return lines.join(''); | ||
} | ||
|
||
function ServiceCollector(services) { | ||
var builtServices = {}; | ||
|
||
function buildService(name, usingDefaultServices) { | ||
var match = name.match(/^(.+?)(?:-(.+?))?$/); | ||
var service = match[1], version = match[2] || 'latest'; | ||
var contents = []; | ||
var lines, err; | ||
|
||
if (!builtServices[service]) { | ||
builtServices[service] = {}; | ||
|
||
lines = getServiceHeader(service); | ||
if (lines === null) { | ||
if (!usingDefaultServices) { | ||
err = new Error('Invalid module: ' + service); | ||
err.name = 'InvalidModuleError'; | ||
throw err; | ||
} | ||
} else { | ||
contents.push(lines); | ||
} | ||
} | ||
|
||
if (!builtServices[service][version]) { | ||
builtServices[service][version] = true; | ||
|
||
lines = getService(service, version); | ||
if (lines === null) { | ||
if (!usingDefaultServices) { | ||
err = new Error('Invalid module: ' + service + '-' + version); | ||
err.name = 'InvalidModuleError'; | ||
throw err; | ||
} | ||
} else { | ||
contents.push(lines); | ||
} | ||
} | ||
|
||
return contents.join(''); | ||
} | ||
|
||
var serviceCode = ''; | ||
var usingDefaultServicesToggle = false; | ||
if (!services) { | ||
usingDefaultServicesToggle = true; | ||
services = defaultServices; | ||
} | ||
if (services.match(sanitizeRegex)) { | ||
throw new Error('Incorrectly formatted service names'); | ||
} | ||
|
||
var invalidModules = []; | ||
var stsIncluded = false; | ||
services.split(',').sort().forEach(function(name) { | ||
if (name.match(/^sts\b/) || name === 'all') stsIncluded = true; | ||
try { | ||
serviceCode += buildService(name, usingDefaultServicesToggle) + '\n'; | ||
} catch (e) { | ||
if (e.name === 'InvalidModuleError') invalidModules.push(name); | ||
else throw e; | ||
} | ||
}); | ||
|
||
if (!stsIncluded) { | ||
serviceCode += buildService('sts') + '\n'; | ||
} | ||
|
||
if (invalidModules.length > 0) { | ||
throw new Error('Missing modules: ' + invalidModules.join(', ')); | ||
} | ||
|
||
return serviceCode; | ||
} | ||
|
||
module.exports = ServiceCollector; | ||
|
||
//var source = ServiceCollector(defaultServices); | ||
var source = ServiceCollector(process.env.AWS_SERVICES); | ||
fs.writeFile(path.join(__dirname, '..', 'lib', 'browser_services.js'), source); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,11 @@ | ||
var util = require('./util'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @chrisradek Do you think it might be worthwhile adding a buffer polyfill as well? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Absolutely. Webpack actually does polyfill buffer, but I like taking control of which buffer polyfill to use back to us (makes updating when bugs are fixed easier), and to make supporting other tools easier. |
||
|
||
// browser specific modules | ||
util.crypto.lib = require('crypto-browserify'); | ||
|
||
// browser stubs | ||
util.nodeRequire = function nodeRequire(mod) {}; | ||
|
||
var AWS = require('./core'); | ||
|
||
// Load browser API loader | ||
|
@@ -16,6 +24,15 @@ AWS.XML.Parser = require('./xml/browser_parser'); | |
// Load the XHR HttpClient | ||
require('./http/xhr'); | ||
|
||
if (typeof process === 'undefined') { | ||
process = { | ||
browser: true | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be |
||
} | ||
|
||
if (typeof window !== 'undefined') window.AWS = AWS; | ||
if (typeof module !== 'undefined') module.exports = AWS; | ||
if (typeof self !== 'undefined') self.AWS = AWS; | ||
|
||
// Load services | ||
require('./browser_services'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious why we can't just rely on browserify pulling in deps?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm working on rewriting this script to better support custom builds, so a lot will probably change here.
I'm not quite sure what you mean. Are you asking why we can't rely on browserify to pull in the service clients, or all the node.js module deps as well? Part of my motivation was so that webpack users wouldn't need browserify as well to customize their build.