aws-spa
Version:
A no-brainer script to deploy a single page app on AWS
96 lines (77 loc) • 4.59 kB
JavaScript
;
var yargs = _interopRequireWildcard(require("yargs"));
var _deploy = require("./deploy");
var _logger = require("./logger");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
yargs.command('deploy <domainName>', 'Deploy a single page app on AWS', yargs => {
return yargs.positional('domainName', {
type: 'string',
demand: true,
describe: `The domain name on which the SPA will be accessible. For example "app.example.com".
You can also specify a path: "app.example.com/something". This can be useful to deploy multiple versions of the app in the same s3 bucket. For example one could deploy a feature branch of the SPA like this:
aws-spa deploy app.example.com/$(git branch | grep \* | cut -d ' ' -f2)`
}).option('wait', {
type: 'boolean',
default: false,
describe: 'Wait for CloudFront distribution to be deployed & cache invalidation to be completed'
}).option('directory', {
type: 'string',
default: 'build',
describe: 'The directory where the static files have been generated. It must contain an index.html file'
}).option('cacheInvalidation', {
type: 'string',
default: '/*',
describe: 'The paths to invalidate on CloudFront. Default is all (/*). You can specify several paths comma separated.'
}).option('cacheBustedPrefix', {
type: 'string',
describe: 'A folder where files use cache busting strategy.'
}).option('noPrompt', {
type: 'boolean',
default: false,
describe: 'Disable confirm message that prompts on non CI environments (env CI=true)'
}).option('shouldBlockBucketPublicAccess', {
type: 'boolean',
default: false,
describe: `Use a REST API endpoint as the origin, and restrict access with an OAC".
This is useful if you want to keep your bucket private. This would not work for multiple versions hosted in the same s3 bucket.`
}).option('noDefaultRootObject', {
type: 'boolean',
default: false,
describe: `Don't set the default route object to index.html.
This is useful if you want to host multiple versions of the app in the same s3 bucket.`
}).option('redirect403ToRoot', {
type: 'boolean',
default: false,
describe: `Redirect 403 errors to the root of the SPA.
This is useful if you want to use client-side routing with an S3 static website without using a hash router.`
}).option('objectExpirationDays', {
type: 'number',
default: undefined,
describe: `Add a lifecycle configuration to the bucket that clean object after X days.
This should be a valid, positive number. (ex: --objectExpirationDays 60).`,
coerce: arg => {
if (arg === undefined || arg === null) {
return null;
}
const numValue = Number(arg);
if (isNaN(numValue) || numValue <= 0) {
throw new Error('objectExpirationDays must be a valid positive number');
}
return numValue;
}
});
}, async argv => {
if (!argv.domainName) {
throw new Error('domainName must be provided');
}
try {
await (0, _deploy.deploy)(argv.domainName, argv.directory, argv.wait, argv.cacheInvalidation, argv.cacheBustedPrefix, argv.noPrompt, argv.shouldBlockBucketPublicAccess, argv.noDefaultRootObject, argv.redirect403ToRoot, argv.objectExpirationDays);
_logger.logger.info('✅ done!');
process.exit(0);
} catch (error) {
_logger.logger.error(`💥 ${error.message}`);
process.exit(1);
}
}).demandCommand().help().argv;