Skip to content

Commit

Permalink
Merge pull request #1 from jesuisBogdan/first-3-tasks
Browse files Browse the repository at this point in the history
First 4 tasks completed
  • Loading branch information
jesuisBogdan authored Mar 3, 2023
2 parents 7bc28f8 + f9bc2d1 commit 5d3e187
Show file tree
Hide file tree
Showing 106 changed files with 54,356 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .browserslistrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
> 1%
last 2 versions
not dead
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
vue.config.js
tests
38 changes: 38 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
module.exports = {
root: true,
env: {
node: true,
},
extends: [
"plugin:vue/essential",
"@vue/typescript/recommended",
'plugin:prettier/recommended',
"plugin:clean-regex/recommended",
],
parserOptions: {
parser: '@typescript-eslint/parser',
sourceType: 'module',
ecmaVersion: 2020,
},
plugins: [
"clean-regex"
],
rules: {
"no-return-await": "error",
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",

"@typescript-eslint/explicit-module-boundary-types": "off"
},
overrides: [
{
files: [
"**/__tests__/*.{j,t}s?(x)",
"**/tests/unit/**/*.spec.{j,t}s?(x)",
],
env: {
jest: true,
},
},
],
};
31 changes: 31 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Production
build
.serverless

# Dependencies
node_modules
/.pnp
.pnp.js

# Testing
/tests/e2e/videos/
/tests/e2e/screenshots/

# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
2 changes: 2 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# skip cypress install (if you would run tests - remove next line and npm i)
CYPRESS_INSTALL_BINARY=0
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build
tests
10 changes: 10 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"useTabs": true,
"printWidth": 80,
"tabWidth": 2,
"semi": true,
"singleQuote": true,
"endOfLine": "auto",
"trailingComma": "es5",
"arrowParens": "avoid"
}
151 changes: 151 additions & 0 deletions .serverless_plugins/serverless-single-page-app-plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
'use strict';

const spawnSync = require('child_process').spawnSync;

class ServerlessPlugin {
constructor(serverless, options) {
this.serverless = serverless;
this.options = options;
this.commands = {
syncToS3: {
usage: 'Deploys the `app` directory to your bucket',
lifecycleEvents: [
'sync',
],
},
domainInfo: {
usage: 'Fetches and prints out the deployed CloudFront domain names',
lifecycleEvents: [
'domainInfo',
],
},
invalidateCloudFrontCache: {
usage: 'Invalidates CloudFront cache',
lifecycleEvents: [
'invalidateCache',
],
},
};

this.hooks = {
'syncToS3:sync': this.syncDirectory.bind(this),
'domainInfo:domainInfo': this.domainInfo.bind(this),
'invalidateCloudFrontCache:invalidateCache': this.invalidateCache.bind(
this,
),
};
}

runAwsCommand(args) {
let command = 'aws';
if (this.serverless.variables.service.provider.region) {
command = `${command} --region ${this.serverless.variables.service.provider.region}`;
}
if (this.serverless.variables.service.provider.profile) {
command = `${command} --profile ${this.serverless.variables.service.provider.profile}`;
}
const result = spawnSync(command, args, { shell: true });
const stdout = result.stdout.toString();
const sterr = result.stderr.toString();
if (stdout) {
this.serverless.cli.log(stdout);
}
if (sterr) {
this.serverless.cli.log(sterr);
}

return { stdout, sterr };
}

// syncs the `app` directory to the provided bucket
syncDirectory() {
const s3Bucket = this.serverless.variables.service.custom.s3Bucket;
const buildFolder = this.serverless.variables.service.custom.client.distributionFolder;
const args = [
's3',
'sync',
`${buildFolder}/`,
`s3://${s3Bucket}/`,
'--delete',
];
const { sterr } = this.runAwsCommand(args);
if (!sterr) {
this.serverless.cli.log('Successfully synced to the S3 bucket');
} else {
throw new Error('Failed syncing to the S3 bucket');
}
}

// fetches the domain name from the CloudFront outputs and prints it out
async domainInfo() {
const provider = this.serverless.getProvider('aws');
const stackName = provider.naming.getStackName(this.options.stage);
const result = await provider.request(
'CloudFormation',
'describeStacks',
{ StackName: stackName },
this.options.stage,
this.options.region,
);

const outputs = result.Stacks[0].Outputs;
const output = outputs.find(
entry => entry.OutputKey === 'WebAppCloudFrontDistributionOutput',
);

if (output && output.OutputValue) {
this.serverless.cli.log(`Web App Domain: ${output.OutputValue}`);
return output.OutputValue;
}

this.serverless.cli.log('Web App Domain: Not Found');
const error = new Error('Could not extract Web App Domain');
throw error;
}

async invalidateCache() {
const provider = this.serverless.getProvider('aws');

const domain = await this.domainInfo();

const result = await provider.request(
'CloudFront',
'listDistributions',
{},
this.options.stage,
this.options.region,
);

const distributions = result.DistributionList.Items;
const distribution = distributions.find(
entry => entry.DomainName === domain,
);

if (distribution) {
this.serverless.cli.log(
`Invalidating CloudFront distribution with id: ${distribution.Id}`,
);
const args = [
'cloudfront',
'create-invalidation',
'--distribution-id',
distribution.Id,
'--paths',
'"/*"',
];
const { sterr } = this.runAwsCommand(args);
if (!sterr) {
this.serverless.cli.log('Successfully invalidated CloudFront cache');
} else {
throw new Error('Failed invalidating CloudFront cache');
}
} else {
const message = `Could not find distribution with domain ${domain}`;
const error = new Error(message);
this.serverless.cli.log(message);
throw error;
}
}
}

module.exports = ServerlessPlugin;
47 changes: 46 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,46 @@
# aws-frontend
# shop-vue-vuex-cloudfront

- [CloudFrontURL](https://d1tlahi24dm39c.cloudfront.net) page should load
- [S3-bucket-html](https://new-s3-shop-react-redux-cloudfront.s3.amazonaws.com/index.html) page should display Access Denied

See `develop` branch for development

## Project setup

```
npm install
```

### Compiles and hot-reloads for development

```
npm run serve
```

### Compiles and minifies for production

```
npm run build
```

### Run your unit tests

```
npm run test:unit
```

### Run your end-to-end tests

```
npm run test:e2e
```

### Lints and fixes files

```
npm run lint
```

### Customize configuration

See [Configuration Reference](https://cli.vuejs.org/config/).
3 changes: 3 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
presets: ["@vue/cli-plugin-babel/preset"],
};
3 changes: 3 additions & 0 deletions cypress.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"pluginsFile": "tests/e2e/plugins/index.js"
}
3 changes: 3 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
preset: "@vue/cli-plugin-unit-jest/presets/typescript-and-babel",
};
Loading

0 comments on commit 5d3e187

Please sign in to comment.