├── .DS_Store
├── .gitignore
├── animating-child-route
├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .postcssrc.js
├── README.md
├── build
│ ├── build.js
│ ├── check-versions.js
│ ├── logo.png
│ ├── utils.js
│ ├── vue-loader.conf.js
│ ├── webpack.base.conf.js
│ ├── webpack.dev.conf.js
│ └── webpack.prod.conf.js
├── config
│ ├── dev.env.js
│ ├── index.js
│ └── prod.env.js
├── index.html
├── package.json
├── src
│ ├── App.vue
│ ├── assets
│ │ └── logo.png
│ ├── components
│ │ ├── Modal.vue
│ │ ├── icons
│ │ │ ├── Close.vue
│ │ │ └── Delete.vue
│ │ └── pages
│ │ │ └── game
│ │ │ ├── List.vue
│ │ │ ├── Single.vue
│ │ │ └── rule
│ │ │ ├── List.vue
│ │ │ └── Single.vue
│ ├── data
│ │ └── games.js
│ ├── main.js
│ ├── router
│ │ └── index.js
│ └── styles
│ │ ├── _colors.scss
│ │ ├── base.scss
│ │ └── normalize.scss
├── static
│ └── .gitkeep
└── yarn.lock
├── docs
├── animating-child-route
│ ├── css
│ │ ├── app.5c2176ebe79045b522ab63a9a5ec9fdd.css
│ │ └── app.5c2176ebe79045b522ab63a9a5ec9fdd.css.map
│ ├── index.html
│ └── js
│ │ ├── app.b2e513a43e7dfc676b6b.js
│ │ ├── app.b2e513a43e7dfc676b6b.js.map
│ │ ├── manifest.1b8b88fb7a426a6d3f67.js
│ │ ├── manifest.1b8b88fb7a426a6d3f67.js.map
│ │ ├── vendor.be70c74316613424bdf6.js
│ │ └── vendor.be70c74316613424bdf6.js.map
├── index.html
├── sidebar-dynamic
│ ├── index.html
│ └── static
│ │ ├── css
│ │ ├── app.a1b9c94bdc470f5ed9184569e8cd64ea.css
│ │ └── app.a1b9c94bdc470f5ed9184569e8cd64ea.css.map
│ │ └── js
│ │ ├── app.cc4efbd447cb00403ba7.js
│ │ ├── app.cc4efbd447cb00403ba7.js.map
│ │ ├── manifest.ecfa1adc4a7519c26d6b.js
│ │ ├── manifest.ecfa1adc4a7519c26d6b.js.map
│ │ ├── vendor.59e1447691d6f3a63918.js
│ │ └── vendor.59e1447691d6f3a63918.js.map
└── sidebar
│ ├── index.html
│ └── static
│ ├── css
│ ├── app.e439c225a7a4e3d818fb42e3f740d862.css
│ └── app.e439c225a7a4e3d818fb42e3f740d862.css.map
│ └── js
│ ├── app.7e8ea3700ad2708b65ba.js
│ ├── app.7e8ea3700ad2708b65ba.js.map
│ ├── manifest.0dc805fcf281e9020471.js
│ ├── manifest.0dc805fcf281e9020471.js.map
│ ├── vendor.59e1447691d6f3a63918.js
│ └── vendor.59e1447691d6f3a63918.js.map
├── prisma-auth0
└── server
│ ├── .gitignore
│ ├── .graphqlconfig.yml
│ ├── README.md
│ ├── database
│ ├── datamodel.graphql
│ ├── prisma.yml
│ └── seed.graphql
│ ├── package.json
│ ├── src
│ ├── generated
│ │ └── prisma.graphql
│ ├── index.js
│ ├── resolvers
│ │ ├── AuthPayload.js
│ │ ├── Mutation
│ │ │ ├── auth.js
│ │ │ └── post.js
│ │ ├── Query.js
│ │ └── index.js
│ ├── schema.graphql
│ └── utils.js
│ └── yarn.lock
├── sidebar-dynamic
├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .postcssrc.js
├── README.md
├── build
│ ├── build.js
│ ├── check-versions.js
│ ├── logo.png
│ ├── utils.js
│ ├── vue-loader.conf.js
│ ├── webpack.base.conf.js
│ ├── webpack.dev.conf.js
│ ├── webpack.prod.conf.js
│ └── webpack.test.conf.js
├── config
│ ├── dev.env.js
│ ├── index.js
│ └── prod.env.js
├── index.html
├── package.json
├── src
│ ├── App.vue
│ ├── components
│ │ ├── addForm.vue
│ │ ├── searchForm.vue
│ │ ├── sidebar.vue
│ │ └── sidebarToggle.vue
│ ├── icons
│ │ ├── add.vue
│ │ └── search.vue
│ ├── main.js
│ └── store
│ │ ├── index.js
│ │ ├── modules
│ │ └── ui.js
│ │ └── mutation-types.js
├── static
│ └── .gitkeep
└── yarn.lock
├── sidebar
├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .postcssrc.js
├── README.md
├── build
│ ├── build.js
│ ├── check-versions.js
│ ├── logo.png
│ ├── utils.js
│ ├── vue-loader.conf.js
│ ├── webpack.base.conf.js
│ ├── webpack.dev.conf.js
│ ├── webpack.prod.conf.js
│ └── webpack.test.conf.js
├── config
│ ├── dev.env.js
│ ├── index.js
│ └── prod.env.js
├── index.html
├── package.json
├── src
│ ├── App.vue
│ ├── assets
│ │ └── logo.png
│ ├── components
│ │ ├── sidebar.vue
│ │ └── sidebarToggle.vue
│ ├── main.js
│ └── store
│ │ ├── index.js
│ │ ├── modules
│ │ └── ui.js
│ │ └── mutation-types.js
├── static
│ └── .gitkeep
└── yarn.lock
├── thumbnail-creator
├── .serverless
│ ├── cloudformation-template-create-stack.json
│ ├── cloudformation-template-update-stack.json
│ ├── serverless-state.json
│ └── thumbnail-creator.zip
├── README.md
├── client
│ ├── .babelrc
│ ├── .editorconfig
│ ├── .eslintignore
│ ├── .eslintrc.js
│ ├── .gitignore
│ ├── .postcssrc.js
│ ├── README.md
│ ├── build
│ │ ├── build.js
│ │ ├── check-versions.js
│ │ ├── logo.png
│ │ ├── utils.js
│ │ ├── vue-loader.conf.js
│ │ ├── webpack.base.conf.js
│ │ ├── webpack.dev.conf.js
│ │ └── webpack.prod.conf.js
│ ├── config
│ │ ├── dev.env.js
│ │ ├── index.js
│ │ └── prod.env.js
│ ├── index.html
│ ├── package.json
│ ├── src
│ │ ├── App.vue
│ │ ├── assets
│ │ │ └── logo.png
│ │ ├── aws.js
│ │ ├── components
│ │ │ ├── Home.vue
│ │ │ ├── appHeader.vue
│ │ │ ├── list.vue
│ │ │ ├── upload.vue
│ │ │ └── uploadForm.vue
│ │ ├── main.js
│ │ └── router
│ │ │ └── index.js
│ └── static
│ │ └── .gitkeep
├── handlers
│ ├── test.json
│ └── transform.js
├── package.json
├── serverless.yml
└── sharp
│ ├── Dockerfile
│ ├── build.sh
│ └── tarballs
│ └── sharp-0.18.4-aws-lambda-linux-x64-node-6.10.1.tar.gz
└── video-colors
├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .postcssrc.js
├── README.md
├── build
├── build.js
├── check-versions.js
├── logo.png
├── utils.js
├── vue-loader.conf.js
├── webpack.base.conf.js
├── webpack.dev.conf.js
└── webpack.prod.conf.js
├── config
├── dev.env.js
├── index.js
└── prod.env.js
├── index.html
├── package.json
├── src
├── App.vue
├── assets
│ ├── logo.png
│ └── test.mp4
├── chart.vue
├── main.js
└── worker.js
└── static
└── .gitkeep
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ramsaylanier/vue-tutorials/26cada54a6f81bc41c0fe786d1d278faf5431e10/.DS_Store
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | **/config/development.json
2 | **/config/production.json
3 | **/config/client.json
4 | **/dist
5 | node_modules
6 |
--------------------------------------------------------------------------------
/animating-child-route/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["env", {
4 | "modules": false,
5 | "targets": {
6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
7 | }
8 | }],
9 | "stage-2"
10 | ],
11 | "plugins": ["transform-vue-jsx", "transform-runtime"]
12 | }
13 |
--------------------------------------------------------------------------------
/animating-child-route/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/animating-child-route/.eslintignore:
--------------------------------------------------------------------------------
1 | /build/
2 | /config/
3 | /dist/
4 | /*.js
5 |
--------------------------------------------------------------------------------
/animating-child-route/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // https://eslint.org/docs/user-guide/configuring
2 |
3 | module.exports = {
4 | root: true,
5 | parserOptions: {
6 | parser: 'babel-eslint'
7 | },
8 | env: {
9 | browser: true,
10 | },
11 | extends: [
12 | // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
13 | // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
14 | 'plugin:vue/essential',
15 | // https://github.com/standard/standard/blob/master/docs/RULES-en.md
16 | 'standard'
17 | ],
18 | // required to lint *.vue files
19 | plugins: [
20 | 'vue'
21 | ],
22 | // add your custom rules here
23 | rules: {
24 | // allow async-await
25 | 'generator-star-spacing': 'off',
26 | // allow debugger during development
27 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/animating-child-route/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | /dist/
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Editor directories and files
9 | .idea
10 | .vscode
11 | *.suo
12 | *.ntvs*
13 | *.njsproj
14 | *.sln
15 |
--------------------------------------------------------------------------------
/animating-child-route/.postcssrc.js:
--------------------------------------------------------------------------------
1 | // https://github.com/michael-ciniawsky/postcss-load-config
2 |
3 | module.exports = {
4 | "plugins": {
5 | "postcss-import": {},
6 | "postcss-url": {},
7 | // to edit target browsers: use "browserslist" field in package.json
8 | "autoprefixer": {}
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/animating-child-route/README.md:
--------------------------------------------------------------------------------
1 | # animating-child-route
2 |
3 | > A Vue.js project
4 |
5 | ## Build Setup
6 |
7 | ``` bash
8 | # install dependencies
9 | npm install
10 |
11 | # serve with hot reload at localhost:8080
12 | npm run dev
13 |
14 | # build for production with minification
15 | npm run build
16 |
17 | # build for production and view the bundle analyzer report
18 | npm run build --report
19 | ```
20 |
21 | For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
22 |
--------------------------------------------------------------------------------
/animating-child-route/build/build.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | require('./check-versions')()
3 |
4 | process.env.NODE_ENV = 'production'
5 |
6 | const ora = require('ora')
7 | const rm = require('rimraf')
8 | const path = require('path')
9 | const chalk = require('chalk')
10 | const webpack = require('webpack')
11 | const config = require('../config')
12 | const webpackConfig = require('./webpack.prod.conf')
13 |
14 | const spinner = ora('building for production...')
15 | spinner.start()
16 |
17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
18 | if (err) throw err
19 | webpack(webpackConfig, (err, stats) => {
20 | spinner.stop()
21 | if (err) throw err
22 | process.stdout.write(stats.toString({
23 | colors: true,
24 | modules: false,
25 | children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
26 | chunks: false,
27 | chunkModules: false
28 | }) + '\n\n')
29 |
30 | if (stats.hasErrors()) {
31 | console.log(chalk.red(' Build failed with errors.\n'))
32 | process.exit(1)
33 | }
34 |
35 | console.log(chalk.cyan(' Build complete.\n'))
36 | console.log(chalk.yellow(
37 | ' Tip: built files are meant to be served over an HTTP server.\n' +
38 | ' Opening index.html over file:// won\'t work.\n'
39 | ))
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/animating-child-route/build/check-versions.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const chalk = require('chalk')
3 | const semver = require('semver')
4 | const packageConfig = require('../package.json')
5 | const shell = require('shelljs')
6 |
7 | function exec (cmd) {
8 | return require('child_process').execSync(cmd).toString().trim()
9 | }
10 |
11 | const versionRequirements = [
12 | {
13 | name: 'node',
14 | currentVersion: semver.clean(process.version),
15 | versionRequirement: packageConfig.engines.node
16 | }
17 | ]
18 |
19 | if (shell.which('npm')) {
20 | versionRequirements.push({
21 | name: 'npm',
22 | currentVersion: exec('npm --version'),
23 | versionRequirement: packageConfig.engines.npm
24 | })
25 | }
26 |
27 | module.exports = function () {
28 | const warnings = []
29 |
30 | for (let i = 0; i < versionRequirements.length; i++) {
31 | const mod = versionRequirements[i]
32 |
33 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
34 | warnings.push(mod.name + ': ' +
35 | chalk.red(mod.currentVersion) + ' should be ' +
36 | chalk.green(mod.versionRequirement)
37 | )
38 | }
39 | }
40 |
41 | if (warnings.length) {
42 | console.log('')
43 | console.log(chalk.yellow('To use this template, you must update following to modules:'))
44 | console.log()
45 |
46 | for (let i = 0; i < warnings.length; i++) {
47 | const warning = warnings[i]
48 | console.log(' ' + warning)
49 | }
50 |
51 | console.log()
52 | process.exit(1)
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/animating-child-route/build/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ramsaylanier/vue-tutorials/26cada54a6f81bc41c0fe786d1d278faf5431e10/animating-child-route/build/logo.png
--------------------------------------------------------------------------------
/animating-child-route/build/utils.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const config = require('../config')
4 | const ExtractTextPlugin = require('extract-text-webpack-plugin')
5 | const packageConfig = require('../package.json')
6 |
7 | exports.assetsPath = function (_path) {
8 | const assetsSubDirectory = process.env.NODE_ENV === 'production'
9 | ? config.build.assetsSubDirectory
10 | : config.dev.assetsSubDirectory
11 |
12 | return path.posix.join(assetsSubDirectory, _path)
13 | }
14 |
15 | exports.cssLoaders = function (options) {
16 | options = options || {}
17 |
18 | const cssLoader = {
19 | loader: 'css-loader',
20 | options: {
21 | sourceMap: options.sourceMap
22 | }
23 | }
24 |
25 | const postcssLoader = {
26 | loader: 'postcss-loader',
27 | options: {
28 | sourceMap: options.sourceMap
29 | }
30 | }
31 |
32 | // generate loader string to be used with extract text plugin
33 | function generateLoaders (loader, loaderOptions) {
34 | const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
35 |
36 | if (loader) {
37 | loaders.push({
38 | loader: loader + '-loader',
39 | options: Object.assign({}, loaderOptions, {
40 | sourceMap: options.sourceMap
41 | })
42 | })
43 | }
44 |
45 | // Extract CSS when that option is specified
46 | // (which is the case during production build)
47 | if (options.extract) {
48 | return ExtractTextPlugin.extract({
49 | use: loaders,
50 | fallback: 'vue-style-loader'
51 | })
52 | } else {
53 | return ['vue-style-loader'].concat(loaders)
54 | }
55 | }
56 |
57 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html
58 | return {
59 | css: generateLoaders(),
60 | postcss: generateLoaders(),
61 | less: generateLoaders('less'),
62 | sass: generateLoaders('sass', { indentedSyntax: true }),
63 | scss: generateLoaders('sass'),
64 | stylus: generateLoaders('stylus'),
65 | styl: generateLoaders('stylus')
66 | }
67 | }
68 |
69 | // Generate loaders for standalone style files (outside of .vue)
70 | exports.styleLoaders = function (options) {
71 | const output = []
72 | const loaders = exports.cssLoaders(options)
73 |
74 | for (const extension in loaders) {
75 | const loader = loaders[extension]
76 | output.push({
77 | test: new RegExp('\\.' + extension + '$'),
78 | use: loader
79 | })
80 | }
81 |
82 | return output
83 | }
84 |
85 | exports.createNotifierCallback = () => {
86 | const notifier = require('node-notifier')
87 |
88 | return (severity, errors) => {
89 | if (severity !== 'error') return
90 |
91 | const error = errors[0]
92 | const filename = error.file && error.file.split('!').pop()
93 |
94 | notifier.notify({
95 | title: packageConfig.name,
96 | message: severity + ': ' + error.name,
97 | subtitle: filename || '',
98 | icon: path.join(__dirname, 'logo.png')
99 | })
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/animating-child-route/build/vue-loader.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const utils = require('./utils')
3 | const config = require('../config')
4 | const isProduction = process.env.NODE_ENV === 'production'
5 | const sourceMapEnabled = isProduction
6 | ? config.build.productionSourceMap
7 | : config.dev.cssSourceMap
8 |
9 | module.exports = {
10 | loaders: utils.cssLoaders({
11 | sourceMap: sourceMapEnabled,
12 | extract: isProduction
13 | }),
14 | cssSourceMap: sourceMapEnabled,
15 | cacheBusting: config.dev.cacheBusting,
16 | transformToRequire: {
17 | video: ['src', 'poster'],
18 | source: 'src',
19 | img: 'src',
20 | image: 'xlink:href'
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/animating-child-route/build/webpack.base.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const utils = require('./utils')
4 | const config = require('../config')
5 | const vueLoaderConfig = require('./vue-loader.conf')
6 |
7 | function resolve (dir) {
8 | return path.join(__dirname, '..', dir)
9 | }
10 |
11 | const createLintingRule = () => ({
12 | test: /\.(js|vue)$/,
13 | loader: 'eslint-loader',
14 | enforce: 'pre',
15 | include: [resolve('src'), resolve('test')],
16 | options: {
17 | formatter: require('eslint-friendly-formatter'),
18 | emitWarning: !config.dev.showEslintErrorsInOverlay
19 | }
20 | })
21 |
22 | module.exports = {
23 | context: path.resolve(__dirname, '../'),
24 | entry: {
25 | app: './src/main.js'
26 | },
27 | output: {
28 | path: config.build.assetsRoot,
29 | filename: '[name].js',
30 | publicPath: process.env.NODE_ENV === 'production'
31 | ? config.build.assetsPublicPath
32 | : config.dev.assetsPublicPath
33 | },
34 | resolve: {
35 | extensions: ['.js', '.vue', '.json'],
36 | alias: {
37 | 'vue$': 'vue/dist/vue.esm.js',
38 | '@': resolve('src'),
39 | }
40 | },
41 | module: {
42 | rules: [
43 | ...(config.dev.useEslint ? [createLintingRule()] : []),
44 | {
45 | test: /\.vue$/,
46 | loader: 'vue-loader',
47 | options: vueLoaderConfig
48 | },
49 | {
50 | test: /\.js$/,
51 | loader: 'babel-loader',
52 | include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
53 | },
54 | {
55 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
56 | loader: 'url-loader',
57 | options: {
58 | limit: 10000,
59 | name: utils.assetsPath('img/[name].[hash:7].[ext]')
60 | }
61 | },
62 | {
63 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
64 | loader: 'url-loader',
65 | options: {
66 | limit: 10000,
67 | name: utils.assetsPath('media/[name].[hash:7].[ext]')
68 | }
69 | },
70 | {
71 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
72 | loader: 'url-loader',
73 | options: {
74 | limit: 10000,
75 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
76 | }
77 | }
78 | ]
79 | },
80 | node: {
81 | // prevent webpack from injecting useless setImmediate polyfill because Vue
82 | // source contains it (although only uses it if it's native).
83 | setImmediate: false,
84 | // prevent webpack from injecting mocks to Node native modules
85 | // that does not make sense for the client
86 | dgram: 'empty',
87 | fs: 'empty',
88 | net: 'empty',
89 | tls: 'empty',
90 | child_process: 'empty'
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/animating-child-route/build/webpack.dev.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const utils = require('./utils')
3 | const webpack = require('webpack')
4 | const config = require('../config')
5 | const merge = require('webpack-merge')
6 | const path = require('path')
7 | const baseWebpackConfig = require('./webpack.base.conf')
8 | const CopyWebpackPlugin = require('copy-webpack-plugin')
9 | const HtmlWebpackPlugin = require('html-webpack-plugin')
10 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
11 | const portfinder = require('portfinder')
12 |
13 | const HOST = process.env.HOST
14 | const PORT = process.env.PORT && Number(process.env.PORT)
15 |
16 | const devWebpackConfig = merge(baseWebpackConfig, {
17 | module: {
18 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
19 | },
20 | // cheap-module-eval-source-map is faster for development
21 | devtool: config.dev.devtool,
22 |
23 | // these devServer options should be customized in /config/index.js
24 | devServer: {
25 | clientLogLevel: 'warning',
26 | historyApiFallback: {
27 | rewrites: [
28 | { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
29 | ],
30 | },
31 | hot: true,
32 | contentBase: false, // since we use CopyWebpackPlugin.
33 | compress: true,
34 | host: HOST || config.dev.host,
35 | port: PORT || config.dev.port,
36 | open: config.dev.autoOpenBrowser,
37 | overlay: config.dev.errorOverlay
38 | ? { warnings: false, errors: true }
39 | : false,
40 | publicPath: config.dev.assetsPublicPath,
41 | proxy: config.dev.proxyTable,
42 | quiet: true, // necessary for FriendlyErrorsPlugin
43 | watchOptions: {
44 | poll: config.dev.poll,
45 | }
46 | },
47 | plugins: [
48 | new webpack.DefinePlugin({
49 | 'process.env': require('../config/dev.env')
50 | }),
51 | new webpack.HotModuleReplacementPlugin(),
52 | new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
53 | new webpack.NoEmitOnErrorsPlugin(),
54 | // https://github.com/ampedandwired/html-webpack-plugin
55 | new HtmlWebpackPlugin({
56 | filename: 'index.html',
57 | template: 'index.html',
58 | inject: true
59 | }),
60 | // copy custom static assets
61 | new CopyWebpackPlugin([
62 | {
63 | from: path.resolve(__dirname, '../static'),
64 | to: config.dev.assetsSubDirectory,
65 | ignore: ['.*']
66 | }
67 | ])
68 | ]
69 | })
70 |
71 | module.exports = new Promise((resolve, reject) => {
72 | portfinder.basePort = process.env.PORT || config.dev.port
73 | portfinder.getPort((err, port) => {
74 | if (err) {
75 | reject(err)
76 | } else {
77 | // publish the new Port, necessary for e2e tests
78 | process.env.PORT = port
79 | // add port to devServer config
80 | devWebpackConfig.devServer.port = port
81 |
82 | // Add FriendlyErrorsPlugin
83 | devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
84 | compilationSuccessInfo: {
85 | messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
86 | },
87 | onErrors: config.dev.notifyOnErrors
88 | ? utils.createNotifierCallback()
89 | : undefined
90 | }))
91 |
92 | resolve(devWebpackConfig)
93 | }
94 | })
95 | })
96 |
--------------------------------------------------------------------------------
/animating-child-route/config/dev.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const merge = require('webpack-merge')
3 | const prodEnv = require('./prod.env')
4 |
5 | module.exports = merge(prodEnv, {
6 | NODE_ENV: '"development"'
7 | })
8 |
--------------------------------------------------------------------------------
/animating-child-route/config/index.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | // Template version: 1.3.1
3 | // see http://vuejs-templates.github.io/webpack for documentation.
4 |
5 | const path = require('path')
6 |
7 | module.exports = {
8 | dev: {
9 |
10 | // Paths
11 | assetsSubDirectory: 'static',
12 | assetsPublicPath: '/',
13 | proxyTable: {},
14 |
15 | // Various Dev Server settings
16 | host: 'localhost', // can be overwritten by process.env.HOST
17 | port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
18 | autoOpenBrowser: false,
19 | errorOverlay: true,
20 | notifyOnErrors: true,
21 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
22 |
23 | // Use Eslint Loader?
24 | // If true, your code will be linted during bundling and
25 | // linting errors and warnings will be shown in the console.
26 | useEslint: true,
27 | // If true, eslint errors and warnings will also be shown in the error overlay
28 | // in the browser.
29 | showEslintErrorsInOverlay: false,
30 |
31 | /**
32 | * Source Maps
33 | */
34 |
35 | // https://webpack.js.org/configuration/devtool/#development
36 | devtool: 'cheap-module-eval-source-map',
37 |
38 | // If you have problems debugging vue-files in devtools,
39 | // set this to false - it *may* help
40 | // https://vue-loader.vuejs.org/en/options.html#cachebusting
41 | cacheBusting: true,
42 |
43 | cssSourceMap: true
44 | },
45 |
46 | build: {
47 | // Template for index.html
48 | index: path.resolve(__dirname, '../docs/index.html'),
49 |
50 | // Paths
51 | assetsRoot: path.resolve(__dirname, '../docs'),
52 | assetsSubDirectory: '',
53 | assetsPublicPath: '',
54 |
55 | /**
56 | * Source Maps
57 | */
58 |
59 | productionSourceMap: true,
60 | // https://webpack.js.org/configuration/devtool/#production
61 | devtool: '#source-map',
62 |
63 | // Gzip off by default as many popular static hosts such as
64 | // Surge or Netlify already gzip all static assets for you.
65 | // Before setting to `true`, make sure to:
66 | // npm install --save-dev compression-webpack-plugin
67 | productionGzip: false,
68 | productionGzipExtensions: ['js', 'css'],
69 |
70 | // Run the build command with an extra argument to
71 | // View the bundle analyzer report after build finishes:
72 | // `npm run build --report`
73 | // Set to `true` or `false` to always turn it on or off
74 | bundleAnalyzerReport: process.env.npm_config_report
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/animating-child-route/config/prod.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | module.exports = {
3 | NODE_ENV: '"production"'
4 | }
5 |
--------------------------------------------------------------------------------
/animating-child-route/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | animating-child-route
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/animating-child-route/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "animating-child-route",
3 | "version": "1.0.0",
4 | "description": "A Vue.js project",
5 | "author": "",
6 | "private": true,
7 | "scripts": {
8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
9 | "start": "npm run dev",
10 | "lint": "eslint --ext .js,.vue src",
11 | "build": "node build/build.js"
12 | },
13 | "dependencies": {
14 | "gsap": "^1.20.3",
15 | "node-sass": "^4.7.2",
16 | "sass-loader": "^6.0.6",
17 | "vue": "^2.5.2",
18 | "vue-router": "^3.0.1"
19 | },
20 | "devDependencies": {
21 | "autoprefixer": "^7.1.2",
22 | "babel-core": "^6.22.1",
23 | "babel-eslint": "^8.2.1",
24 | "babel-helper-vue-jsx-merge-props": "^2.0.3",
25 | "babel-loader": "^7.1.1",
26 | "babel-plugin-syntax-jsx": "^6.18.0",
27 | "babel-plugin-transform-runtime": "^6.22.0",
28 | "babel-plugin-transform-vue-jsx": "^3.5.0",
29 | "babel-preset-env": "^1.3.2",
30 | "babel-preset-stage-2": "^6.22.0",
31 | "chalk": "^2.0.1",
32 | "copy-webpack-plugin": "^4.0.1",
33 | "css-loader": "^0.28.0",
34 | "eslint": "^4.15.0",
35 | "eslint-config-standard": "^10.2.1",
36 | "eslint-friendly-formatter": "^3.0.0",
37 | "eslint-loader": "^1.7.1",
38 | "eslint-plugin-import": "^2.7.0",
39 | "eslint-plugin-node": "^5.2.0",
40 | "eslint-plugin-promise": "^3.4.0",
41 | "eslint-plugin-standard": "^3.0.1",
42 | "eslint-plugin-vue": "^4.0.0",
43 | "extract-text-webpack-plugin": "^3.0.0",
44 | "file-loader": "^1.1.4",
45 | "friendly-errors-webpack-plugin": "^1.6.1",
46 | "html-webpack-plugin": "^2.30.1",
47 | "node-notifier": "^5.1.2",
48 | "optimize-css-assets-webpack-plugin": "^3.2.0",
49 | "ora": "^1.2.0",
50 | "portfinder": "^1.0.13",
51 | "postcss-import": "^11.0.0",
52 | "postcss-loader": "^2.0.8",
53 | "postcss-url": "^7.2.1",
54 | "rimraf": "^2.6.0",
55 | "semver": "^5.3.0",
56 | "shelljs": "^0.7.6",
57 | "uglifyjs-webpack-plugin": "^1.1.1",
58 | "url-loader": "^0.5.8",
59 | "vue-loader": "^13.3.0",
60 | "vue-style-loader": "^3.0.1",
61 | "vue-template-compiler": "^2.5.2",
62 | "webpack": "^3.6.0",
63 | "webpack-bundle-analyzer": "^2.9.0",
64 | "webpack-dev-server": "^2.9.1",
65 | "webpack-merge": "^4.1.0"
66 | },
67 | "engines": {
68 | "node": ">= 6.0.0",
69 | "npm": ">= 3.0.0"
70 | },
71 | "browserslist": [
72 | "> 1%",
73 | "last 2 versions",
74 | "not ie <= 8"
75 | ]
76 | }
77 |
--------------------------------------------------------------------------------
/animating-child-route/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
28 |
--------------------------------------------------------------------------------
/animating-child-route/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ramsaylanier/vue-tutorials/26cada54a6f81bc41c0fe786d1d278faf5431e10/animating-child-route/src/assets/logo.png
--------------------------------------------------------------------------------
/animating-child-route/src/components/Modal.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
14 |
15 |
16 |
17 |
47 |
48 |
89 |
--------------------------------------------------------------------------------
/animating-child-route/src/components/icons/Close.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
14 |
15 |
18 |
--------------------------------------------------------------------------------
/animating-child-route/src/components/icons/Delete.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
13 |
14 |
17 |
--------------------------------------------------------------------------------
/animating-child-route/src/components/pages/game/List.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Games
5 |
6 |
7 |
8 | {{game.title}}
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
27 |
28 |
79 |
--------------------------------------------------------------------------------
/animating-child-route/src/components/pages/game/Single.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
42 |
43 |
67 |
--------------------------------------------------------------------------------
/animating-child-route/src/components/pages/game/rule/List.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Rules
4 |
5 |
6 |
7 | {{excerpt(rule.text)}}
8 |
9 |
10 |
11 |
12 |
13 |
14 |
31 |
32 |
69 |
--------------------------------------------------------------------------------
/animating-child-route/src/components/pages/game/rule/Single.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
31 |
32 |
82 |
--------------------------------------------------------------------------------
/animating-child-route/src/main.js:
--------------------------------------------------------------------------------
1 | // The Vue build version to load with the `import` command
2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
3 | import Vue from 'vue'
4 | import App from './App'
5 | import router from './router'
6 |
7 | Vue.config.productionTip = false
8 |
9 | /* eslint-disable no-new */
10 | new Vue({
11 | el: '#app',
12 | router,
13 | components: { App },
14 | template: ' '
15 | })
16 |
--------------------------------------------------------------------------------
/animating-child-route/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 | import GameList from '@/components/pages/game/List.vue'
4 | import GameSingle from '@/components/pages/game/Single.vue'
5 | import RuleList from '@/components/pages/game/rule/List.vue'
6 | import RuleSingle from '@/components/pages/game/rule/Single.vue'
7 |
8 | Vue.use(Router)
9 |
10 | export default new Router({
11 | routes: [
12 | {
13 | path: '/',
14 | component: GameList
15 | },
16 | {
17 | path: '/game/:id',
18 | name: 'Game',
19 | component: GameSingle,
20 | children: [
21 | {
22 | path: 'rules',
23 | name: 'Game Rules',
24 | components: {
25 | page: RuleList
26 | },
27 | meta: {
28 | showModal: false
29 | }
30 | },
31 | {
32 | path: 'rules/:ruleId',
33 | name: 'Game Rule',
34 | components: {
35 | page: RuleList,
36 | rule: RuleSingle
37 | },
38 | meta: {
39 | showModal: true
40 | }
41 | }
42 | ]
43 | }
44 | ]
45 | })
46 |
--------------------------------------------------------------------------------
/animating-child-route/src/styles/_colors.scss:
--------------------------------------------------------------------------------
1 | $primary: #f26f4d;
2 | $secondary: #8471b3;
3 |
4 | $page-gradient: linear-gradient(-200deg, $primary 40%, adjust-hue($primary, -5%) 80%);
5 | $profile-gradient: linear-gradient(180deg, $secondary 0%, adjust-hue($secondary, -10%) 100%);
6 | $submit-gradient: linear-gradient(-200deg, $secondary 0%, adjust-hue($secondary, -40%) 100%);
--------------------------------------------------------------------------------
/animating-child-route/src/styles/base.scss:
--------------------------------------------------------------------------------
1 | @import "./_colors.scss";
2 |
3 | .page{
4 | background-image: $page-gradient;
5 | min-height: 100vh;
6 | padding: 1rem;
7 | }
--------------------------------------------------------------------------------
/animating-child-route/static/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ramsaylanier/vue-tutorials/26cada54a6f81bc41c0fe786d1d278faf5431e10/animating-child-route/static/.gitkeep
--------------------------------------------------------------------------------
/docs/animating-child-route/css/app.5c2176ebe79045b522ab63a9a5ec9fdd.css:
--------------------------------------------------------------------------------
1 | @import url(https://fonts.googleapis.com/css?family=Rubik:400,700);
2 | /*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:inherit;font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}[hidden],template{display:none}.page{background-image:linear-gradient(-200deg,#f26f4d 40%,#f2614d 80%);min-height:100vh;padding:1rem}#app{font-family:Rubik,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}*{box-sizing:border-box}.body[data-v-9555ea32],.page[data-v-9555ea32]{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.body[data-v-9555ea32]{padding:0;-ms-flex-flow:column;flex-flow:column;background-color:#fff;padding:2rem}.title[data-v-9555ea32]{font-size:3rem;font-weight:100}.list[data-v-9555ea32]{list-style:none;padding:0;margin:0}.list-item[data-v-9555ea32]:not(:last-of-type){margin-bottom:.5rem}.link[data-v-9555ea32]{background-color:#f26f4d;display:block;padding:1rem;color:#fff;font-size:1.5rem;text-decoration:none;border-radius:3px}.link[data-v-9555ea32]:hover{background-color:#8471b3}.page[data-v-7f60e7da]{padding:0}.header[data-v-7f60e7da]{background-color:#fff;padding:1rem;text-align:center}.wrapper[data-v-7f60e7da]{max-width:800px;margin:0 auto}.title[data-v-7f60e7da]{font-size:3rem;font-weight:100;color:#f26f4d}.modal[data-v-632b7e47]{position:fixed;top:0;left:0;height:100vh;width:100vw;background-color:rgba(0,0,0,.8);display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.inner[data-v-632b7e47]{background-color:#fff;width:800px;position:relative}.close-button[data-v-632b7e47]{position:absolute;top:-40px;right:0;border:0;height:40px;width:40px;background-color:#f2f2f2;cursor:pointer;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.close-button svg[data-v-632b7e47]{width:30px;height:30px}.title[data-v-6652bc69]{font-size:2rem;color:#fff;font-weight:100;margin:2rem 0}.list[data-v-6652bc69]{list-style:none;padding:0;margin:0}.list-item[data-v-6652bc69]:not(:last-of-type){margin-bottom:.5rem}.link[data-v-6652bc69]{display:block;padding:1rem;color:#f26f4d;font-size:1.2rem;text-decoration:none;border-radius:3px;background-color:#fff}.link[data-v-6652bc69]:hover{background-color:#8471b3;color:#fff}.rule[data-v-4436bdc1]{height:100%;background-color:#f2f2f2;position:relative}.body[data-v-4436bdc1]{padding:2rem;background-color:#fff}.text[data-v-4436bdc1]{margin:0;font-size:1.5rem;line-height:1.5}.menu[data-v-4436bdc1]{position:absolute;bottom:-1rem;left:0}.menu ul[data-v-4436bdc1]{list-style:none;padding:0;margin:0}.menu button[data-v-4436bdc1]{position:absolute;bottom:-4rem;left:0;border:0;height:4rem;width:4rem;background-color:#8471b3;cursor:pointer;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.menu button svg[data-v-4436bdc1]{width:30px;height:30px}
3 | /*# sourceMappingURL=app.5c2176ebe79045b522ab63a9a5ec9fdd.css.map */
--------------------------------------------------------------------------------
/docs/animating-child-route/index.html:
--------------------------------------------------------------------------------
1 | animating-child-route
--------------------------------------------------------------------------------
/docs/animating-child-route/js/manifest.1b8b88fb7a426a6d3f67.js:
--------------------------------------------------------------------------------
1 | !function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,c,u){for(var a,i,f,s=0,l=[];s
2 |
3 |
4 |
5 |
6 |
7 | Vue Tutorial Examples
8 |
9 |
45 |
46 |
47 |
48 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/docs/sidebar-dynamic/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Dynamic Sidebar
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/docs/sidebar-dynamic/static/css/app.a1b9c94bdc470f5ed9184569e8cd64ea.css:
--------------------------------------------------------------------------------
1 | :root{--accent-color:#ffcb08;--primary-color:#820263;--dark-color:#2e294e}*{box-sizing:border-box}._1yQEW-OB4Ybyf_vE6oWyGO_1{position:fixed;left:0;top:0;height:100vh;width:100vw;background-color:var(--primary-color)}.d_6wpGL-HDubyTBE0M-h8_1{position:fixed;right:1rem;bottom:1rem;display:-ms-flexbox;display:flex}._1Akv3QSGkfLjHLmQBua5gq_0{position:fixed;right:0;top:0;width:300px;height:100vh;max-width:90vw;background-color:var(--accent-color);padding:1rem}._2lbLj0f9KsKJTS3AY46M7w_0{padding:0;height:50px;width:50px;border:3px solid transparent;border-radius:50%;background-color:transparent;color:var(--dark-color);cursor:pointer;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;line-height:0;transition:transform .3s ease-out,border-color .3s ease-out}._2lbLj0f9KsKJTS3AY46M7w_0 svg{height:100%;width:100%;fill:var(--accent-color);transition:fill .3s ease-out}._2lbLj0f9KsKJTS3AY46M7w_0:focus{outline:none;border-color:var(--accent-color)}.n02dqwlexV56EeqjpzyEx_0{transform:rotate(45deg)}.n02dqwlexV56EeqjpzyEx_0 svg{fill:var(--primary-color)}.n02dqwlexV56EeqjpzyEx_0:focus{border-color:var(--primary-color)}._3-2e6nsGqNdlimbojUKT1s_0,.pugt3ynvQ0eZJzxl6baou_0{font-size:3rem;color:#fff;font-family:roboto}
2 | /*# sourceMappingURL=app.a1b9c94bdc470f5ed9184569e8cd64ea.css.map */
--------------------------------------------------------------------------------
/docs/sidebar-dynamic/static/css/app.a1b9c94bdc470f5ed9184569e8cd64ea.css.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["app.a1b9c94bdc470f5ed9184569e8cd64ea.css"],"names":[],"mappings":"AACA,MACE,uBAAwB,AACxB,wBAAyB,AACzB,oBAAsB,CACvB,AACD,EAEU,qBAAuB,CAChC,AAGD,2BACE,eAAgB,AAChB,OAAQ,AACR,MAAO,AACP,aAAc,AACd,YAAa,AACb,qCAAuC,CACxC,AACD,yBACE,eAAgB,AAChB,WAAY,AACZ,YAAa,AAEb,oBAAqB,AACrB,YAAc,CACf,AAED,2BACE,eAAgB,AAChB,QAAS,AACT,MAAO,AACP,YAAa,AACb,aAAc,AACd,eAAgB,AAChB,qCAAsC,AACtC,YAAc,CACf,AAED,2BACE,UAAW,AACX,YAAa,AACb,WAAY,AACZ,6BAA8B,AAC9B,kBAAmB,AACnB,6BAA8B,AAC9B,wBAAyB,AACzB,eAAgB,AAEhB,oBAAqB,AACrB,aAAc,AAEV,sBAAuB,AACnB,mBAAoB,AAExB,qBAAsB,AAClB,uBAAwB,AAChC,cAAe,AAGf,2DAAkE,CAEnE,AACD,+BACE,YAAa,AACb,WAAY,AACZ,yBAA0B,AAE1B,4BAAgC,CACjC,AACD,iCACE,aAAc,AACd,gCAAkC,CACnC,AACD,yBAEU,uBAAyB,CAClC,AACD,6BACE,yBAA2B,CAC5B,AACD,+BACE,iCAAmC,CACpC,AASD,oDACE,eAAgB,AAChB,WAAa,AACb,kBAAsB,CACvB","file":"app.a1b9c94bdc470f5ed9184569e8cd64ea.css","sourcesContent":["\n:root{\n --accent-color: #FFCB08;\n --primary-color: #820263;\n --dark-color: #2E294E;\n}\n*{\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n}\n\n\n._1yQEW-OB4Ybyf_vE6oWyGO_1{\n position: fixed;\n left: 0;\n top: 0;\n height: 100vh;\n width: 100vw;\n background-color: var(--primary-color);\n}\n.d_6wpGL-HDubyTBE0M-h8_1{\n position: fixed;\n right: 1rem;\n bottom: 1rem;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n}\n\n._1Akv3QSGkfLjHLmQBua5gq_0{\n position: fixed;\n right: 0;\n top: 0;\n width: 300px;\n height: 100vh;\n max-width: 90vw;\n background-color: var(--accent-color);\n padding: 1rem;\n}\n\n._2lbLj0f9KsKJTS3AY46M7w_0{\n padding: 0;\n height: 50px;\n width: 50px;\n border: 3px solid transparent;\n border-radius: 50%;\n background-color: transparent;\n color: var(--dark-color);\n cursor: pointer;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n -webkit-box-pack: center;\n -ms-flex-pack: center;\n justify-content: center;\n line-height: 0;\n -webkit-transition: border-color 300ms ease-out, -webkit-transform 300ms ease-out;\n transition: border-color 300ms ease-out, -webkit-transform 300ms ease-out;\n transition: transform 300ms ease-out, border-color 300ms ease-out;\n transition: transform 300ms ease-out, border-color 300ms ease-out, -webkit-transform 300ms ease-out;\n}\n._2lbLj0f9KsKJTS3AY46M7w_0 svg{\n height: 100%;\n width: 100%;\n fill: var(--accent-color);\n -webkit-transition: fill 300ms ease-out;\n transition: fill 300ms ease-out;\n}\n._2lbLj0f9KsKJTS3AY46M7w_0:focus{\n outline: none;\n border-color: var(--accent-color);\n}\n.n02dqwlexV56EeqjpzyEx_0{\n -webkit-transform: rotate(45deg);\n transform: rotate(45deg);\n}\n.n02dqwlexV56EeqjpzyEx_0 svg{\n fill: var(--primary-color);\n}\n.n02dqwlexV56EeqjpzyEx_0:focus{\n border-color: var(--primary-color);\n}\n\n\n.pugt3ynvQ0eZJzxl6baou_0{\n font-size: 3rem;\n color: white;\n font-family: 'roboto';\n}\n\n._3-2e6nsGqNdlimbojUKT1s_0{\n font-size: 3rem;\n color: white;\n font-family: 'roboto';\n}\n"]}
--------------------------------------------------------------------------------
/docs/sidebar-dynamic/static/js/app.cc4efbd447cb00403ba7.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([1],{"1GX7":function(e,t){e.exports={button:"_2lbLj0f9KsKJTS3AY46M7w_0",active:"n02dqwlexV56EeqjpzyEx_0"}},"32HJ":function(e,t){e.exports={title:"_3-2e6nsGqNdlimbojUKT1s_0"}},"7jBf":function(e,t){e.exports={container:"_1yQEW-OB4Ybyf_vE6oWyGO_1",toggles:"d_6wpGL-HDubyTBE0M-h8_1"}},EZew:function(e,t){e.exports={title:"pugt3ynvQ0eZJzxl6baou_0"}},NHnr:function(e,t,n){"use strict";function s(e){this.$style=n("wpMw")}function r(e){this.$style=n("1GX7")}function o(e){this.$style=n("EZew")}function i(e){this.$style=n("32HJ")}function a(e){n("z8r5"),this.$style=n("7jBf")}Object.defineProperty(t,"__esModule",{value:!0});var l,c=n("7+uW"),u=n("+Uzz"),d={name:"sidebar",mounted:function(){u.TweenMax.set(this.$el,{x:this.$el.offsetWidth})},computed:{open:function(){return this.$store.state.ui.sidebarOpen},component:function(){return this.$store.state.ui.sidebarComponent}},watch:{open:function(e){var t=e?0:this.$el.offsetWidth;u.TweenMax.to(this.$el,.6,{x:t,ease:u.Power4.easeOut})}}},p=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{class:e.$style.sidebar},[n(e.component,{tag:"component"})],1)},h=[],m={render:p,staticRenderFns:h},f=m,v=n("VU/8"),_=s,b=v(d,f,!1,_,null,null),g=b.exports,w={name:"sidebar-toggle",props:["sidebarComponent","icon"],computed:{open:function(){return this.$store.state.ui.sidebarOpen&&this.$store.state.ui.sidebarComponent===this.sidebarComponent}},methods:{handleClick:function(){this.$store.dispatch("toggleSidebar",{component:this.sidebarComponent})}}},$=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("button",{class:[e.open?e.$style.active:"",e.$style.button],on:{click:e.handleClick}},[n(e.icon,{tag:"component"})],1)},x=[],E={render:$,staticRenderFns:x},y=E,O=n("VU/8"),C=r,S=O(w,y,!1,C,null,null),F=S.exports,M={name:"add-form"},T=function(){var e=this,t=e.$createElement;return(e._self._c||t)("h3",{class:e.$style.title},[e._v("Add Form")])},z=[],B={render:T,staticRenderFns:z},R=B,G=n("VU/8"),A=o,H=G(M,R,!1,A,null,null),I=H.exports,U={name:"search-form"},V=function(){var e=this,t=e.$createElement;return(e._self._c||t)("h3",{class:e.$style.title},[e._v("Search Form")])},N=[],j={render:V,staticRenderFns:N},L=j,k=n("VU/8"),D=i,J=k(U,L,!1,D,null,null),W=J.exports,q={name:"search-icon"},P=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("svg",{attrs:{fill:"#000000",height:"24",viewBox:"0 0 24 24",width:"24",xmlns:"http://www.w3.org/2000/svg"}},[n("path",{attrs:{d:"M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"}}),e._v(" "),n("path",{attrs:{d:"M0 0h24v24H0z",fill:"none"}})])},Q=[],K={render:P,staticRenderFns:Q},Y=K,Z=n("VU/8"),X=Z(q,Y,!1,null,null,null),ee=X.exports,te={name:"search-icon"},ne=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("svg",{attrs:{fill:"#000000",height:"24",viewBox:"0 0 24 24",width:"24",xmlns:"http://www.w3.org/2000/svg"}},[n("path",{attrs:{d:"M0 0h24v24H0z",fill:"none"}}),e._v(" "),n("path",{attrs:{d:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z"}})])},se=[],re={render:ne,staticRenderFns:se},oe=re,ie=n("VU/8"),ae=ie(te,oe,!1,null,null,null),le=ae.exports,ce={name:"app",components:{Sidebar:g,SidebarToggle:F},data:function(){return{addForm:I,searchForm:W,searchIcon:ee,addIcon:le}}},ue=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{attrs:{id:"app"}},[n("div",{class:e.$style.container}),e._v(" "),n("sidebar"),e._v(" "),n("div",{class:e.$style.toggles},[n("sidebar-toggle",{attrs:{sidebarComponent:e.addForm,icon:e.searchIcon}}),e._v(" "),n("sidebar-toggle",{attrs:{sidebarComponent:e.searchForm,icon:e.addIcon}})],1)],1)},de=[],pe={render:ue,staticRenderFns:de},he=pe,me=n("VU/8"),fe=a,ve=me(ce,he,!1,fe,null,null),_e=ve.exports,be=n("NYxO"),ge=n("bOdI"),we=n.n(ge),$e={sidebarOpen:!1,sidebarComponent:null},xe={sidebarOpen:function(e){return e.sidebarOpen},sidebarComponent:function(e){return e.sidebarComponent}},Ee={toggleSidebar:function(e,t){var n=e.commit,s=(e.state,t.component);n("TOGGLE_SIDEBAR"),n("SET_SIDEBAR_COMPONENT",s)}},ye=(l={},we()(l,"TOGGLE_SIDEBAR",function(e){e.sidebarOpen=!e.sidebarOpen}),we()(l,"SET_SIDEBAR_COMPONENT",function(e,t){e.sidebarComponent=t}),l),Oe={state:$e,getters:xe,actions:Ee,mutations:ye};c.a.use(be.a);var Ce=new be.a.Store({modules:{ui:Oe},strict:!1});c.a.config.productionTip=!1,new c.a({el:"#app",store:Ce,template:" ",components:{App:_e}})},wpMw:function(e,t){e.exports={sidebar:"_1Akv3QSGkfLjHLmQBua5gq_0"}},z8r5:function(e,t){}},["NHnr"]);
2 | //# sourceMappingURL=app.cc4efbd447cb00403ba7.js.map
--------------------------------------------------------------------------------
/docs/sidebar-dynamic/static/js/manifest.ecfa1adc4a7519c26d6b.js:
--------------------------------------------------------------------------------
1 | !function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,c,a){for(var i,u,f,s=0,p=[];s
2 |
3 |
4 |
5 |
6 |
7 | sidebar
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/docs/sidebar/static/css/app.e439c225a7a4e3d818fb42e3f740d862.css:
--------------------------------------------------------------------------------
1 | :root{--accent-color:#ffcb08;--primary-color:#820263;--dark-color:#2e294e}*{box-sizing:border-box}._1yQEW-OB4Ybyf_vE6oWyGO_1{position:fixed;left:0;top:0;height:100vh;width:100vw;background-color:var(--primary-color)}._1Akv3QSGkfLjHLmQBua5gq_0{position:fixed;right:0;top:0;width:300px;height:100vh;max-width:90vw;background-color:var(--accent-color)}._2lbLj0f9KsKJTS3AY46M7w_0{position:fixed;bottom:1rem;right:1rem;padding:0;height:50px;width:50px;border:3px solid transparent;border-radius:50%;background-color:transparent;color:var(--dark-color);cursor:pointer;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;line-height:0;transition:transform .3s ease-out,border-color .3s ease-out}._2lbLj0f9KsKJTS3AY46M7w_0 svg{height:100%;width:100%;fill:var(--accent-color);transition:fill .3s ease-out}._2lbLj0f9KsKJTS3AY46M7w_0:focus{outline:none;border-color:var(--accent-color)}.n02dqwlexV56EeqjpzyEx_0{transform:rotate(45deg)}.n02dqwlexV56EeqjpzyEx_0 svg{fill:var(--primary-color)}.n02dqwlexV56EeqjpzyEx_0:focus{border-color:var(--primary-color)}
2 | /*# sourceMappingURL=app.e439c225a7a4e3d818fb42e3f740d862.css.map */
--------------------------------------------------------------------------------
/docs/sidebar/static/css/app.e439c225a7a4e3d818fb42e3f740d862.css.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["app.e439c225a7a4e3d818fb42e3f740d862.css"],"names":[],"mappings":"AACA,MACE,uBAAwB,AACxB,wBAAyB,AACzB,oBAAsB,CACvB,AACD,EAEU,qBAAuB,CAChC,AAGD,2BACE,eAAgB,AAChB,OAAQ,AACR,MAAO,AACP,aAAc,AACd,YAAa,AACb,qCAAuC,CACxC,AAED,2BACE,eAAgB,AAChB,QAAS,AACT,MAAO,AACP,YAAa,AACb,aAAc,AACd,eAAgB,AAChB,oCAAsC,CACvC,AAED,2BACE,eAAgB,AAChB,YAAa,AACb,WAAY,AACZ,UAAW,AACX,YAAa,AACb,WAAY,AACZ,6BAA8B,AAC9B,kBAAmB,AACnB,6BAA8B,AAC9B,wBAAyB,AACzB,eAAgB,AAEhB,oBAAqB,AACrB,aAAc,AAEV,sBAAuB,AACnB,mBAAoB,AAExB,qBAAsB,AAClB,uBAAwB,AAChC,cAAe,AAGf,2DAAkE,CAEnE,AACD,+BACE,YAAa,AACb,WAAY,AACZ,yBAA0B,AAE1B,4BAAgC,CACjC,AACD,iCACE,aAAc,AACd,gCAAkC,CACnC,AACD,yBAEU,uBAAyB,CAClC,AACD,6BACE,yBAA2B,CAC5B,AACD,+BACE,iCAAmC,CACpC","file":"app.e439c225a7a4e3d818fb42e3f740d862.css","sourcesContent":["\n:root{\n --accent-color: #FFCB08;\n --primary-color: #820263;\n --dark-color: #2E294E;\n}\n*{\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n}\n\n\n._1yQEW-OB4Ybyf_vE6oWyGO_1{\n position: fixed;\n left: 0;\n top: 0;\n height: 100vh;\n width: 100vw;\n background-color: var(--primary-color);\n}\n\n._1Akv3QSGkfLjHLmQBua5gq_0{\n position: fixed;\n right: 0;\n top: 0;\n width: 300px;\n height: 100vh;\n max-width: 90vw;\n background-color: var(--accent-color);\n}\n\n._2lbLj0f9KsKJTS3AY46M7w_0{\n position: fixed;\n bottom: 1rem;\n right: 1rem;\n padding: 0;\n height: 50px;\n width: 50px;\n border: 3px solid transparent;\n border-radius: 50%;\n background-color: transparent;\n color: var(--dark-color);\n cursor: pointer;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n -webkit-box-pack: center;\n -ms-flex-pack: center;\n justify-content: center;\n line-height: 0;\n -webkit-transition: border-color 300ms ease-out, -webkit-transform 300ms ease-out;\n transition: border-color 300ms ease-out, -webkit-transform 300ms ease-out;\n transition: transform 300ms ease-out, border-color 300ms ease-out;\n transition: transform 300ms ease-out, border-color 300ms ease-out, -webkit-transform 300ms ease-out;\n}\n._2lbLj0f9KsKJTS3AY46M7w_0 svg{\n height: 100%;\n width: 100%;\n fill: var(--accent-color);\n -webkit-transition: fill 300ms ease-out;\n transition: fill 300ms ease-out;\n}\n._2lbLj0f9KsKJTS3AY46M7w_0:focus{\n outline: none;\n border-color: var(--accent-color);\n}\n.n02dqwlexV56EeqjpzyEx_0{\n -webkit-transform: rotate(45deg);\n transform: rotate(45deg);\n}\n.n02dqwlexV56EeqjpzyEx_0 svg{\n fill: var(--primary-color);\n}\n.n02dqwlexV56EeqjpzyEx_0:focus{\n border-color: var(--primary-color);\n}\n\n"]}
--------------------------------------------------------------------------------
/docs/sidebar/static/js/app.7e8ea3700ad2708b65ba.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([1],{DWur:function(e,t){e.exports={container:"_1yQEW-OB4Ybyf_vE6oWyGO_1"}},LltD:function(e,t){e.exports={sidebar:"_1Akv3QSGkfLjHLmQBua5gq_0"}},NHnr:function(e,t,n){"use strict";function s(e){this.$style=n("LltD")}function i(e){this.$style=n("mf0t")}function r(e){n("bFqF"),this.$style=n("DWur")}Object.defineProperty(t,"__esModule",{value:!0});var a=n("7+uW"),o=n("+Uzz"),l={name:"sidebar",mounted:function(){o.TweenMax.set(this.$el,{x:this.$el.offsetWidth})},computed:{open:function(){return this.$store.state.ui.sidebarOpen}},watch:{open:function(e){var t=e?0:this.$el.offsetWidth;o.TweenMax.to(this.$el,.6,{x:t,ease:o.Power4.easeOut})}}},c=function(){var e=this,t=e.$createElement;return(e._self._c||t)("div",{class:e.$style.sidebar})},u=[],d={render:c,staticRenderFns:u},p=d,f=n("VU/8"),h=s,b=f(l,p,!1,h,null,null),v=b.exports,m={name:"sidebar-toggle",computed:{open:function(){return this.$store.state.ui.sidebarOpen}},methods:{handleClick:function(){this.$store.dispatch("toggleSidebar")}}},_=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("button",{class:[e.open?e.$style.active:"",e.$style.button],on:{click:e.handleClick}},[n("svg",{attrs:{fill:"#000000",height:"24",viewBox:"0 0 24 24",width:"24",xmlns:"http://www.w3.org/2000/svg"}},[n("path",{attrs:{d:"M0 0h24v24H0z",fill:"none"}}),e._v(" "),n("path",{attrs:{d:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z"}})])])},g=[],$={render:_,staticRenderFns:g},w=$,x=n("VU/8"),O=i,y=x(m,w,!1,O,null,null),E=y.exports,S={name:"app",components:{Sidebar:v,SidebarToggle:E}},F=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{attrs:{id:"app"}},[n("div",{class:e.$style.container}),e._v(" "),n("sidebar"),e._v(" "),n("sidebar-toggle")],1)},L=[],T={render:F,staticRenderFns:L},W=T,k=n("VU/8"),z=r,A=k(S,W,!1,z,null,null),D=A.exports,G=n("NYxO"),M=n("bOdI"),q=n.n(M),B={sidebarOpen:!1},H={sidebarOpen:function(e){return e.sidebarOpen}},R={toggleSidebar:function(e){var t=e.commit;e.state;t("TOGGLE_SIDEBAR")}},V=q()({},"TOGGLE_SIDEBAR",function(e){e.sidebarOpen=!e.sidebarOpen}),j={state:B,getters:H,actions:R,mutations:V};a.a.use(G.a);var U=new G.a.Store({modules:{ui:j},strict:!1});a.a.config.productionTip=!1,new a.a({el:"#app",store:U,template:" ",components:{App:D}})},bFqF:function(e,t){},mf0t:function(e,t){e.exports={button:"_2lbLj0f9KsKJTS3AY46M7w_0",active:"n02dqwlexV56EeqjpzyEx_0"}}},["NHnr"]);
2 | //# sourceMappingURL=app.7e8ea3700ad2708b65ba.js.map
--------------------------------------------------------------------------------
/docs/sidebar/static/js/manifest.0dc805fcf281e9020471.js:
--------------------------------------------------------------------------------
1 | !function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,a,c){for(var i,u,f,s=0,p=[];sBoilerplate for an Advanced GraphQL Server
2 |
3 |
4 |
5 | 
6 |
7 | 🚀 Bootstrap your GraphQL server within seconds
8 | Advanced starter kit for a flexible GraphQL server for Node.js - based on best practices from the GraphQL community.
9 |
10 | ## Features
11 |
12 | - **Scalable GraphQL server:** The server uses [`graphql-yoga`](https://github.com/prisma/graphql-yoga) which is based on Apollo Server & Express
13 | - **GraphQL database:** Includes GraphQL database binding to [Prisma](https://www.prismagraphql.com) (running on MySQL)
14 | - **Authentication**: Signup and login workflows are ready to use for your users
15 | - **Tooling**: Out-of-the-box support for [GraphQL Playground](https://github.com/prisma/graphql-playground) & [query performance tracing](https://github.com/apollographql/apollo-tracing)
16 | - **Extensible**: Simple and flexible [data model](./database/datamodel.graphql) – easy to adjust and extend
17 | - **No configuration overhead**: Preconfigured [`graphql-config`](https://github.com/prisma/graphql-config) setup
18 |
19 | ## Requirements
20 |
21 | You need to have the [GraphQL CLI](https://github.com/graphql-cli/graphql-cli) installed to bootstrap your GraphQL server using `graphql create`:
22 |
23 | ```sh
24 | npm install -g graphql-cli
25 | ```
26 |
27 | ## Getting started
28 |
29 | ```sh
30 | # 1. Bootstrap GraphQL server in directory `my-app`, based on `node-advanced` boilerplate
31 | graphql create my-app --boilerplate node-advanced
32 |
33 | # 2. When prompted, deploy the Prisma service to a _public cluster_
34 |
35 | # 3. Navigate to the new project
36 | cd my-app
37 |
38 | # 4. Start server (runs on http://localhost:4000) and open GraphQL Playground
39 | yarn dev
40 | ```
41 |
42 | 
43 |
44 | ## Documentation
45 |
46 | ### Commands
47 |
48 | * `yarn start` starts GraphQL server on `http://localhost:4000`
49 | * `yarn dev` starts GraphQL server on `http://localhost:4000` _and_ opens GraphQL Playground
50 | * `yarn playground` opens the GraphQL Playground for the `projects` from [`.graphqlconfig.yml`](./.graphqlconfig.yml)
51 | * `yarn prisma ` gives access to local version of Prisma CLI (e.g. `yarn prisma deploy`)
52 |
53 | > **Note**: We recommend that you're using `yarn dev` during development as it will give you access to the GraphQL API or your server (defined by the [application schema](./src/schema.graphql)) as well as to the Prisma API directly (defined by the [Prisma database schema](./generated/prisma.graphql)). If you're starting the server with `yarn start`, you'll only be able to access the API of the application schema.
54 |
55 | ### Project structure
56 |
57 | 
58 |
59 | | File name | Description |
60 | | :-- | :-- |
61 | | `├── .env` | Defines environment variables |
62 | | `├── .graphqlconfig.yml` | Configuration file based on [`graphql-config`](https://github.com/prisma/graphql-config) (e.g. used by GraphQL Playground).|
63 | | `└── database ` (_directory_) | _Contains all files that are related to the Prisma database service_ |\
64 | | ` ├── prisma.yml` | The root configuration file for your Prisma database service ([docs](https://www.prismagraphql.com/docs/reference/prisma.yml/overview-and-example-foatho8aip)) |
65 | | ` └── datamodel.graphql` | Defines your data model (written in [GraphQL SDL](https://blog.graph.cool/graphql-sdl-schema-definition-language-6755bcb9ce51)) |
66 | | `└── src ` (_directory_) | _Contains the source files for your GraphQL server_ |
67 | | ` ├── index.js` | The entry point for your GraphQL server |
68 | | ` ├── schema.graphql` | The **application schema** defining the API exposed to client applications |
69 | | ` ├── resolvers` (_directory_) | _Contains the implementation of the resolvers for the application schema_ |
70 | | ` └── generated` (_directory_) | _Contains generated files_ |
71 | | ` └── prisma.grapghql` | The **Prisma database schema** defining the Prisma GraphQL API |
72 |
73 | ## Contributing
74 |
75 | The GraphQL boilerplates are maintained by the GraphQL community, with official support from the [Apollo](https://dev-blog.apollodata.com) & [Graphcool](https://blog.graph.cool/) teams.
76 |
77 | Your feedback is **very helpful**, please share your opinion and thoughts! If you have any questions or want to contribute yourself, join the [`#graphql-boilerplate`](https://graphcool.slack.com/messages/graphql-boilerplate) channel on our [Slack](https://graphcool.slack.com/).
--------------------------------------------------------------------------------
/prisma-auth0/server/database/datamodel.graphql:
--------------------------------------------------------------------------------
1 | type Post {
2 | id: ID! @unique
3 | createdAt: DateTime!
4 | updatedAt: DateTime!
5 | isPublished: Boolean! @default(value: "false")
6 | title: String!
7 | text: String!
8 | author: User!
9 | }
10 |
11 | type User {
12 | id: ID! @unique
13 | email: String! @unique
14 | password: String!
15 | name: String!
16 | posts: [Post!]!
17 | }
18 |
--------------------------------------------------------------------------------
/prisma-auth0/server/database/prisma.yml:
--------------------------------------------------------------------------------
1 | # the name for the service (will be part of the service's HTTP endpoint)
2 | service: server
3 |
4 | # the cluster and stage the service is deployed to
5 | stage: ${env:PRISMA_STAGE}
6 |
7 | # to disable authentication:
8 | # disableAuth: true
9 | secret: ${env:PRISMA_SECRET}
10 |
11 | # the file path pointing to your data model
12 | datamodel: datamodel.graphql
13 |
14 | # seed your service with initial data based on seed.graphql
15 | seed:
16 | import: seed.graphql
17 |
18 | cluster: ${env:PRISMA_CLUSTER}
--------------------------------------------------------------------------------
/prisma-auth0/server/database/seed.graphql:
--------------------------------------------------------------------------------
1 | mutation {
2 | createUser(data: {
3 | email: "developer@example.com"
4 | password: "$2a$10$hACwQ5/HQI6FhbIISOUVeusy3sKyUDhSq36fF5d/54aAdiygJPFzm" # plaintext password: "nooneknows"
5 | name: "Sarah"
6 | posts: {
7 | create: [{
8 | title: "Hello World"
9 | text: "This is my first blog post ever!"
10 | isPublished: true
11 | }, {
12 | title: "My Second Post"
13 | text: "My first post was good, but this one is better!"
14 | isPublished: true
15 | }, {
16 | title: "Solving World Hunger"
17 | text: "This is a draft..."
18 | isPublished: false
19 | }]
20 | }
21 | }) {
22 | id
23 | }
24 | }
--------------------------------------------------------------------------------
/prisma-auth0/server/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "server",
3 | "scripts": {
4 | "start": "nodemon -e js,graphql -x node -r dotenv/config src/index.js",
5 | "debug": "nodemon -e js,graphql -x node --inspect -r dotenv/config src/index.js",
6 | "playground": "graphql playground",
7 | "dev": "npm-run-all --parallel start playground"
8 | },
9 | "dependencies": {
10 | "bcryptjs": "2.4.3",
11 | "graphql-yoga": "1.2.1",
12 | "jsonwebtoken": "8.1.1",
13 | "prisma-binding": "1.4.0"
14 | },
15 | "devDependencies": {
16 | "dotenv": "4.0.0",
17 | "graphql-cli": "2.13.0",
18 | "nodemon": "1.14.11",
19 | "npm-run-all": "4.1.2",
20 | "prisma": "1.1.2"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/prisma-auth0/server/src/index.js:
--------------------------------------------------------------------------------
1 | const { GraphQLServer } = require('graphql-yoga')
2 | const { Prisma } = require('prisma-binding')
3 | const resolvers = require('./resolvers')
4 |
5 | const server = new GraphQLServer({
6 | typeDefs: 'src/schema.graphql',
7 | resolvers,
8 | context: req => ({
9 | ...req,
10 | db: new Prisma({
11 | typeDefs: 'src/generated/prisma.graphql',
12 | endpoint: process.env.PRISMA_ENDPOINT, // the endpoint of the Prisma DB service (value is set in .env)
13 | secret: process.env.PRISMA_SECRET, // taken from database/prisma.yml (value is set in .env)
14 | debug: true, // log all GraphQL queries & mutations
15 | }),
16 | }),
17 | })
18 |
19 | server.start(() => console.log('Server is running on http://localhost:4000'))
20 |
--------------------------------------------------------------------------------
/prisma-auth0/server/src/resolvers/AuthPayload.js:
--------------------------------------------------------------------------------
1 | const { Context } = require('../utils')
2 |
3 | const AuthPayload = {
4 | user: async ({ user: { id } }, args, ctx, info) => {
5 | return ctx.db.query.user({ where: { id } }, info)
6 | },
7 | }
8 |
9 | module.exports = { AuthPayload }
--------------------------------------------------------------------------------
/prisma-auth0/server/src/resolvers/Mutation/auth.js:
--------------------------------------------------------------------------------
1 | const bcrypt = require('bcryptjs')
2 | const jwt = require('jsonwebtoken')
3 | const { Context } = require( '../../utils')
4 |
5 | const auth = {
6 | async signup(parent, args, ctx, info) {
7 | const password = await bcrypt.hash(args.password, 10)
8 | const user = await ctx.db.mutation.createUser({
9 | data: { ...args, password },
10 | })
11 |
12 | return {
13 | token: jwt.sign({ userId: user.id }, process.env.APP_SECRET),
14 | user,
15 | }
16 | },
17 |
18 | async login(parent, { email, password }, ctx, info) {
19 | const user = await ctx.db.query.user({ where: { email } })
20 | if (!user) {
21 | throw new Error(`No such user found for email: ${email}`)
22 | }
23 |
24 | const valid = await bcrypt.compare(password, user.password)
25 | if (!valid) {
26 | throw new Error('Invalid password')
27 | }
28 |
29 | return {
30 | token: jwt.sign({ userId: user.id }, process.env.APP_SECRET),
31 | user,
32 | }
33 | },
34 | }
35 |
36 | module.exports = { auth }
37 |
--------------------------------------------------------------------------------
/prisma-auth0/server/src/resolvers/Mutation/post.js:
--------------------------------------------------------------------------------
1 | const { getUserId, Context } = require('../../utils')
2 |
3 | const post = {
4 | async createDraft(parent, { title, text }, ctx, info) {
5 | const userId = getUserId(ctx)
6 | return ctx.db.mutation.createPost(
7 | {
8 | data: {
9 | title,
10 | text,
11 | isPublished: false,
12 | author: {
13 | connect: { id: userId },
14 | },
15 | },
16 | },
17 | info
18 | )
19 | },
20 |
21 | async publish(parent, { id }, ctx, info) {
22 | const userId = getUserId(ctx)
23 | const postExists = await ctx.db.exists.Post({
24 | id,
25 | author: { id: userId },
26 | })
27 | if (!postExists) {
28 | throw new Error(`Post not found or you're not the author`)
29 | }
30 |
31 | return ctx.db.mutation.updatePost(
32 | {
33 | where: { id },
34 | data: { isPublished: true },
35 | },
36 | info,
37 | )
38 | },
39 |
40 | async deletePost(parent, { id }, ctx, info) {
41 | const userId = getUserId(ctx)
42 | const postExists = await ctx.db.exists.Post({
43 | id,
44 | author: { id: userId },
45 | })
46 | if (!postExists) {
47 | throw new Error(`Post not found or you're not the author`)
48 | }
49 |
50 | return ctx.db.mutation.deletePost({ where: { id } })
51 | },
52 | }
53 |
54 | module.exports = { post }
55 |
--------------------------------------------------------------------------------
/prisma-auth0/server/src/resolvers/Query.js:
--------------------------------------------------------------------------------
1 | const { getUserId, Context } = require('../utils')
2 |
3 | const Query = {
4 | feed(parent, args, ctx, info) {
5 | return ctx.db.query.posts({ where: { isPublished: true } }, info)
6 | },
7 |
8 | drafts(parent, args, ctx, info) {
9 | const id = getUserId(ctx)
10 |
11 | const where = {
12 | isPublished: false,
13 | author: {
14 | id
15 | }
16 | }
17 |
18 | return ctx.db.query.posts({ where }, info)
19 | },
20 |
21 | post(parent, { id }, ctx, info) {
22 | return ctx.db.query.post({ where: { id } }, info)
23 | },
24 |
25 | me(parent, args, ctx, info) {
26 | const id = getUserId(ctx)
27 | return ctx.db.query.user({ where: { id } }, info)
28 | },
29 | }
30 |
31 | module.exports = { Query }
32 |
--------------------------------------------------------------------------------
/prisma-auth0/server/src/resolvers/index.js:
--------------------------------------------------------------------------------
1 | const { Query } = require('./Query')
2 | const { auth } = require('./Mutation/auth')
3 | const { post } = require('./Mutation/post')
4 | const { AuthPayload } = require('./AuthPayload')
5 |
6 | module.exports = {
7 | Query,
8 | Mutation: {
9 | ...auth,
10 | ...post,
11 | },
12 | AuthPayload,
13 | }
14 |
--------------------------------------------------------------------------------
/prisma-auth0/server/src/schema.graphql:
--------------------------------------------------------------------------------
1 | # import Post from "./generated/prisma.graphql"
2 |
3 | type Query {
4 | feed: [Post!]!
5 | drafts: [Post!]!
6 | post(id: ID!): Post!
7 | me: User
8 | }
9 |
10 | type Mutation {
11 | signup(email: String!, password: String!, name: String!): AuthPayload!
12 | login(email: String!, password: String!): AuthPayload!
13 | createDraft(title: String!, text: String!): Post!
14 | publish(id: ID!): Post!
15 | deletePost(id: ID!): Post!
16 | }
17 |
18 | type AuthPayload {
19 | token: String!
20 | user: User!
21 | }
22 |
23 | type User {
24 | id: ID!
25 | email: String!
26 | name: String!
27 | posts: [Post!]!
28 | }
29 |
--------------------------------------------------------------------------------
/prisma-auth0/server/src/utils.js:
--------------------------------------------------------------------------------
1 | const jwt = require('jsonwebtoken')
2 |
3 | function getUserId(ctx) {
4 | const Authorization = ctx.request.get('Authorization')
5 | if (Authorization) {
6 | const token = Authorization.replace('Bearer ', '')
7 | const { userId } = jwt.verify(token, process.env.APP_SECRET)
8 | return userId
9 | }
10 |
11 | throw new AuthError()
12 | }
13 |
14 | class AuthError extends Error {
15 | constructor() {
16 | super('Not authorized')
17 | }
18 | }
19 |
20 | module.exports = {
21 | getUserId,
22 | AuthError
23 | }
--------------------------------------------------------------------------------
/sidebar-dynamic/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["env", {
4 | "modules": false
5 | }],
6 | "stage-2"
7 | ],
8 | "plugins": ["transform-runtime"],
9 | "env": {
10 | "test": {
11 | "presets": ["env", "stage-2"] }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/sidebar-dynamic/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/sidebar-dynamic/.eslintignore:
--------------------------------------------------------------------------------
1 | /build/
2 | /config/
3 | /dist/
4 | /*.js
5 |
--------------------------------------------------------------------------------
/sidebar-dynamic/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // https://eslint.org/docs/user-guide/configuring
2 |
3 | module.exports = {
4 | root: true,
5 | parser: 'babel-eslint',
6 | parserOptions: {
7 | sourceType: 'module'
8 | },
9 | env: {
10 | browser: true,
11 | },
12 | // https://github.com/standard/standard/blob/master/docs/RULES-en.md
13 | extends: 'standard',
14 | // required to lint *.vue files
15 | plugins: [
16 | 'html'
17 | ],
18 | // add your custom rules here
19 | 'rules': {
20 | // allow paren-less arrow functions
21 | 'arrow-parens': 0,
22 | // allow async-await
23 | 'generator-star-spacing': 0,
24 | // allow debugger during development
25 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/sidebar-dynamic/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | /dist/
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Editor directories and files
9 | .idea
10 | .vscode
11 | *.suo
12 | *.ntvs*
13 | *.njsproj
14 | *.sln
15 |
--------------------------------------------------------------------------------
/sidebar-dynamic/.postcssrc.js:
--------------------------------------------------------------------------------
1 | // https://github.com/michael-ciniawsky/postcss-load-config
2 |
3 | module.exports = {
4 | "plugins": {
5 | // to edit target browsers: use "browserslist" field in package.json
6 | "postcss-import": {},
7 | "autoprefixer": {}
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/sidebar-dynamic/README.md:
--------------------------------------------------------------------------------
1 | # Dynamic Content Sidebar
2 |
3 | [Read the Medium tutorial first!](https://medium.com/@rmmmsy/creating-a-sidebar-with-dynamic-content-using-vue-and-vuex-88e904894e00)
4 |
5 | ## Build Setup
6 |
7 | ``` bash
8 | # install dependencies
9 | npm install
10 |
11 | # serve with hot reload at localhost:8080
12 | npm run dev
13 |
14 | # build for production with minification
15 | npm run build
16 |
17 | # build for production and view the bundle analyzer report
18 | npm run build --report
19 | ```
20 |
21 | For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
22 |
--------------------------------------------------------------------------------
/sidebar-dynamic/build/build.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | require('./check-versions')()
3 |
4 | process.env.NODE_ENV = 'production'
5 |
6 | const ora = require('ora')
7 | const rm = require('rimraf')
8 | const path = require('path')
9 | const chalk = require('chalk')
10 | const webpack = require('webpack')
11 | const config = require('../config')
12 | const webpackConfig = require('./webpack.prod.conf')
13 |
14 | const spinner = ora('building for production...')
15 | spinner.start()
16 |
17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
18 | if (err) throw err
19 | webpack(webpackConfig, function (err, stats) {
20 | spinner.stop()
21 | if (err) throw err
22 | process.stdout.write(stats.toString({
23 | colors: true,
24 | modules: false,
25 | children: false,
26 | chunks: false,
27 | chunkModules: false
28 | }) + '\n\n')
29 |
30 | if (stats.hasErrors()) {
31 | console.log(chalk.red(' Build failed with errors.\n'))
32 | process.exit(1)
33 | }
34 |
35 | console.log(chalk.cyan(' Build complete.\n'))
36 | console.log(chalk.yellow(
37 | ' Tip: built files are meant to be served over an HTTP server.\n' +
38 | ' Opening index.html over file:// won\'t work.\n'
39 | ))
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/sidebar-dynamic/build/check-versions.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const chalk = require('chalk')
3 | const semver = require('semver')
4 | const packageConfig = require('../package.json')
5 | const shell = require('shelljs')
6 | function exec (cmd) {
7 | return require('child_process').execSync(cmd).toString().trim()
8 | }
9 |
10 | const versionRequirements = [
11 | {
12 | name: 'node',
13 | currentVersion: semver.clean(process.version),
14 | versionRequirement: packageConfig.engines.node
15 | }
16 | ]
17 |
18 | if (shell.which('npm')) {
19 | versionRequirements.push({
20 | name: 'npm',
21 | currentVersion: exec('npm --version'),
22 | versionRequirement: packageConfig.engines.npm
23 | })
24 | }
25 |
26 | module.exports = function () {
27 | const warnings = []
28 | for (let i = 0; i < versionRequirements.length; i++) {
29 | const mod = versionRequirements[i]
30 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
31 | warnings.push(mod.name + ': ' +
32 | chalk.red(mod.currentVersion) + ' should be ' +
33 | chalk.green(mod.versionRequirement)
34 | )
35 | }
36 | }
37 |
38 | if (warnings.length) {
39 | console.log('')
40 | console.log(chalk.yellow('To use this template, you must update following to modules:'))
41 | console.log()
42 | for (let i = 0; i < warnings.length; i++) {
43 | const warning = warnings[i]
44 | console.log(' ' + warning)
45 | }
46 | console.log()
47 | process.exit(1)
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/sidebar-dynamic/build/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ramsaylanier/vue-tutorials/26cada54a6f81bc41c0fe786d1d278faf5431e10/sidebar-dynamic/build/logo.png
--------------------------------------------------------------------------------
/sidebar-dynamic/build/utils.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const config = require('../config')
4 | const ExtractTextPlugin = require('extract-text-webpack-plugin')
5 | const pkg = require('../package.json')
6 |
7 | exports.assetsPath = function (_path) {
8 | const assetsSubDirectory = process.env.NODE_ENV === 'production'
9 | ? config.build.assetsSubDirectory
10 | : config.dev.assetsSubDirectory
11 | return path.posix.join(assetsSubDirectory, _path)
12 | }
13 |
14 | exports.cssLoaders = function (options) {
15 | options = options || {}
16 |
17 | const cssLoader = {
18 | loader: 'css-loader',
19 | options: {
20 | sourceMap: options.sourceMap
21 | }
22 | }
23 |
24 | var postcssLoader = {
25 | loader: 'postcss-loader',
26 | options: {
27 | sourceMap: options.sourceMap
28 | }
29 | }
30 |
31 | // generate loader string to be used with extract text plugin
32 | function generateLoaders (loader, loaderOptions) {
33 | const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
34 | if (loader) {
35 | loaders.push({
36 | loader: loader + '-loader',
37 | options: Object.assign({}, loaderOptions, {
38 | sourceMap: options.sourceMap
39 | })
40 | })
41 | }
42 |
43 | // Extract CSS when that option is specified
44 | // (which is the case during production build)
45 | if (options.extract) {
46 | return ExtractTextPlugin.extract({
47 | use: loaders,
48 | fallback: 'vue-style-loader'
49 | })
50 | } else {
51 | return ['vue-style-loader'].concat(loaders)
52 | }
53 | }
54 |
55 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html
56 | return {
57 | css: generateLoaders(),
58 | postcss: generateLoaders(),
59 | less: generateLoaders('less'),
60 | sass: generateLoaders('sass', { indentedSyntax: true }),
61 | scss: generateLoaders('sass'),
62 | stylus: generateLoaders('stylus'),
63 | styl: generateLoaders('stylus')
64 | }
65 | }
66 |
67 | // Generate loaders for standalone style files (outside of .vue)
68 | exports.styleLoaders = function (options) {
69 | const output = []
70 | const loaders = exports.cssLoaders(options)
71 | for (const extension in loaders) {
72 | const loader = loaders[extension]
73 | output.push({
74 | test: new RegExp('\\.' + extension + '$'),
75 | use: loader
76 | })
77 | }
78 | return output
79 | }
80 |
81 | exports.createNotifierCallback = function () {
82 | const notifier = require('node-notifier')
83 |
84 | return (severity, errors) => {
85 | if (severity !== 'error') {
86 | return
87 | }
88 | const error = errors[0]
89 |
90 | const filename = error.file.split('!').pop()
91 | notifier.notify({
92 | title: pkg.name,
93 | message: severity + ': ' + error.name,
94 | subtitle: filename || '',
95 | icon: path.join(__dirname, 'logo.png')
96 | })
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/sidebar-dynamic/build/vue-loader.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const utils = require('./utils')
3 | const config = require('../config')
4 | const isProduction = process.env.NODE_ENV === 'production'
5 | const sourceMapEnabled = isProduction
6 | ? config.build.productionSourceMap
7 | : config.dev.cssSourceMap
8 |
9 |
10 | module.exports = {
11 | loaders: utils.cssLoaders({
12 | sourceMap: sourceMapEnabled,
13 | extract: isProduction
14 | }),
15 | cssSourceMap: sourceMapEnabled,
16 | transformToRequire: {
17 | video: 'src',
18 | source: 'src',
19 | img: 'src',
20 | image: 'xlink:href'
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/sidebar-dynamic/build/webpack.base.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const utils = require('./utils')
4 | const config = require('../config')
5 | const vueLoaderConfig = require('./vue-loader.conf')
6 |
7 | function resolve (dir) {
8 | return path.join(__dirname, '..', dir)
9 | }
10 |
11 | module.exports = {
12 | context: path.resolve(__dirname, '../'),
13 | entry: {
14 | app: './src/main.js'
15 | },
16 | output: {
17 | path: config.build.assetsRoot,
18 | filename: '[name].js',
19 | publicPath: process.env.NODE_ENV === 'production'
20 | ? config.build.assetsPublicPath
21 | : config.dev.assetsPublicPath
22 | },
23 | resolve: {
24 | extensions: ['.js', '.vue', '.json'],
25 | alias: {
26 | 'vue$': 'vue/dist/vue.esm.js',
27 | '@': resolve('src'),
28 | }
29 | },
30 | module: {
31 | rules: [
32 | ...(config.dev.useEslint? [{
33 | test: /\.(js|vue)$/,
34 | loader: 'eslint-loader',
35 | enforce: 'pre',
36 | include: [resolve('src'), resolve('test')],
37 | options: {
38 | formatter: require('eslint-friendly-formatter'),
39 | emitWarning: !config.dev.showEslintErrorsInOverlay
40 | }
41 | }] : []),
42 | {
43 | test: /\.vue$/,
44 | loader: 'vue-loader',
45 | options: vueLoaderConfig
46 | },
47 | {
48 | test: /\.js$/,
49 | loader: 'babel-loader',
50 | include: [resolve('src'), resolve('test')]
51 | },
52 | {
53 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
54 | loader: 'url-loader',
55 | options: {
56 | limit: 10000,
57 | name: utils.assetsPath('img/[name].[hash:7].[ext]')
58 | }
59 | },
60 | {
61 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
62 | loader: 'url-loader',
63 | options: {
64 | limit: 10000,
65 | name: utils.assetsPath('media/[name].[hash:7].[ext]')
66 | }
67 | },
68 | {
69 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
70 | loader: 'url-loader',
71 | options: {
72 | limit: 10000,
73 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
74 | }
75 | }
76 | ]
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/sidebar-dynamic/build/webpack.dev.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const utils = require('./utils')
3 | const webpack = require('webpack')
4 | const config = require('../config')
5 | const merge = require('webpack-merge')
6 | const baseWebpackConfig = require('./webpack.base.conf')
7 | const HtmlWebpackPlugin = require('html-webpack-plugin')
8 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
9 | const portfinder = require('portfinder')
10 |
11 | const devWebpackConfig = merge(baseWebpackConfig, {
12 | module: {
13 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
14 | },
15 | // cheap-module-eval-source-map is faster for development
16 | devtool: config.dev.devtool,
17 |
18 | // these devServer options should be customized in /config/index.js
19 | devServer: {
20 | clientLogLevel: 'warning',
21 | historyApiFallback: true,
22 | hot: true,
23 | host: process.env.HOST || config.dev.host,
24 | port: process.env.PORT || config.dev.port,
25 | open: config.dev.autoOpenBrowser,
26 | overlay: config.dev.errorOverlay ? {
27 | warnings: false,
28 | errors: true,
29 | } : false,
30 | publicPath: config.dev.assetsPublicPath,
31 | proxy: config.dev.proxyTable,
32 | quiet: true, // necessary for FriendlyErrorsPlugin
33 | watchOptions: {
34 | poll: config.dev.poll,
35 | }
36 | },
37 | plugins: [
38 | new webpack.DefinePlugin({
39 | 'process.env': require('../config/dev.env')
40 | }),
41 | new webpack.HotModuleReplacementPlugin(),
42 | new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
43 | new webpack.NoEmitOnErrorsPlugin(),
44 | // https://github.com/ampedandwired/html-webpack-plugin
45 | new HtmlWebpackPlugin({
46 | filename: 'index.html',
47 | template: 'index.html',
48 | inject: true
49 | }),
50 | ]
51 | })
52 |
53 | module.exports = new Promise((resolve, reject) => {
54 | portfinder.basePort = process.env.PORT || config.dev.port
55 | portfinder.getPort((err, port) => {
56 | if (err) {
57 | reject(err)
58 | } else {
59 | // publish the new Port, necessary for e2e tests
60 | process.env.PORT = port
61 | // add port to devServer config
62 | devWebpackConfig.devServer.port = port
63 |
64 | // Add FriendlyErrorsPlugin
65 | devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
66 | compilationSuccessInfo: {
67 | messages: [`Your application is running here: http://${config.dev.host}:${port}`],
68 | },
69 | onErrors: config.dev.notifyOnErrors
70 | ? utils.createNotifierCallback()
71 | : undefined
72 | }))
73 |
74 | resolve(devWebpackConfig)
75 | }
76 | })
77 | })
78 |
--------------------------------------------------------------------------------
/sidebar-dynamic/build/webpack.test.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | // This is the webpack config used for unit tests.
3 |
4 | const utils = require('./utils')
5 | const webpack = require('webpack')
6 | const merge = require('webpack-merge')
7 | const baseWebpackConfig = require('./webpack.base.conf')
8 |
9 | const webpackConfig = merge(baseWebpackConfig, {
10 | // use inline sourcemap for karma-sourcemap-loader
11 | module: {
12 | rules: utils.styleLoaders()
13 | },
14 | devtool: '#inline-source-map',
15 | resolveLoader: {
16 | alias: {
17 | // necessary to to make lang="scss" work in test when using vue-loader's ?inject option
18 | // see discussion at https://github.com/vuejs/vue-loader/issues/724
19 | 'scss-loader': 'sass-loader'
20 | }
21 | },
22 | plugins: [
23 | new webpack.DefinePlugin({
24 | 'process.env': require('../config/test.env')
25 | })
26 | ]
27 | })
28 |
29 | // no need for app entry during tests
30 | delete webpackConfig.entry
31 |
32 | module.exports = webpackConfig
33 |
--------------------------------------------------------------------------------
/sidebar-dynamic/config/dev.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const merge = require('webpack-merge')
3 | const prodEnv = require('./prod.env')
4 |
5 | module.exports = merge(prodEnv, {
6 | NODE_ENV: '"development"'
7 | })
8 |
--------------------------------------------------------------------------------
/sidebar-dynamic/config/index.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | // Template version: 1.2.3
3 | // see http://vuejs-templates.github.io/webpack for documentation.
4 |
5 | const path = require('path')
6 |
7 | module.exports = {
8 | dev: {
9 |
10 | // Paths
11 | assetsSubDirectory: 'static',
12 | assetsPublicPath: '/',
13 | proxyTable: {},
14 |
15 | // Various Dev Server settings
16 | host: 'localhost', // can be overwritten by process.env.HOST
17 | port: 8080, // can be overwritten by process.env.HOST, if port is in use, a free one will be determined
18 | autoOpenBrowser: false,
19 | errorOverlay: true,
20 | notifyOnErrors: true,
21 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
22 |
23 | // Use Eslint Loader?
24 | // If true, your code will be linted during bundling and
25 | // linting errors and warnings will be shown in the console.
26 | useEslint: true,
27 | // If true, eslint errors and warnings will also be shown in the error overlay
28 | // in the browser.
29 | showEslintErrorsInOverlay: false,
30 |
31 | /**
32 | * Source Maps
33 | */
34 |
35 | // https://webpack.js.org/configuration/devtool/#development
36 | devtool: 'eval-source-map',
37 |
38 | // If you have problems debugging vue-files in devtools,
39 | // set this to false - it *may* help
40 | // https://vue-loader.vuejs.org/en/options.html#cachebusting
41 | cacheBusting: true,
42 |
43 | // CSS Sourcemaps off by default because relative paths are "buggy"
44 | // with this option, according to the CSS-Loader README
45 | // (https://github.com/webpack/css-loader#sourcemaps)
46 | // In our experience, they generally work as expected,
47 | // just be aware of this issue when enabling this option.
48 | cssSourceMap: false,
49 | },
50 |
51 | build: {
52 | // Template for index.html
53 | index: path.resolve(__dirname, '../dist/index.html'),
54 |
55 | // Paths
56 | assetsRoot: path.resolve(__dirname, '../dist'),
57 | assetsSubDirectory: 'static',
58 | assetsPublicPath: '/',
59 |
60 | /**
61 | * Source Maps
62 | */
63 |
64 | productionSourceMap: true,
65 | // https://webpack.js.org/configuration/devtool/#production
66 | devtool: '#source-map',
67 |
68 | // Gzip off by default as many popular static hosts such as
69 | // Surge or Netlify already gzip all static assets for you.
70 | // Before setting to `true`, make sure to:
71 | // npm install --save-dev compression-webpack-plugin
72 | productionGzip: false,
73 | productionGzipExtensions: ['js', 'css'],
74 |
75 | // Run the build command with an extra argument to
76 | // View the bundle analyzer report after build finishes:
77 | // `npm run build --report`
78 | // Set to `true` or `false` to always turn it on or off
79 | bundleAnalyzerReport: process.env.npm_config_report
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/sidebar-dynamic/config/prod.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | module.exports = {
3 | NODE_ENV: '"production"'
4 | }
5 |
--------------------------------------------------------------------------------
/sidebar-dynamic/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | sidebar
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/sidebar-dynamic/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sidebar",
3 | "version": "1.0.0",
4 | "description": "A Vue.js project",
5 | "author": "ramsaylanier",
6 | "private": true,
7 | "scripts": {
8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
9 | "start": "npm run dev",
10 | "lint": "eslint --ext .js,.vue src",
11 | "build": "node build/build.js"
12 | },
13 | "dependencies": {
14 | "css-loader": "^0.28.7",
15 | "gsap": "^1.20.3",
16 | "vue": "^2.5.2",
17 | "vue-style-loader": "^3.0.3",
18 | "vuex": "^3.0.1"
19 | },
20 | "devDependencies": {
21 | "autoprefixer": "^7.1.2",
22 | "babel-core": "^6.22.1",
23 | "babel-eslint": "^7.1.1",
24 | "babel-loader": "^7.1.1",
25 | "babel-plugin-transform-runtime": "^6.22.0",
26 | "babel-preset-env": "^1.3.2",
27 | "babel-preset-stage-2": "^6.22.0",
28 | "babel-register": "^6.22.0",
29 | "chalk": "^2.0.1",
30 | "copy-webpack-plugin": "^4.0.1",
31 | "css-loader": "^0.28.0",
32 | "eslint": "^3.19.0",
33 | "eslint-friendly-formatter": "^3.0.0",
34 | "eslint-loader": "^1.7.1",
35 | "eslint-plugin-html": "^3.0.0",
36 | "eslint-config-standard": "^10.2.1",
37 | "eslint-plugin-promise": "^3.4.0",
38 | "eslint-plugin-standard": "^3.0.1",
39 | "eslint-plugin-import": "^2.7.0",
40 | "eslint-plugin-node": "^5.2.0",
41 | "eventsource-polyfill": "^0.9.6",
42 | "extract-text-webpack-plugin": "^3.0.0",
43 | "file-loader": "^1.1.4",
44 | "friendly-errors-webpack-plugin": "^1.6.1",
45 | "html-webpack-plugin": "^2.30.1",
46 | "webpack-bundle-analyzer": "^2.9.0",
47 | "node-notifier": "^5.1.2",
48 | "postcss-import": "^11.0.0",
49 | "postcss-loader": "^2.0.8",
50 | "semver": "^5.3.0",
51 | "shelljs": "^0.7.6",
52 | "optimize-css-assets-webpack-plugin": "^3.2.0",
53 | "ora": "^1.2.0",
54 | "rimraf": "^2.6.0",
55 | "url-loader": "^0.5.8",
56 | "vue-loader": "^13.3.0",
57 | "vue-style-loader": "^3.0.1",
58 | "vue-template-compiler": "^2.5.2",
59 | "portfinder": "^1.0.13",
60 | "webpack": "^3.6.0",
61 | "webpack-dev-server": "^2.9.1",
62 | "webpack-merge": "^4.1.0"
63 | },
64 | "engines": {
65 | "node": ">= 4.0.0",
66 | "npm": ">= 3.0.0"
67 | },
68 | "browserslist": [
69 | "> 1%",
70 | "last 2 versions",
71 | "not ie <= 8"
72 | ]
73 | }
74 |
--------------------------------------------------------------------------------
/sidebar-dynamic/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
38 |
39 |
51 |
52 |
69 |
--------------------------------------------------------------------------------
/sidebar-dynamic/src/components/addForm.vue:
--------------------------------------------------------------------------------
1 |
2 | Add Form
3 |
4 |
5 |
10 |
11 |
--------------------------------------------------------------------------------
/sidebar-dynamic/src/components/searchForm.vue:
--------------------------------------------------------------------------------
1 |
2 | Search Form
3 |
4 |
5 |
10 |
11 |
--------------------------------------------------------------------------------
/sidebar-dynamic/src/components/sidebar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
36 |
37 |
--------------------------------------------------------------------------------
/sidebar-dynamic/src/components/sidebarToggle.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
23 |
24 |
--------------------------------------------------------------------------------
/sidebar-dynamic/src/icons/add.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/sidebar-dynamic/src/icons/search.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/sidebar-dynamic/src/main.js:
--------------------------------------------------------------------------------
1 | // The Vue build version to load with the `import` command
2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
3 | import Vue from 'vue'
4 | import App from './App'
5 | import store from './store/index.js'
6 |
7 | Vue.config.productionTip = false
8 |
9 | /* eslint-disable no-new */
10 | new Vue({
11 | el: '#app',
12 | store,
13 | template: ' ',
14 | components: { App }
15 | })
16 |
--------------------------------------------------------------------------------
/sidebar-dynamic/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 | import ui from './modules/ui'
4 |
5 | Vue.use(Vuex)
6 |
7 | const debug = process.env.NODE_ENV !== 'production'
8 |
9 | export default new Vuex.Store({
10 | modules: {
11 | ui
12 | },
13 | strict: debug
14 | })
15 |
--------------------------------------------------------------------------------
/sidebar-dynamic/src/store/modules/ui.js:
--------------------------------------------------------------------------------
1 | import * as types from '../mutation-types'
2 |
3 | // initial state
4 | // shape: [{ id, quantity }]
5 | const state = {
6 | sidebarOpen: false,
7 | sidebarComponent: null
8 | }
9 |
10 | // getters
11 | const getters = {
12 | sidebarOpen: state => state.sidebarOpen,
13 | sidebarComponent: state => state.sidebarComponent
14 | }
15 |
16 | // actions
17 | const actions = {
18 | toggleSidebar ({ commit, state }, {component}) {
19 | commit(types.TOGGLE_SIDEBAR)
20 | commit(types.SET_SIDEBAR_COMPONENT, component)
21 | }
22 | }
23 |
24 | // mutations
25 | const mutations = {
26 | [types.TOGGLE_SIDEBAR] (state) {
27 | state.sidebarOpen = !state.sidebarOpen
28 | },
29 | [types.SET_SIDEBAR_COMPONENT] (state, component) {
30 | state.sidebarComponent = component
31 | }
32 | }
33 |
34 | export default {
35 | state,
36 | getters,
37 | actions,
38 | mutations
39 | }
40 |
--------------------------------------------------------------------------------
/sidebar-dynamic/src/store/mutation-types.js:
--------------------------------------------------------------------------------
1 | export const TOGGLE_SIDEBAR = 'TOGGLE_SIDEBAR'
2 | export const SET_SIDEBAR_COMPONENT = 'SET_SIDEBAR_COMPONENT'
3 |
--------------------------------------------------------------------------------
/sidebar-dynamic/static/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ramsaylanier/vue-tutorials/26cada54a6f81bc41c0fe786d1d278faf5431e10/sidebar-dynamic/static/.gitkeep
--------------------------------------------------------------------------------
/sidebar/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["env", {
4 | "modules": false
5 | }],
6 | "stage-2"
7 | ],
8 | "plugins": ["transform-runtime"],
9 | "env": {
10 | "test": {
11 | "presets": ["env", "stage-2"] }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/sidebar/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/sidebar/.eslintignore:
--------------------------------------------------------------------------------
1 | /build/
2 | /config/
3 | /dist/
4 | /*.js
5 |
--------------------------------------------------------------------------------
/sidebar/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // https://eslint.org/docs/user-guide/configuring
2 |
3 | module.exports = {
4 | root: true,
5 | parser: 'babel-eslint',
6 | parserOptions: {
7 | sourceType: 'module'
8 | },
9 | env: {
10 | browser: true,
11 | },
12 | // https://github.com/standard/standard/blob/master/docs/RULES-en.md
13 | extends: 'standard',
14 | // required to lint *.vue files
15 | plugins: [
16 | 'html'
17 | ],
18 | // add your custom rules here
19 | 'rules': {
20 | // allow paren-less arrow functions
21 | 'arrow-parens': 0,
22 | // allow async-await
23 | 'generator-star-spacing': 0,
24 | // allow debugger during development
25 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/sidebar/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | /dist/
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Editor directories and files
9 | .idea
10 | .vscode
11 | *.suo
12 | *.ntvs*
13 | *.njsproj
14 | *.sln
15 |
--------------------------------------------------------------------------------
/sidebar/.postcssrc.js:
--------------------------------------------------------------------------------
1 | // https://github.com/michael-ciniawsky/postcss-load-config
2 |
3 | module.exports = {
4 | "plugins": {
5 | // to edit target browsers: use "browserslist" field in package.json
6 | "postcss-import": {},
7 | "autoprefixer": {}
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/sidebar/README.md:
--------------------------------------------------------------------------------
1 | # sidebar
2 |
3 | > A Vue.js project
4 |
5 | ## Build Setup
6 |
7 | ``` bash
8 | # install dependencies
9 | npm install
10 |
11 | # serve with hot reload at localhost:8080
12 | npm run dev
13 |
14 | # build for production with minification
15 | npm run build
16 |
17 | # build for production and view the bundle analyzer report
18 | npm run build --report
19 | ```
20 |
21 | For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
22 |
--------------------------------------------------------------------------------
/sidebar/build/build.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | require('./check-versions')()
3 |
4 | process.env.NODE_ENV = 'production'
5 |
6 | const ora = require('ora')
7 | const rm = require('rimraf')
8 | const path = require('path')
9 | const chalk = require('chalk')
10 | const webpack = require('webpack')
11 | const config = require('../config')
12 | const webpackConfig = require('./webpack.prod.conf')
13 |
14 | const spinner = ora('building for production...')
15 | spinner.start()
16 |
17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
18 | if (err) throw err
19 | webpack(webpackConfig, function (err, stats) {
20 | spinner.stop()
21 | if (err) throw err
22 | process.stdout.write(stats.toString({
23 | colors: true,
24 | modules: false,
25 | children: false,
26 | chunks: false,
27 | chunkModules: false
28 | }) + '\n\n')
29 |
30 | if (stats.hasErrors()) {
31 | console.log(chalk.red(' Build failed with errors.\n'))
32 | process.exit(1)
33 | }
34 |
35 | console.log(chalk.cyan(' Build complete.\n'))
36 | console.log(chalk.yellow(
37 | ' Tip: built files are meant to be served over an HTTP server.\n' +
38 | ' Opening index.html over file:// won\'t work.\n'
39 | ))
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/sidebar/build/check-versions.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const chalk = require('chalk')
3 | const semver = require('semver')
4 | const packageConfig = require('../package.json')
5 | const shell = require('shelljs')
6 | function exec (cmd) {
7 | return require('child_process').execSync(cmd).toString().trim()
8 | }
9 |
10 | const versionRequirements = [
11 | {
12 | name: 'node',
13 | currentVersion: semver.clean(process.version),
14 | versionRequirement: packageConfig.engines.node
15 | }
16 | ]
17 |
18 | if (shell.which('npm')) {
19 | versionRequirements.push({
20 | name: 'npm',
21 | currentVersion: exec('npm --version'),
22 | versionRequirement: packageConfig.engines.npm
23 | })
24 | }
25 |
26 | module.exports = function () {
27 | const warnings = []
28 | for (let i = 0; i < versionRequirements.length; i++) {
29 | const mod = versionRequirements[i]
30 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
31 | warnings.push(mod.name + ': ' +
32 | chalk.red(mod.currentVersion) + ' should be ' +
33 | chalk.green(mod.versionRequirement)
34 | )
35 | }
36 | }
37 |
38 | if (warnings.length) {
39 | console.log('')
40 | console.log(chalk.yellow('To use this template, you must update following to modules:'))
41 | console.log()
42 | for (let i = 0; i < warnings.length; i++) {
43 | const warning = warnings[i]
44 | console.log(' ' + warning)
45 | }
46 | console.log()
47 | process.exit(1)
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/sidebar/build/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ramsaylanier/vue-tutorials/26cada54a6f81bc41c0fe786d1d278faf5431e10/sidebar/build/logo.png
--------------------------------------------------------------------------------
/sidebar/build/utils.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const config = require('../config')
4 | const ExtractTextPlugin = require('extract-text-webpack-plugin')
5 | const pkg = require('../package.json')
6 |
7 | exports.assetsPath = function (_path) {
8 | const assetsSubDirectory = process.env.NODE_ENV === 'production'
9 | ? config.build.assetsSubDirectory
10 | : config.dev.assetsSubDirectory
11 | return path.posix.join(assetsSubDirectory, _path)
12 | }
13 |
14 | exports.cssLoaders = function (options) {
15 | options = options || {}
16 |
17 | const cssLoader = {
18 | loader: 'css-loader',
19 | options: {
20 | sourceMap: options.sourceMap
21 | }
22 | }
23 |
24 | var postcssLoader = {
25 | loader: 'postcss-loader',
26 | options: {
27 | sourceMap: options.sourceMap
28 | }
29 | }
30 |
31 | // generate loader string to be used with extract text plugin
32 | function generateLoaders (loader, loaderOptions) {
33 | const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
34 | if (loader) {
35 | loaders.push({
36 | loader: loader + '-loader',
37 | options: Object.assign({}, loaderOptions, {
38 | sourceMap: options.sourceMap
39 | })
40 | })
41 | }
42 |
43 | // Extract CSS when that option is specified
44 | // (which is the case during production build)
45 | if (options.extract) {
46 | return ExtractTextPlugin.extract({
47 | use: loaders,
48 | fallback: 'vue-style-loader'
49 | })
50 | } else {
51 | return ['vue-style-loader'].concat(loaders)
52 | }
53 | }
54 |
55 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html
56 | return {
57 | css: generateLoaders(),
58 | postcss: generateLoaders(),
59 | less: generateLoaders('less'),
60 | sass: generateLoaders('sass', { indentedSyntax: true }),
61 | scss: generateLoaders('sass'),
62 | stylus: generateLoaders('stylus'),
63 | styl: generateLoaders('stylus')
64 | }
65 | }
66 |
67 | // Generate loaders for standalone style files (outside of .vue)
68 | exports.styleLoaders = function (options) {
69 | const output = []
70 | const loaders = exports.cssLoaders(options)
71 | for (const extension in loaders) {
72 | const loader = loaders[extension]
73 | output.push({
74 | test: new RegExp('\\.' + extension + '$'),
75 | use: loader
76 | })
77 | }
78 | return output
79 | }
80 |
81 | exports.createNotifierCallback = function () {
82 | const notifier = require('node-notifier')
83 |
84 | return (severity, errors) => {
85 | if (severity !== 'error') {
86 | return
87 | }
88 | const error = errors[0]
89 |
90 | const filename = error.file.split('!').pop()
91 | notifier.notify({
92 | title: pkg.name,
93 | message: severity + ': ' + error.name,
94 | subtitle: filename || '',
95 | icon: path.join(__dirname, 'logo.png')
96 | })
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/sidebar/build/vue-loader.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const utils = require('./utils')
3 | const config = require('../config')
4 | const isProduction = process.env.NODE_ENV === 'production'
5 | const sourceMapEnabled = isProduction
6 | ? config.build.productionSourceMap
7 | : config.dev.cssSourceMap
8 |
9 |
10 | module.exports = {
11 | loaders: utils.cssLoaders({
12 | sourceMap: sourceMapEnabled,
13 | extract: isProduction
14 | }),
15 | cssSourceMap: sourceMapEnabled,
16 | transformToRequire: {
17 | video: 'src',
18 | source: 'src',
19 | img: 'src',
20 | image: 'xlink:href'
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/sidebar/build/webpack.base.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const utils = require('./utils')
4 | const config = require('../config')
5 | const vueLoaderConfig = require('./vue-loader.conf')
6 |
7 | function resolve (dir) {
8 | return path.join(__dirname, '..', dir)
9 | }
10 |
11 | module.exports = {
12 | context: path.resolve(__dirname, '../'),
13 | entry: {
14 | app: './src/main.js'
15 | },
16 | output: {
17 | path: config.build.assetsRoot,
18 | filename: '[name].js',
19 | publicPath: process.env.NODE_ENV === 'production'
20 | ? config.build.assetsPublicPath
21 | : config.dev.assetsPublicPath
22 | },
23 | resolve: {
24 | extensions: ['.js', '.vue', '.json'],
25 | alias: {
26 | 'vue$': 'vue/dist/vue.esm.js',
27 | '@': resolve('src'),
28 | }
29 | },
30 | module: {
31 | rules: [
32 | ...(config.dev.useEslint? [{
33 | test: /\.(js|vue)$/,
34 | loader: 'eslint-loader',
35 | enforce: 'pre',
36 | include: [resolve('src'), resolve('test')],
37 | options: {
38 | formatter: require('eslint-friendly-formatter'),
39 | emitWarning: !config.dev.showEslintErrorsInOverlay
40 | }
41 | }] : []),
42 | {
43 | test: /\.vue$/,
44 | loader: 'vue-loader',
45 | options: vueLoaderConfig
46 | },
47 | {
48 | test: /\.js$/,
49 | loader: 'babel-loader',
50 | include: [resolve('src'), resolve('test')]
51 | },
52 | {
53 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
54 | loader: 'url-loader',
55 | options: {
56 | limit: 10000,
57 | name: utils.assetsPath('img/[name].[hash:7].[ext]')
58 | }
59 | },
60 | {
61 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
62 | loader: 'url-loader',
63 | options: {
64 | limit: 10000,
65 | name: utils.assetsPath('media/[name].[hash:7].[ext]')
66 | }
67 | },
68 | {
69 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
70 | loader: 'url-loader',
71 | options: {
72 | limit: 10000,
73 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
74 | }
75 | }
76 | ]
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/sidebar/build/webpack.dev.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const utils = require('./utils')
3 | const webpack = require('webpack')
4 | const config = require('../config')
5 | const merge = require('webpack-merge')
6 | const baseWebpackConfig = require('./webpack.base.conf')
7 | const HtmlWebpackPlugin = require('html-webpack-plugin')
8 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
9 | const portfinder = require('portfinder')
10 |
11 | const devWebpackConfig = merge(baseWebpackConfig, {
12 | module: {
13 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
14 | },
15 | // cheap-module-eval-source-map is faster for development
16 | devtool: config.dev.devtool,
17 |
18 | // these devServer options should be customized in /config/index.js
19 | devServer: {
20 | clientLogLevel: 'warning',
21 | historyApiFallback: true,
22 | hot: true,
23 | host: process.env.HOST || config.dev.host,
24 | port: process.env.PORT || config.dev.port,
25 | open: config.dev.autoOpenBrowser,
26 | overlay: config.dev.errorOverlay ? {
27 | warnings: false,
28 | errors: true,
29 | } : false,
30 | publicPath: config.dev.assetsPublicPath,
31 | proxy: config.dev.proxyTable,
32 | quiet: true, // necessary for FriendlyErrorsPlugin
33 | watchOptions: {
34 | poll: config.dev.poll,
35 | }
36 | },
37 | plugins: [
38 | new webpack.DefinePlugin({
39 | 'process.env': require('../config/dev.env')
40 | }),
41 | new webpack.HotModuleReplacementPlugin(),
42 | new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
43 | new webpack.NoEmitOnErrorsPlugin(),
44 | // https://github.com/ampedandwired/html-webpack-plugin
45 | new HtmlWebpackPlugin({
46 | filename: 'index.html',
47 | template: 'index.html',
48 | inject: true
49 | }),
50 | ]
51 | })
52 |
53 | module.exports = new Promise((resolve, reject) => {
54 | portfinder.basePort = process.env.PORT || config.dev.port
55 | portfinder.getPort((err, port) => {
56 | if (err) {
57 | reject(err)
58 | } else {
59 | // publish the new Port, necessary for e2e tests
60 | process.env.PORT = port
61 | // add port to devServer config
62 | devWebpackConfig.devServer.port = port
63 |
64 | // Add FriendlyErrorsPlugin
65 | devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
66 | compilationSuccessInfo: {
67 | messages: [`Your application is running here: http://${config.dev.host}:${port}`],
68 | },
69 | onErrors: config.dev.notifyOnErrors
70 | ? utils.createNotifierCallback()
71 | : undefined
72 | }))
73 |
74 | resolve(devWebpackConfig)
75 | }
76 | })
77 | })
78 |
--------------------------------------------------------------------------------
/sidebar/build/webpack.test.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | // This is the webpack config used for unit tests.
3 |
4 | const utils = require('./utils')
5 | const webpack = require('webpack')
6 | const merge = require('webpack-merge')
7 | const baseWebpackConfig = require('./webpack.base.conf')
8 |
9 | const webpackConfig = merge(baseWebpackConfig, {
10 | // use inline sourcemap for karma-sourcemap-loader
11 | module: {
12 | rules: utils.styleLoaders()
13 | },
14 | devtool: '#inline-source-map',
15 | resolveLoader: {
16 | alias: {
17 | // necessary to to make lang="scss" work in test when using vue-loader's ?inject option
18 | // see discussion at https://github.com/vuejs/vue-loader/issues/724
19 | 'scss-loader': 'sass-loader'
20 | }
21 | },
22 | plugins: [
23 | new webpack.DefinePlugin({
24 | 'process.env': require('../config/test.env')
25 | })
26 | ]
27 | })
28 |
29 | // no need for app entry during tests
30 | delete webpackConfig.entry
31 |
32 | module.exports = webpackConfig
33 |
--------------------------------------------------------------------------------
/sidebar/config/dev.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const merge = require('webpack-merge')
3 | const prodEnv = require('./prod.env')
4 |
5 | module.exports = merge(prodEnv, {
6 | NODE_ENV: '"development"'
7 | })
8 |
--------------------------------------------------------------------------------
/sidebar/config/index.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | // Template version: 1.2.3
3 | // see http://vuejs-templates.github.io/webpack for documentation.
4 |
5 | const path = require('path')
6 |
7 | module.exports = {
8 | dev: {
9 |
10 | // Paths
11 | assetsSubDirectory: 'static',
12 | assetsPublicPath: '/',
13 | proxyTable: {},
14 |
15 | // Various Dev Server settings
16 | host: 'localhost', // can be overwritten by process.env.HOST
17 | port: 8080, // can be overwritten by process.env.HOST, if port is in use, a free one will be determined
18 | autoOpenBrowser: false,
19 | errorOverlay: true,
20 | notifyOnErrors: true,
21 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
22 |
23 | // Use Eslint Loader?
24 | // If true, your code will be linted during bundling and
25 | // linting errors and warnings will be shown in the console.
26 | useEslint: true,
27 | // If true, eslint errors and warnings will also be shown in the error overlay
28 | // in the browser.
29 | showEslintErrorsInOverlay: false,
30 |
31 | /**
32 | * Source Maps
33 | */
34 |
35 | // https://webpack.js.org/configuration/devtool/#development
36 | devtool: 'eval-source-map',
37 |
38 | // If you have problems debugging vue-files in devtools,
39 | // set this to false - it *may* help
40 | // https://vue-loader.vuejs.org/en/options.html#cachebusting
41 | cacheBusting: true,
42 |
43 | // CSS Sourcemaps off by default because relative paths are "buggy"
44 | // with this option, according to the CSS-Loader README
45 | // (https://github.com/webpack/css-loader#sourcemaps)
46 | // In our experience, they generally work as expected,
47 | // just be aware of this issue when enabling this option.
48 | cssSourceMap: false,
49 | },
50 |
51 | build: {
52 | // Template for index.html
53 | index: path.resolve(__dirname, '../dist/index.html'),
54 |
55 | // Paths
56 | assetsRoot: path.resolve(__dirname, '../dist'),
57 | assetsSubDirectory: 'static',
58 | assetsPublicPath: '/',
59 |
60 | /**
61 | * Source Maps
62 | */
63 |
64 | productionSourceMap: true,
65 | // https://webpack.js.org/configuration/devtool/#production
66 | devtool: '#source-map',
67 |
68 | // Gzip off by default as many popular static hosts such as
69 | // Surge or Netlify already gzip all static assets for you.
70 | // Before setting to `true`, make sure to:
71 | // npm install --save-dev compression-webpack-plugin
72 | productionGzip: false,
73 | productionGzipExtensions: ['js', 'css'],
74 |
75 | // Run the build command with an extra argument to
76 | // View the bundle analyzer report after build finishes:
77 | // `npm run build --report`
78 | // Set to `true` or `false` to always turn it on or off
79 | bundleAnalyzerReport: process.env.npm_config_report
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/sidebar/config/prod.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | module.exports = {
3 | NODE_ENV: '"production"'
4 | }
5 |
--------------------------------------------------------------------------------
/sidebar/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | sidebar
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/sidebar/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sidebar",
3 | "version": "1.0.0",
4 | "description": "A Vue.js project",
5 | "author": "ramsaylanier",
6 | "private": true,
7 | "scripts": {
8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
9 | "start": "npm run dev",
10 | "lint": "eslint --ext .js,.vue src",
11 | "build": "node build/build.js"
12 | },
13 | "dependencies": {
14 | "css-loader": "^0.28.7",
15 | "gsap": "^1.20.3",
16 | "vue": "^2.5.2",
17 | "vue-style-loader": "^3.0.3",
18 | "vuex": "^3.0.1"
19 | },
20 | "devDependencies": {
21 | "autoprefixer": "^7.1.2",
22 | "babel-core": "^6.22.1",
23 | "babel-eslint": "^7.1.1",
24 | "babel-loader": "^7.1.1",
25 | "babel-plugin-transform-runtime": "^6.22.0",
26 | "babel-preset-env": "^1.3.2",
27 | "babel-preset-stage-2": "^6.22.0",
28 | "babel-register": "^6.22.0",
29 | "chalk": "^2.0.1",
30 | "copy-webpack-plugin": "^4.0.1",
31 | "css-loader": "^0.28.0",
32 | "eslint": "^3.19.0",
33 | "eslint-friendly-formatter": "^3.0.0",
34 | "eslint-loader": "^1.7.1",
35 | "eslint-plugin-html": "^3.0.0",
36 | "eslint-config-standard": "^10.2.1",
37 | "eslint-plugin-promise": "^3.4.0",
38 | "eslint-plugin-standard": "^3.0.1",
39 | "eslint-plugin-import": "^2.7.0",
40 | "eslint-plugin-node": "^5.2.0",
41 | "eventsource-polyfill": "^0.9.6",
42 | "extract-text-webpack-plugin": "^3.0.0",
43 | "file-loader": "^1.1.4",
44 | "friendly-errors-webpack-plugin": "^1.6.1",
45 | "html-webpack-plugin": "^2.30.1",
46 | "webpack-bundle-analyzer": "^2.9.0",
47 | "node-notifier": "^5.1.2",
48 | "postcss-import": "^11.0.0",
49 | "postcss-loader": "^2.0.8",
50 | "semver": "^5.3.0",
51 | "shelljs": "^0.7.6",
52 | "optimize-css-assets-webpack-plugin": "^3.2.0",
53 | "ora": "^1.2.0",
54 | "rimraf": "^2.6.0",
55 | "url-loader": "^0.5.8",
56 | "vue-loader": "^13.3.0",
57 | "vue-style-loader": "^3.0.1",
58 | "vue-template-compiler": "^2.5.2",
59 | "portfinder": "^1.0.13",
60 | "webpack": "^3.6.0",
61 | "webpack-dev-server": "^2.9.1",
62 | "webpack-merge": "^4.1.0"
63 | },
64 | "engines": {
65 | "node": ">= 4.0.0",
66 | "npm": ">= 3.0.0"
67 | },
68 | "browserslist": [
69 | "> 1%",
70 | "last 2 versions",
71 | "not ie <= 8"
72 | ]
73 | }
74 |
--------------------------------------------------------------------------------
/sidebar/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
22 |
23 |
35 |
36 |
46 |
--------------------------------------------------------------------------------
/sidebar/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ramsaylanier/vue-tutorials/26cada54a6f81bc41c0fe786d1d278faf5431e10/sidebar/src/assets/logo.png
--------------------------------------------------------------------------------
/sidebar/src/components/sidebar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
31 |
32 |
--------------------------------------------------------------------------------
/sidebar/src/components/sidebarToggle.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
25 |
26 |
--------------------------------------------------------------------------------
/sidebar/src/main.js:
--------------------------------------------------------------------------------
1 | // The Vue build version to load with the `import` command
2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
3 | import Vue from 'vue'
4 | import App from './App'
5 | import store from './store/index.js'
6 |
7 | Vue.config.productionTip = false
8 |
9 | /* eslint-disable no-new */
10 | new Vue({
11 | el: '#app',
12 | store,
13 | template: ' ',
14 | components: { App }
15 | })
16 |
--------------------------------------------------------------------------------
/sidebar/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 | import ui from './modules/ui'
4 |
5 | Vue.use(Vuex)
6 |
7 | const debug = process.env.NODE_ENV !== 'production'
8 |
9 | export default new Vuex.Store({
10 | modules: {
11 | ui
12 | },
13 | strict: debug
14 | })
15 |
--------------------------------------------------------------------------------
/sidebar/src/store/modules/ui.js:
--------------------------------------------------------------------------------
1 | import * as types from '../mutation-types'
2 |
3 | // initial state
4 | // shape: [{ id, quantity }]
5 | const state = {
6 | sidebarOpen: false
7 | }
8 |
9 | // getters
10 | const getters = {
11 | sidebarOpen: state => state.sidebarOpen
12 | }
13 |
14 | // actions
15 | const actions = {
16 | toggleSidebar ({ commit, state }) {
17 | commit(types.TOGGLE_SIDEBAR)
18 | }
19 | }
20 |
21 | // mutations
22 | const mutations = {
23 | [types.TOGGLE_SIDEBAR] (state) {
24 | state.sidebarOpen = !state.sidebarOpen
25 | }
26 | }
27 |
28 | export default {
29 | state,
30 | getters,
31 | actions,
32 | mutations
33 | }
34 |
--------------------------------------------------------------------------------
/sidebar/src/store/mutation-types.js:
--------------------------------------------------------------------------------
1 | export const TOGGLE_SIDEBAR = 'TOGGLE_SIDEBAR'
2 |
--------------------------------------------------------------------------------
/sidebar/static/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ramsaylanier/vue-tutorials/26cada54a6f81bc41c0fe786d1d278faf5431e10/sidebar/static/.gitkeep
--------------------------------------------------------------------------------
/thumbnail-creator/.serverless/cloudformation-template-create-stack.json:
--------------------------------------------------------------------------------
1 | {
2 | "AWSTemplateFormatVersion": "2010-09-09",
3 | "Description": "The AWS CloudFormation template for this Serverless application",
4 | "Resources": {
5 | "ServerlessDeploymentBucket": {
6 | "Type": "AWS::S3::Bucket"
7 | }
8 | },
9 | "Outputs": {
10 | "ServerlessDeploymentBucketName": {
11 | "Value": {
12 | "Ref": "ServerlessDeploymentBucket"
13 | }
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/thumbnail-creator/.serverless/thumbnail-creator.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ramsaylanier/vue-tutorials/26cada54a6f81bc41c0fe786d1d278faf5431e10/thumbnail-creator/.serverless/thumbnail-creator.zip
--------------------------------------------------------------------------------
/thumbnail-creator/README.md:
--------------------------------------------------------------------------------
1 | # Thumbnail Creator
2 |
3 | A simple web application that uploads files to an S3 bucket and generates thumbnails using AWS Lambda.
4 |
5 | ## Articles on Medium
6 |
7 | *READ THESE FIRST*
8 |
9 | [Part 1 - The Setup](https://medium.com/@rmmmsy/creating-an-image-thumbnail-generator-using-vue-aws-and-serverless-part-1-the-setup-5d187b0bb1e1)
10 |
11 | [Part 2 - The Upload](https://medium.com/@rmmmsy/creating-an-image-thumbnail-generator-using-vue-aws-and-serverless-part-2-the-upload-614863e7d12b)
12 |
13 | [Part 3 - The Lambda](https://medium.com/@rmmmsy/creating-an-image-thumbnail-generator-using-vue-aws-and-serverless-part-3-the-lambda-f08db7d0d624)
14 |
15 | [Part 4 - The Finish](https://medium.com/@rmmmsy/creating-an-image-thumbnail-generator-using-vue-aws-and-serverless-part-4-the-finish-1988eff2d7ed)
16 |
17 | ## Things to note
18 |
19 | ### Serverless.yml
20 |
21 | Please make sure you change the bucket names in the `serverless.yml` file or else you'll have a bad time.
22 |
23 | ### Testing the lambda
24 |
25 | Please read [Part 3 - The Lambda](https://medium.com/@rmmmsy/creating-an-image-thumbnail-generator-using-vue-aws-and-serverless-part-3-the-lambda-f08db7d0d624) carefully when it comes to testing your lambda function. You'll need to have Docker installed. Just read the story, okay?!
26 |
27 |
28 | ### Bugs
29 |
30 | I'm sure there are some - create an issue and be nice.
31 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["env", {
4 | "modules": false
5 | }],
6 | "stage-2"
7 | ],
8 | "plugins": ["transform-runtime"]
9 | }
10 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/.eslintignore:
--------------------------------------------------------------------------------
1 | /build/
2 | /config/
3 | /dist/
4 | /*.js
5 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // https://eslint.org/docs/user-guide/configuring
2 |
3 | module.exports = {
4 | root: true,
5 | parser: 'babel-eslint',
6 | parserOptions: {
7 | sourceType: 'module'
8 | },
9 | env: {
10 | browser: true,
11 | },
12 | // https://github.com/standard/standard/blob/master/docs/RULES-en.md
13 | extends: 'standard',
14 | // required to lint *.vue files
15 | plugins: [
16 | 'html'
17 | ],
18 | // add your custom rules here
19 | 'rules': {
20 | // allow paren-less arrow functions
21 | 'arrow-parens': 0,
22 | // allow async-await
23 | 'generator-star-spacing': 0,
24 | // allow debugger during development
25 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | /dist/
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Editor directories and files
9 | .idea
10 | .vscode
11 | *.suo
12 | *.ntvs*
13 | *.njsproj
14 | *.sln
15 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/.postcssrc.js:
--------------------------------------------------------------------------------
1 | // https://github.com/michael-ciniawsky/postcss-load-config
2 |
3 | module.exports = {
4 | "plugins": {
5 | // to edit target browsers: use "browserslist" field in package.json
6 | "postcss-import": {},
7 | "autoprefixer": {}
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/README.md:
--------------------------------------------------------------------------------
1 | # client
2 |
3 | > A Vue.js project
4 |
5 | ## Build Setup
6 |
7 | ``` bash
8 | # install dependencies
9 | npm install
10 |
11 | # serve with hot reload at localhost:8080
12 | npm run dev
13 |
14 | # build for production with minification
15 | npm run build
16 |
17 | # build for production and view the bundle analyzer report
18 | npm run build --report
19 | ```
20 |
21 | For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
22 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/build/build.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | require('./check-versions')()
3 |
4 | process.env.NODE_ENV = 'production'
5 |
6 | const ora = require('ora')
7 | const rm = require('rimraf')
8 | const path = require('path')
9 | const chalk = require('chalk')
10 | const webpack = require('webpack')
11 | const config = require('../config')
12 | const webpackConfig = require('./webpack.prod.conf')
13 |
14 | const spinner = ora('building for production...')
15 | spinner.start()
16 |
17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
18 | if (err) throw err
19 | webpack(webpackConfig, function (err, stats) {
20 | spinner.stop()
21 | if (err) throw err
22 | process.stdout.write(stats.toString({
23 | colors: true,
24 | modules: false,
25 | children: false,
26 | chunks: false,
27 | chunkModules: false
28 | }) + '\n\n')
29 |
30 | if (stats.hasErrors()) {
31 | console.log(chalk.red(' Build failed with errors.\n'))
32 | process.exit(1)
33 | }
34 |
35 | console.log(chalk.cyan(' Build complete.\n'))
36 | console.log(chalk.yellow(
37 | ' Tip: built files are meant to be served over an HTTP server.\n' +
38 | ' Opening index.html over file:// won\'t work.\n'
39 | ))
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/build/check-versions.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const chalk = require('chalk')
3 | const semver = require('semver')
4 | const packageConfig = require('../package.json')
5 | const shell = require('shelljs')
6 | function exec (cmd) {
7 | return require('child_process').execSync(cmd).toString().trim()
8 | }
9 |
10 | const versionRequirements = [
11 | {
12 | name: 'node',
13 | currentVersion: semver.clean(process.version),
14 | versionRequirement: packageConfig.engines.node
15 | }
16 | ]
17 |
18 | if (shell.which('npm')) {
19 | versionRequirements.push({
20 | name: 'npm',
21 | currentVersion: exec('npm --version'),
22 | versionRequirement: packageConfig.engines.npm
23 | })
24 | }
25 |
26 | module.exports = function () {
27 | const warnings = []
28 | for (let i = 0; i < versionRequirements.length; i++) {
29 | const mod = versionRequirements[i]
30 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
31 | warnings.push(mod.name + ': ' +
32 | chalk.red(mod.currentVersion) + ' should be ' +
33 | chalk.green(mod.versionRequirement)
34 | )
35 | }
36 | }
37 |
38 | if (warnings.length) {
39 | console.log('')
40 | console.log(chalk.yellow('To use this template, you must update following to modules:'))
41 | console.log()
42 | for (let i = 0; i < warnings.length; i++) {
43 | const warning = warnings[i]
44 | console.log(' ' + warning)
45 | }
46 | console.log()
47 | process.exit(1)
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/build/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ramsaylanier/vue-tutorials/26cada54a6f81bc41c0fe786d1d278faf5431e10/thumbnail-creator/client/build/logo.png
--------------------------------------------------------------------------------
/thumbnail-creator/client/build/utils.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const config = require('../config')
4 | const ExtractTextPlugin = require('extract-text-webpack-plugin')
5 | const pkg = require('../package.json')
6 |
7 | exports.assetsPath = function (_path) {
8 | const assetsSubDirectory = process.env.NODE_ENV === 'production'
9 | ? config.build.assetsSubDirectory
10 | : config.dev.assetsSubDirectory
11 | return path.posix.join(assetsSubDirectory, _path)
12 | }
13 |
14 | exports.cssLoaders = function (options) {
15 | options = options || {}
16 |
17 | const cssLoader = {
18 | loader: 'css-loader',
19 | options: {
20 | sourceMap: options.sourceMap
21 | }
22 | }
23 |
24 | var postcssLoader = {
25 | loader: 'postcss-loader',
26 | options: {
27 | sourceMap: options.sourceMap
28 | }
29 | }
30 |
31 | // generate loader string to be used with extract text plugin
32 | function generateLoaders (loader, loaderOptions) {
33 | const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
34 | if (loader) {
35 | loaders.push({
36 | loader: loader + '-loader',
37 | options: Object.assign({}, loaderOptions, {
38 | sourceMap: options.sourceMap
39 | })
40 | })
41 | }
42 |
43 | // Extract CSS when that option is specified
44 | // (which is the case during production build)
45 | if (options.extract) {
46 | return ExtractTextPlugin.extract({
47 | use: loaders,
48 | fallback: 'vue-style-loader'
49 | })
50 | } else {
51 | return ['vue-style-loader'].concat(loaders)
52 | }
53 | }
54 |
55 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html
56 | return {
57 | css: generateLoaders(),
58 | postcss: generateLoaders(),
59 | less: generateLoaders('less'),
60 | sass: generateLoaders('sass', { indentedSyntax: true }),
61 | scss: generateLoaders('sass'),
62 | stylus: generateLoaders('stylus'),
63 | styl: generateLoaders('stylus')
64 | }
65 | }
66 |
67 | // Generate loaders for standalone style files (outside of .vue)
68 | exports.styleLoaders = function (options) {
69 | const output = []
70 | const loaders = exports.cssLoaders(options)
71 | for (const extension in loaders) {
72 | const loader = loaders[extension]
73 | output.push({
74 | test: new RegExp('\\.' + extension + '$'),
75 | use: loader
76 | })
77 | }
78 | return output
79 | }
80 |
81 | exports.createNotifierCallback = function () {
82 | const notifier = require('node-notifier')
83 |
84 | return (severity, errors) => {
85 | if (severity !== 'error') {
86 | return
87 | }
88 | const error = errors[0]
89 |
90 | const filename = error.file && error.file.split('!').pop()
91 | notifier.notify({
92 | title: pkg.name,
93 | message: severity + ': ' + error.name,
94 | subtitle: filename || '',
95 | icon: path.join(__dirname, 'logo.png')
96 | })
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/build/vue-loader.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const utils = require('./utils')
3 | const config = require('../config')
4 | const isProduction = process.env.NODE_ENV === 'production'
5 | const sourceMapEnabled = isProduction
6 | ? config.build.productionSourceMap
7 | : config.dev.cssSourceMap
8 |
9 |
10 | module.exports = {
11 | loaders: utils.cssLoaders({
12 | sourceMap: sourceMapEnabled,
13 | extract: isProduction
14 | }),
15 | cssSourceMap: sourceMapEnabled,
16 | cacheBusting: config.dev.cacheBusting,
17 | transformToRequire: {
18 | video: 'src',
19 | source: 'src',
20 | img: 'src',
21 | image: 'xlink:href'
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/build/webpack.base.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const utils = require('./utils')
4 | const config = require('../config')
5 | const Config = require('config')
6 | const fs = require('fs')
7 | const vueLoaderConfig = require('./vue-loader.conf')
8 |
9 | fs.writeFileSync(path.resolve(__dirname, '../config/client.json'), JSON.stringify(Config))
10 |
11 | function resolve (dir) {
12 | return path.join(__dirname, '..', dir)
13 | }
14 |
15 | module.exports = {
16 | entry: {
17 | app: './src/main.js'
18 | },
19 | output: {
20 | path: config.build.assetsRoot,
21 | filename: '[name].js',
22 | publicPath: process.env.NODE_ENV === 'production'
23 | ? config.build.assetsPublicPath
24 | : config.dev.assetsPublicPath
25 | },
26 | resolve: {
27 | extensions: ['.js', '.vue', '.json'],
28 | alias: {
29 | 'vue$': 'vue/dist/vue.esm.js',
30 | '@': resolve('src'),
31 | 'config': resolve('config/client.json')
32 | }
33 | },
34 | module: {
35 | rules: [
36 | {
37 | test: /\.(js|vue)$/,
38 | loader: 'eslint-loader',
39 | enforce: 'pre',
40 | include: [resolve('src'), resolve('test')],
41 | options: {
42 | formatter: require('eslint-friendly-formatter')
43 | }
44 | },
45 | {
46 | test: /\.vue$/,
47 | loader: 'vue-loader',
48 | options: vueLoaderConfig
49 | },
50 | {
51 | test: /\.js$/,
52 | loader: 'babel-loader',
53 | include: [resolve('src'), resolve('test')]
54 | },
55 | {
56 | test: /\.(graphql|gql)$/,
57 | exclude: /node_modules/,
58 | use: {
59 | loader: 'graphql-tag/loader'
60 | }
61 | },
62 | {
63 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
64 | loader: 'url-loader',
65 | options: {
66 | limit: 10000,
67 | name: utils.assetsPath('img/[name].[hash:7].[ext]')
68 | }
69 | },
70 | {
71 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
72 | loader: 'url-loader',
73 | options: {
74 | limit: 10000,
75 | name: utils.assetsPath('media/[name].[hash:7].[ext]')
76 | }
77 | },
78 | {
79 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
80 | loader: 'url-loader',
81 | options: {
82 | limit: 10000,
83 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
84 | }
85 | }
86 | ]
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/build/webpack.dev.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const utils = require('./utils')
3 | const webpack = require('webpack')
4 | const config = require('../config')
5 | const merge = require('webpack-merge')
6 | const baseWebpackConfig = require('./webpack.base.conf')
7 | const HtmlWebpackPlugin = require('html-webpack-plugin')
8 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
9 | const portfinder = require('portfinder')
10 |
11 | const devWebpackConfig = merge(baseWebpackConfig, {
12 | module: {
13 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
14 | },
15 | // cheap-module-eval-source-map is faster for development
16 | devtool: config.dev.devtool,
17 |
18 | // these devServer options should be customized in /config/index.js
19 | devServer: {
20 | clientLogLevel: 'warning',
21 | historyApiFallback: true,
22 | hot: true,
23 | compress: true,
24 | host: process.env.HOST || config.dev.host,
25 | port: process.env.PORT || config.dev.port,
26 | open: config.dev.autoOpenBrowser,
27 | overlay: config.dev.errorOverlay ? {
28 | warnings: false,
29 | errors: true,
30 | } : false,
31 | publicPath: config.dev.assetsPublicPath,
32 | proxy: config.dev.proxyTable,
33 | quiet: true, // necessary for FriendlyErrorsPlugin
34 | watchOptions: {
35 | poll: config.dev.poll,
36 | }
37 | },
38 | plugins: [
39 | new webpack.DefinePlugin({
40 | 'process.env': require('../config/dev.env')
41 | }),
42 | new webpack.HotModuleReplacementPlugin(),
43 | new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
44 | new webpack.NoEmitOnErrorsPlugin(),
45 | // https://github.com/ampedandwired/html-webpack-plugin
46 | new HtmlWebpackPlugin({
47 | filename: 'index.html',
48 | template: 'index.html',
49 | inject: true
50 | }),
51 | ]
52 | })
53 |
54 | module.exports = new Promise((resolve, reject) => {
55 | portfinder.basePort = process.env.PORT || config.dev.port
56 | portfinder.getPort((err, port) => {
57 | if (err) {
58 | reject(err)
59 | } else {
60 | // publish the new Port, necessary for e2e tests
61 | process.env.PORT = port
62 | // add port to devServer config
63 | devWebpackConfig.devServer.port = port
64 |
65 | // Add FriendlyErrorsPlugin
66 | devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
67 | compilationSuccessInfo: {
68 | messages: [`Your application is running here: http://${config.dev.host}:${port}`],
69 | },
70 | onErrors: config.dev.notifyOnErrors
71 | ? utils.createNotifierCallback()
72 | : undefined
73 | }))
74 |
75 | resolve(devWebpackConfig)
76 | }
77 | })
78 | })
79 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/config/dev.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const merge = require('webpack-merge')
3 | const prodEnv = require('./prod.env')
4 |
5 | module.exports = merge(prodEnv, {
6 | NODE_ENV: '"development"'
7 | })
8 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/config/index.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | // Template version: 1.2.4
3 | // see http://vuejs-templates.github.io/webpack for documentation.
4 |
5 | const path = require('path')
6 |
7 | module.exports = {
8 | dev: {
9 |
10 | // Paths
11 | assetsSubDirectory: 'static',
12 | assetsPublicPath: '/',
13 | proxyTable: {},
14 |
15 | // Various Dev Server settings
16 | host: 'localhost', // can be overwritten by process.env.HOST
17 | port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
18 | autoOpenBrowser: false,
19 | errorOverlay: true,
20 | notifyOnErrors: true,
21 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
22 |
23 | // Use Eslint Loader?
24 | // If true, your code will be linted during bundling and
25 | // linting errors and warnings will be shown in the console.
26 | useEslint: true,
27 | // If true, eslint errors and warnings will also be shown in the error overlay
28 | // in the browser.
29 | showEslintErrorsInOverlay: false,
30 |
31 | /**
32 | * Source Maps
33 | */
34 |
35 | // https://webpack.js.org/configuration/devtool/#development
36 | devtool: 'eval-source-map',
37 |
38 | // If you have problems debugging vue-files in devtools,
39 | // set this to false - it *may* help
40 | // https://vue-loader.vuejs.org/en/options.html#cachebusting
41 | cacheBusting: true,
42 |
43 | // CSS Sourcemaps off by default because relative paths are "buggy"
44 | // with this option, according to the CSS-Loader README
45 | // (https://github.com/webpack/css-loader#sourcemaps)
46 | // In our experience, they generally work as expected,
47 | // just be aware of this issue when enabling this option.
48 | cssSourceMap: false,
49 | },
50 |
51 | build: {
52 | // Template for index.html
53 | index: path.resolve(__dirname, '../dist/index.html'),
54 |
55 | // Paths
56 | assetsRoot: path.resolve(__dirname, '../dist'),
57 | assetsSubDirectory: 'static',
58 | assetsPublicPath: '/',
59 |
60 | /**
61 | * Source Maps
62 | */
63 |
64 | productionSourceMap: true,
65 | // https://webpack.js.org/configuration/devtool/#production
66 | devtool: '#source-map',
67 |
68 | // Gzip off by default as many popular static hosts such as
69 | // Surge or Netlify already gzip all static assets for you.
70 | // Before setting to `true`, make sure to:
71 | // npm install --save-dev compression-webpack-plugin
72 | productionGzip: false,
73 | productionGzipExtensions: ['js', 'css'],
74 |
75 | // Run the build command with an extra argument to
76 | // View the bundle analyzer report after build finishes:
77 | // `npm run build --report`
78 | // Set to `true` or `false` to always turn it on or off
79 | bundleAnalyzerReport: process.env.npm_config_report
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/config/prod.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | module.exports = {
3 | NODE_ENV: '"production"'
4 | }
5 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | client
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "1.0.0",
4 | "description": "A Vue.js project",
5 | "author": "",
6 | "private": true,
7 | "scripts": {
8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
9 | "start": "npm run dev",
10 | "lint": "eslint --ext .js,.vue src",
11 | "build": "node build/build.js",
12 | "deploy": "npm run build && aws s3 sync dist/ s3://thumbnail-creator-tutorial"
13 | },
14 | "dependencies": {
15 | "aws-sdk": "^2.157.0",
16 | "config": "^1.28.1",
17 | "vue": "^2.5.2",
18 | "vue-router": "^3.0.1"
19 | },
20 | "devDependencies": {
21 | "autoprefixer": "^7.1.2",
22 | "babel-core": "^6.22.1",
23 | "babel-eslint": "^7.1.1",
24 | "babel-loader": "^7.1.1",
25 | "babel-plugin-transform-runtime": "^6.22.0",
26 | "babel-preset-env": "^1.3.2",
27 | "babel-preset-stage-2": "^6.22.0",
28 | "babel-register": "^6.22.0",
29 | "chalk": "^2.0.1",
30 | "copy-webpack-plugin": "^4.0.1",
31 | "css-loader": "^0.28.0",
32 | "eslint": "^3.19.0",
33 | "eslint-friendly-formatter": "^3.0.0",
34 | "eslint-loader": "^1.7.1",
35 | "eslint-plugin-html": "^3.0.0",
36 | "eslint-config-standard": "^10.2.1",
37 | "eslint-plugin-promise": "^3.4.0",
38 | "eslint-plugin-standard": "^3.0.1",
39 | "eslint-plugin-import": "^2.7.0",
40 | "eslint-plugin-node": "^5.2.0",
41 | "eventsource-polyfill": "^0.9.6",
42 | "extract-text-webpack-plugin": "^3.0.0",
43 | "file-loader": "^1.1.4",
44 | "friendly-errors-webpack-plugin": "^1.6.1",
45 | "html-webpack-plugin": "^2.30.1",
46 | "webpack-bundle-analyzer": "^2.9.0",
47 | "node-notifier": "^5.1.2",
48 | "postcss-import": "^11.0.0",
49 | "postcss-loader": "^2.0.8",
50 | "semver": "^5.3.0",
51 | "shelljs": "^0.7.6",
52 | "optimize-css-assets-webpack-plugin": "^3.2.0",
53 | "ora": "^1.2.0",
54 | "rimraf": "^2.6.0",
55 | "url-loader": "^0.5.8",
56 | "vue-loader": "^13.3.0",
57 | "vue-style-loader": "^3.0.1",
58 | "vue-template-compiler": "^2.5.2",
59 | "portfinder": "^1.0.13",
60 | "webpack": "^3.6.0",
61 | "webpack-dev-server": "^2.9.1",
62 | "webpack-merge": "^4.1.0"
63 | },
64 | "engines": {
65 | "node": ">= 4.0.0",
66 | "npm": ">= 3.0.0"
67 | },
68 | "browserslist": [
69 | "> 1%",
70 | "last 2 versions",
71 | "not ie <= 8"
72 | ]
73 | }
74 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
20 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ramsaylanier/vue-tutorials/26cada54a6f81bc41c0fe786d1d278faf5431e10/thumbnail-creator/client/src/assets/logo.png
--------------------------------------------------------------------------------
/thumbnail-creator/client/src/aws.js:
--------------------------------------------------------------------------------
1 | import {config, S3} from 'aws-sdk'
2 | import {aws} from 'config'
3 | import {map} from 'lodash'
4 |
5 | // Remember to add the name of your thumbnail bucket to the config file
6 | const {region, accessKeyId, secretAccessKey, uploadBucket, thumbnailBucket} = aws
7 |
8 | config.update({
9 | region: region,
10 | credentials: {
11 | accessKeyId: accessKeyId,
12 | secretAccessKey: secretAccessKey
13 | }
14 | })
15 |
16 | config.setPromisesDependency(Promise)
17 |
18 | export const s3UploadBucket = new S3({
19 | apiVersion: '2006-03-01',
20 | params: {
21 | Bucket: uploadBucket
22 | }
23 | })
24 |
25 | // We create a new S3 object for the thumbnail bucket.
26 | export const s3ThumbnailBucket = new S3({
27 | apiVersion: '2006-03-01',
28 | params: {
29 | Bucket: thumbnailBucket
30 | }
31 | })
32 |
33 | export const uploadFiles = files => {
34 | return Promise.all(
35 | map(files, file => {
36 | return s3UploadBucket.putObject({
37 | Key: file.name,
38 | Body: file
39 | }).promise()
40 | })
41 | )
42 | }
43 |
44 | export const getUploads = () => {
45 | return s3UploadBucket.listObjects().promise().then(r => {
46 | return r.Contents
47 | })
48 | }
49 |
50 | // We use the Prefix option with a value of the key argument. The key
51 | // is the name of the uploaded file without the file extension.
52 | export const getThumbnails = (key) => {
53 | return s3ThumbnailBucket.listObjects({
54 | Prefix: key
55 | }).promise().then(r => {
56 | return r.Contents
57 | })
58 | }
59 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/src/components/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
29 |
30 |
36 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/src/components/appHeader.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/src/components/list.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
{{upload.Key}}
9 |
10 |
11 |
12 |
13 |
14 |
15 |
50 |
51 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/src/components/upload.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Back
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
34 |
35 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/src/components/uploadForm.vue:
--------------------------------------------------------------------------------
1 |
2 |
23 |
24 |
25 |
52 |
53 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/src/main.js:
--------------------------------------------------------------------------------
1 | // The Vue build version to load with the `import` command
2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
3 | import Vue from 'vue'
4 | import App from './App'
5 | import router from './router'
6 |
7 | Vue.config.productionTip = false
8 |
9 | /* eslint-disable no-new */
10 | new Vue({
11 | el: '#app',
12 | router,
13 | template: ' ',
14 | components: { App }
15 | })
16 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 | import Home from '@/components/Home'
4 | import Upload from '@/components/upload'
5 |
6 | Vue.use(Router)
7 |
8 | export default new Router({
9 | routes: [
10 | {
11 | path: '/',
12 | name: 'Home',
13 | component: Home
14 | },
15 | {
16 | path: '/upload/:key',
17 | name: 'Upload',
18 | component: Upload
19 | }
20 | ]
21 | })
22 |
--------------------------------------------------------------------------------
/thumbnail-creator/client/static/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ramsaylanier/vue-tutorials/26cada54a6f81bc41c0fe786d1d278faf5431e10/thumbnail-creator/client/static/.gitkeep
--------------------------------------------------------------------------------
/thumbnail-creator/handlers/test.json:
--------------------------------------------------------------------------------
1 | {
2 | "Records": [
3 | {
4 | "s3": {
5 | "bucket":{
6 | "name":"thumbnail-creator-tutorial-uploads"
7 | },
8 | "object":{
9 | "key":"Screen Shot 2017-11-30 at 10.27.47 AM.png"
10 | }
11 | }
12 | }
13 | ]
14 | }
--------------------------------------------------------------------------------
/thumbnail-creator/handlers/transform.js:
--------------------------------------------------------------------------------
1 | const AWS = require('aws-sdk')
2 | const sharp = require('sharp')
3 | const config = require('client/config/production.json')
4 |
5 | AWS.config.update({
6 | credentials: {
7 | accessKeyId: config.aws.accessKeyId,
8 | secretAccessKey: config.aws.secretAccessKey
9 | }
10 | })
11 |
12 | AWS.config.setPromisesDependency(Promise)
13 |
14 | const getFileExtension = filename => {
15 | var ext = /^.+\.([^.]+)$/.exec(filename);
16 | return ext == null ? "" : ext[1];
17 | }
18 |
19 | const s3UploadBucket = new AWS.S3({
20 | apiVersion: '2006-03-01',
21 | params: {
22 | Bucket: config.aws.uploadBucket
23 | }
24 | })
25 |
26 | const s3ThumbnailBucket = new AWS.S3({
27 | apiVersion: '2006-03-01',
28 | params: {
29 | Bucket: config.aws.thumbnailBucket
30 | }
31 | })
32 |
33 | const transforms = [200, 400, 600]
34 |
35 | module.exports.transform = (event, context, callback) => {
36 | const {key} = event.Records[0].s3.object
37 |
38 | // if you put spaces in your filename, the event Key replaces them with '+'. We need
39 | // to undo that before getting the object. Then we remove the exntesion from the key.
40 | const sanitizedKey = key.replace(/\+/g, ' ')
41 | const keyWithoutExtension = sanitizedKey.replace(/.[^.]+$/, '')
42 |
43 | s3UploadBucket.getObject({Key: sanitizedKey}).promise().then(r => {
44 | transforms.map(t => {
45 | sharp(r.Body)
46 | .resize(t, t)
47 | .max()
48 | .toFormat('jpeg')
49 | .toBuffer()
50 | .then( data => {
51 | s3ThumbnailBucket.putObject({
52 | Body: data,
53 | Key: `${keyWithoutExtension}-${t}.jpg`
54 | }).promise().then( res => {
55 | console.log(res)
56 | })
57 | })
58 | })
59 | })
60 | }
--------------------------------------------------------------------------------
/thumbnail-creator/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "thumbnail-creator",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "test:transform": "docker run -v \"$PWD\":/var/task lambci/lambda:nodejs6.10 handlers/transform.transform \"$(cat handlers/test.json)\"",
9 | "extract:sharp": "tar -xzvf ./sharp/tarballs/sharp-0.18.4-aws-lambda-linux-x64-node-6.10.1.tar.gz -C ./",
10 | "build:sharp": "docker build -t serverless-sharp-image ./sharp && docker run -v \"$PWD/sharp\":/var/task serverless-sharp-image && npm run extract:sharp",
11 | "deploy": "sls deploy -v"
12 | },
13 | "keywords": [],
14 | "author": "",
15 | "license": "ISC",
16 | "dependencies": {
17 | "sharp": "^0.18.4"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/thumbnail-creator/serverless.yml:
--------------------------------------------------------------------------------
1 | service: thumbnail-creator
2 |
3 | custom:
4 | bucket: thumbnail-creator-tutorial
5 | uploadBucket: ${self:custom.bucket}-uploads
6 | thumbnailBucket: ${self:custom.bucket}-thumbnails
7 |
8 | provider:
9 | name: aws
10 | runtime: nodejs6.10
11 |
12 | functions:
13 | transform:
14 | handler: handlers/transform.transform
15 | events:
16 | - s3:
17 | bucket: ${self:custom.uploadBucket}
18 | event: s3:ObjectCreated:*
19 |
20 | resources:
21 | Resources:
22 | UploadBucketS3BucketPolicy:
23 | Type: AWS::S3::BucketPolicy
24 | Properties:
25 | Bucket:
26 | Ref: WebAppS3Bucket
27 | PolicyDocument:
28 | Statement:
29 | - Sid: PublicReadPutObject
30 | Effect: Allow
31 | Principal: "*"
32 | Action:
33 | - s3:PutObject
34 | Resource: arn:aws:s3:::${self:custom.uploadBucket}/*
35 | ThumbnailsS3Bucket:
36 | Type: AWS::S3::Bucket
37 | Properties:
38 | BucketName: ${self:custom.thumbnailBucket}
39 | WebAppS3Bucket:
40 | Type: AWS::S3::Bucket
41 | Properties:
42 | BucketName: ${self:custom.bucket}
43 | AccessControl: PublicRead
44 | WebsiteConfiguration:
45 | IndexDocument: index.html
46 | ErrorDocument: index.html
47 | WebAppS3BucketPolicy:
48 | Type: AWS::S3::BucketPolicy
49 | Properties:
50 | Bucket:
51 | Ref: WebAppS3Bucket
52 | PolicyDocument:
53 | Statement:
54 | - Sid: PublicReadGetObject
55 | Effect: Allow
56 | Principal: "*"
57 | Action:
58 | - s3:GetObject
59 | Resource: arn:aws:s3:::${self:custom.bucket}/*
60 |
61 | package:
62 | exclude:
63 | - client/**
64 | - sharp/**
65 | - package.json
66 | - .serverless
67 | - serverless.yml
68 | include:
69 | - client/config/production.json
--------------------------------------------------------------------------------
/thumbnail-creator/sharp/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM lambci/lambda:build-nodejs6.10
2 |
3 | CMD ["sh", "/var/task/build.sh"]
--------------------------------------------------------------------------------
/thumbnail-creator/sharp/build.sh:
--------------------------------------------------------------------------------
1 | # Set some variables
2 | SHARP_VERSION=$(npm show sharp version)
3 | SHARP_DIRECTORY=sharp-$SHARP_VERSION
4 | TARBALL=sharp-$SHARP_VERSION-aws-lambda-linux-x64-node-6.10.1.tar.gz
5 |
6 | # Make a working directory
7 | mkdir $SHARP_DIRECTORY
8 | cd $SHARP_DIRECTORY
9 |
10 | # NPM install sharp
11 | npm init -y
12 | npm install sharp@$SHARP_VERSION
13 |
14 | # tarball the resulting node_modules
15 | tar --no-xattrs --hard-dereference -cznshf $TARBALL node_modules
16 |
17 | mv $TARBALL ../tarballs
18 |
19 | # Clean up
20 | cd ../
21 | rm -Rf $SHARP_DIRECTORY
22 |
--------------------------------------------------------------------------------
/thumbnail-creator/sharp/tarballs/sharp-0.18.4-aws-lambda-linux-x64-node-6.10.1.tar.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ramsaylanier/vue-tutorials/26cada54a6f81bc41c0fe786d1d278faf5431e10/thumbnail-creator/sharp/tarballs/sharp-0.18.4-aws-lambda-linux-x64-node-6.10.1.tar.gz
--------------------------------------------------------------------------------
/video-colors/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["env", {
4 | "modules": false
5 | }],
6 | "stage-2"
7 | ],
8 | "plugins": ["transform-runtime"]
9 | }
10 |
--------------------------------------------------------------------------------
/video-colors/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/video-colors/.eslintignore:
--------------------------------------------------------------------------------
1 | /build/
2 | /config/
3 | /dist/
4 | /*.js
5 |
--------------------------------------------------------------------------------
/video-colors/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // https://eslint.org/docs/user-guide/configuring
2 |
3 | module.exports = {
4 | root: true,
5 | parser: 'babel-eslint',
6 | parserOptions: {
7 | sourceType: 'module'
8 | },
9 | env: {
10 | browser: true,
11 | },
12 | // https://github.com/standard/standard/blob/master/docs/RULES-en.md
13 | extends: 'standard',
14 | // required to lint *.vue files
15 | plugins: [
16 | 'html'
17 | ],
18 | // add your custom rules here
19 | rules: {
20 | // allow async-await
21 | 'generator-star-spacing': 'off',
22 | // allow debugger during development
23 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/video-colors/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | /dist/
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Editor directories and files
9 | .idea
10 | .vscode
11 | *.suo
12 | *.ntvs*
13 | *.njsproj
14 | *.sln
15 |
--------------------------------------------------------------------------------
/video-colors/.postcssrc.js:
--------------------------------------------------------------------------------
1 | // https://github.com/michael-ciniawsky/postcss-load-config
2 |
3 | module.exports = {
4 | "plugins": {
5 | // to edit target browsers: use "browserslist" field in package.json
6 | "postcss-import": {},
7 | "autoprefixer": {}
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/video-colors/README.md:
--------------------------------------------------------------------------------
1 | # video-colors
2 |
3 | > A Vue.js project
4 |
5 | ## Build Setup
6 |
7 | ``` bash
8 | # install dependencies
9 | npm install
10 |
11 | # serve with hot reload at localhost:8080
12 | npm run dev
13 |
14 | # build for production with minification
15 | npm run build
16 |
17 | # build for production and view the bundle analyzer report
18 | npm run build --report
19 | ```
20 |
21 | For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
22 |
--------------------------------------------------------------------------------
/video-colors/build/build.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | require('./check-versions')()
3 |
4 | process.env.NODE_ENV = 'production'
5 |
6 | const ora = require('ora')
7 | const rm = require('rimraf')
8 | const path = require('path')
9 | const chalk = require('chalk')
10 | const webpack = require('webpack')
11 | const config = require('../config')
12 | const webpackConfig = require('./webpack.prod.conf')
13 |
14 | const spinner = ora('building for production...')
15 | spinner.start()
16 |
17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
18 | if (err) throw err
19 | webpack(webpackConfig, (err, stats) => {
20 | spinner.stop()
21 | if (err) throw err
22 | process.stdout.write(stats.toString({
23 | colors: true,
24 | modules: false,
25 | children: false,
26 | chunks: false,
27 | chunkModules: false
28 | }) + '\n\n')
29 |
30 | if (stats.hasErrors()) {
31 | console.log(chalk.red(' Build failed with errors.\n'))
32 | process.exit(1)
33 | }
34 |
35 | console.log(chalk.cyan(' Build complete.\n'))
36 | console.log(chalk.yellow(
37 | ' Tip: built files are meant to be served over an HTTP server.\n' +
38 | ' Opening index.html over file:// won\'t work.\n'
39 | ))
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/video-colors/build/check-versions.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const chalk = require('chalk')
3 | const semver = require('semver')
4 | const packageConfig = require('../package.json')
5 | const shell = require('shelljs')
6 |
7 | function exec (cmd) {
8 | return require('child_process').execSync(cmd).toString().trim()
9 | }
10 |
11 | const versionRequirements = [
12 | {
13 | name: 'node',
14 | currentVersion: semver.clean(process.version),
15 | versionRequirement: packageConfig.engines.node
16 | }
17 | ]
18 |
19 | if (shell.which('npm')) {
20 | versionRequirements.push({
21 | name: 'npm',
22 | currentVersion: exec('npm --version'),
23 | versionRequirement: packageConfig.engines.npm
24 | })
25 | }
26 |
27 | module.exports = function () {
28 | const warnings = []
29 |
30 | for (let i = 0; i < versionRequirements.length; i++) {
31 | const mod = versionRequirements[i]
32 |
33 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
34 | warnings.push(mod.name + ': ' +
35 | chalk.red(mod.currentVersion) + ' should be ' +
36 | chalk.green(mod.versionRequirement)
37 | )
38 | }
39 | }
40 |
41 | if (warnings.length) {
42 | console.log('')
43 | console.log(chalk.yellow('To use this template, you must update following to modules:'))
44 | console.log()
45 |
46 | for (let i = 0; i < warnings.length; i++) {
47 | const warning = warnings[i]
48 | console.log(' ' + warning)
49 | }
50 |
51 | console.log()
52 | process.exit(1)
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/video-colors/build/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ramsaylanier/vue-tutorials/26cada54a6f81bc41c0fe786d1d278faf5431e10/video-colors/build/logo.png
--------------------------------------------------------------------------------
/video-colors/build/utils.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const config = require('../config')
4 | const ExtractTextPlugin = require('extract-text-webpack-plugin')
5 | const packageConfig = require('../package.json')
6 |
7 | exports.assetsPath = function (_path) {
8 | const assetsSubDirectory = process.env.NODE_ENV === 'production'
9 | ? config.build.assetsSubDirectory
10 | : config.dev.assetsSubDirectory
11 |
12 | return path.posix.join(assetsSubDirectory, _path)
13 | }
14 |
15 | exports.cssLoaders = function (options) {
16 | options = options || {}
17 |
18 | const cssLoader = {
19 | loader: 'css-loader',
20 | options: {
21 | sourceMap: options.sourceMap
22 | }
23 | }
24 |
25 | const postcssLoader = {
26 | loader: 'postcss-loader',
27 | options: {
28 | sourceMap: options.sourceMap
29 | }
30 | }
31 |
32 | // generate loader string to be used with extract text plugin
33 | function generateLoaders (loader, loaderOptions) {
34 | const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
35 |
36 | if (loader) {
37 | loaders.push({
38 | loader: loader + '-loader',
39 | options: Object.assign({}, loaderOptions, {
40 | sourceMap: options.sourceMap
41 | })
42 | })
43 | }
44 |
45 | // Extract CSS when that option is specified
46 | // (which is the case during production build)
47 | if (options.extract) {
48 | return ExtractTextPlugin.extract({
49 | use: loaders,
50 | fallback: 'vue-style-loader'
51 | })
52 | } else {
53 | return ['vue-style-loader'].concat(loaders)
54 | }
55 | }
56 |
57 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html
58 | return {
59 | css: generateLoaders(),
60 | postcss: generateLoaders(),
61 | less: generateLoaders('less'),
62 | sass: generateLoaders('sass', { indentedSyntax: true }),
63 | scss: generateLoaders('sass'),
64 | stylus: generateLoaders('stylus'),
65 | styl: generateLoaders('stylus')
66 | }
67 | }
68 |
69 | // Generate loaders for standalone style files (outside of .vue)
70 | exports.styleLoaders = function (options) {
71 | const output = []
72 | const loaders = exports.cssLoaders(options)
73 |
74 | for (const extension in loaders) {
75 | const loader = loaders[extension]
76 | output.push({
77 | test: new RegExp('\\.' + extension + '$'),
78 | use: loader
79 | })
80 | }
81 |
82 | return output
83 | }
84 |
85 | exports.createNotifierCallback = () => {
86 | const notifier = require('node-notifier')
87 |
88 | return (severity, errors) => {
89 | if (severity !== 'error') return
90 |
91 | const error = errors[0]
92 | const filename = error.file && error.file.split('!').pop()
93 |
94 | notifier.notify({
95 | title: packageConfig.name,
96 | message: severity + ': ' + error.name,
97 | subtitle: filename || '',
98 | icon: path.join(__dirname, 'logo.png')
99 | })
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/video-colors/build/vue-loader.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const utils = require('./utils')
3 | const config = require('../config')
4 | const isProduction = process.env.NODE_ENV === 'production'
5 | const sourceMapEnabled = isProduction
6 | ? config.build.productionSourceMap
7 | : config.dev.cssSourceMap
8 |
9 | module.exports = {
10 | loaders: utils.cssLoaders({
11 | sourceMap: sourceMapEnabled,
12 | extract: isProduction
13 | }),
14 | cssSourceMap: sourceMapEnabled,
15 | cacheBusting: config.dev.cacheBusting,
16 | transformToRequire: {
17 | video: ['src', 'poster'],
18 | source: 'src',
19 | img: 'src',
20 | image: 'xlink:href'
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/video-colors/build/webpack.base.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const utils = require('./utils')
4 | const config = require('../config')
5 | const vueLoaderConfig = require('./vue-loader.conf')
6 |
7 | function resolve (dir) {
8 | return path.join(__dirname, '..', dir)
9 | }
10 |
11 | const createLintingRule = () => ({
12 | test: /\.(js|vue)$/,
13 | loader: 'eslint-loader',
14 | enforce: 'pre',
15 | include: [resolve('src'), resolve('test')],
16 | options: {
17 | formatter: require('eslint-friendly-formatter'),
18 | emitWarning: !config.dev.showEslintErrorsInOverlay
19 | }
20 | })
21 |
22 | module.exports = {
23 | context: path.resolve(__dirname, '../'),
24 | entry: {
25 | app: './src/main.js'
26 | },
27 | output: {
28 | path: config.build.assetsRoot,
29 | filename: '[name].js',
30 | publicPath: process.env.NODE_ENV === 'production'
31 | ? config.build.assetsPublicPath
32 | : config.dev.assetsPublicPath
33 | },
34 | resolve: {
35 | extensions: ['.js', '.vue', '.json'],
36 | alias: {
37 | 'vue$': 'vue/dist/vue.esm.js',
38 | '@': resolve('src'),
39 | }
40 | },
41 | module: {
42 | rules: [
43 | ...(config.dev.useEslint ? [createLintingRule()] : []),
44 | {
45 | test: /\.vue$/,
46 | loader: 'vue-loader',
47 | options: vueLoaderConfig
48 | },
49 | {
50 | test: /\.js$/,
51 | loader: 'babel-loader',
52 | include: [resolve('src'), resolve('test')]
53 | },
54 | {
55 | test: /\worker\.js$/,
56 | loader: 'worker-loader',
57 | include: [resolve('src'), resolve('test')]
58 | },
59 | {
60 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
61 | loader: 'url-loader',
62 | options: {
63 | limit: 10000,
64 | name: utils.assetsPath('img/[name].[hash:7].[ext]')
65 | }
66 | },
67 | {
68 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
69 | loader: 'url-loader',
70 | options: {
71 | limit: 10000,
72 | name: utils.assetsPath('media/[name].[hash:7].[ext]')
73 | }
74 | },
75 | {
76 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
77 | loader: 'url-loader',
78 | options: {
79 | limit: 10000,
80 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
81 | }
82 | }
83 | ]
84 | },
85 | node: {
86 | // prevent webpack from injecting useless setImmediate polyfill because Vue
87 | // source contains it (although only uses it if it's native).
88 | setImmediate: false,
89 | // prevent webpack from injecting mocks to Node native modules
90 | // that does not make sense for the client
91 | dgram: 'empty',
92 | fs: 'empty',
93 | net: 'empty',
94 | tls: 'empty',
95 | child_process: 'empty'
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/video-colors/build/webpack.dev.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const utils = require('./utils')
3 | const webpack = require('webpack')
4 | const config = require('../config')
5 | const merge = require('webpack-merge')
6 | const baseWebpackConfig = require('./webpack.base.conf')
7 | const HtmlWebpackPlugin = require('html-webpack-plugin')
8 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
9 | const portfinder = require('portfinder')
10 |
11 | const HOST = process.env.HOST
12 | const PORT = process.env.PORT && Number(process.env.PORT)
13 |
14 | const devWebpackConfig = merge(baseWebpackConfig, {
15 | module: {
16 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
17 | },
18 | // cheap-module-eval-source-map is faster for development
19 | devtool: config.dev.devtool,
20 |
21 | // these devServer options should be customized in /config/index.js
22 | devServer: {
23 | clientLogLevel: 'warning',
24 | historyApiFallback: true,
25 | hot: true,
26 | compress: true,
27 | host: HOST || config.dev.host,
28 | port: PORT || config.dev.port,
29 | open: config.dev.autoOpenBrowser,
30 | overlay: config.dev.errorOverlay
31 | ? { warnings: false, errors: true }
32 | : false,
33 | publicPath: config.dev.assetsPublicPath,
34 | proxy: config.dev.proxyTable,
35 | quiet: true, // necessary for FriendlyErrorsPlugin
36 | watchOptions: {
37 | poll: config.dev.poll,
38 | }
39 | },
40 | plugins: [
41 | new webpack.DefinePlugin({
42 | 'process.env': require('../config/dev.env')
43 | }),
44 | new webpack.HotModuleReplacementPlugin(),
45 | new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
46 | new webpack.NoEmitOnErrorsPlugin(),
47 | // https://github.com/ampedandwired/html-webpack-plugin
48 | new HtmlWebpackPlugin({
49 | filename: 'index.html',
50 | template: 'index.html',
51 | inject: true
52 | }),
53 | ]
54 | })
55 |
56 | module.exports = new Promise((resolve, reject) => {
57 | portfinder.basePort = process.env.PORT || config.dev.port
58 | portfinder.getPort((err, port) => {
59 | if (err) {
60 | reject(err)
61 | } else {
62 | // publish the new Port, necessary for e2e tests
63 | process.env.PORT = port
64 | // add port to devServer config
65 | devWebpackConfig.devServer.port = port
66 |
67 | // Add FriendlyErrorsPlugin
68 | devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
69 | compilationSuccessInfo: {
70 | messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
71 | },
72 | onErrors: config.dev.notifyOnErrors
73 | ? utils.createNotifierCallback()
74 | : undefined
75 | }))
76 |
77 | resolve(devWebpackConfig)
78 | }
79 | })
80 | })
81 |
--------------------------------------------------------------------------------
/video-colors/build/webpack.prod.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const utils = require('./utils')
4 | const webpack = require('webpack')
5 | const config = require('../config')
6 | const merge = require('webpack-merge')
7 | const baseWebpackConfig = require('./webpack.base.conf')
8 | const CopyWebpackPlugin = require('copy-webpack-plugin')
9 | const HtmlWebpackPlugin = require('html-webpack-plugin')
10 | const ExtractTextPlugin = require('extract-text-webpack-plugin')
11 | const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
12 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
13 |
14 | const env = require('../config/prod.env')
15 |
16 | const webpackConfig = merge(baseWebpackConfig, {
17 | module: {
18 | rules: utils.styleLoaders({
19 | sourceMap: config.build.productionSourceMap,
20 | extract: true,
21 | usePostCSS: true
22 | })
23 | },
24 | devtool: config.build.productionSourceMap ? config.build.devtool : false,
25 | output: {
26 | path: config.build.assetsRoot,
27 | filename: utils.assetsPath('js/[name].[chunkhash].js'),
28 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
29 | },
30 | plugins: [
31 | // http://vuejs.github.io/vue-loader/en/workflow/production.html
32 | new webpack.DefinePlugin({
33 | 'process.env': env
34 | }),
35 | new UglifyJsPlugin({
36 | uglifyOptions: {
37 | compress: {
38 | warnings: false
39 | }
40 | },
41 | sourceMap: config.build.productionSourceMap,
42 | parallel: true
43 | }),
44 | // extract css into its own file
45 | new ExtractTextPlugin({
46 | filename: utils.assetsPath('css/[name].[contenthash].css'),
47 | // set the following option to `true` if you want to extract CSS from
48 | // codesplit chunks into this main css file as well.
49 | // This will result in *all* of your app's CSS being loaded upfront.
50 | allChunks: false,
51 | }),
52 | // Compress extracted CSS. We are using this plugin so that possible
53 | // duplicated CSS from different components can be deduped.
54 | new OptimizeCSSPlugin({
55 | cssProcessorOptions: config.build.productionSourceMap
56 | ? { safe: true, map: { inline: false } }
57 | : { safe: true }
58 | }),
59 | // generate dist index.html with correct asset hash for caching.
60 | // you can customize output by editing /index.html
61 | // see https://github.com/ampedandwired/html-webpack-plugin
62 | new HtmlWebpackPlugin({
63 | filename: config.build.index,
64 | template: 'index.html',
65 | inject: true,
66 | minify: {
67 | removeComments: true,
68 | collapseWhitespace: true,
69 | removeAttributeQuotes: true
70 | // more options:
71 | // https://github.com/kangax/html-minifier#options-quick-reference
72 | },
73 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin
74 | chunksSortMode: 'dependency'
75 | }),
76 | // keep module.id stable when vender modules does not change
77 | new webpack.HashedModuleIdsPlugin(),
78 | // enable scope hoisting
79 | new webpack.optimize.ModuleConcatenationPlugin(),
80 | // split vendor js into its own file
81 | new webpack.optimize.CommonsChunkPlugin({
82 | name: 'vendor',
83 | minChunks (module) {
84 | // any required modules inside node_modules are extracted to vendor
85 | return (
86 | module.resource &&
87 | /\.js$/.test(module.resource) &&
88 | module.resource.indexOf(
89 | path.join(__dirname, '../node_modules')
90 | ) === 0
91 | )
92 | }
93 | }),
94 | // extract webpack runtime and module manifest to its own file in order to
95 | // prevent vendor hash from being updated whenever app bundle is updated
96 | new webpack.optimize.CommonsChunkPlugin({
97 | name: 'manifest',
98 | minChunks: Infinity
99 | }),
100 | // This instance extracts shared chunks from code splitted chunks and bundles them
101 | // in a separate chunk, similar to the vendor chunk
102 | // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
103 | new webpack.optimize.CommonsChunkPlugin({
104 | name: 'app',
105 | async: 'vendor-async',
106 | children: true,
107 | minChunks: 3
108 | }),
109 |
110 | // copy custom static assets
111 | new CopyWebpackPlugin([
112 | {
113 | from: path.resolve(__dirname, '../static'),
114 | to: config.build.assetsSubDirectory,
115 | ignore: ['.*']
116 | }
117 | ])
118 | ]
119 | })
120 |
121 | if (config.build.productionGzip) {
122 | const CompressionWebpackPlugin = require('compression-webpack-plugin')
123 |
124 | webpackConfig.plugins.push(
125 | new CompressionWebpackPlugin({
126 | asset: '[path].gz[query]',
127 | algorithm: 'gzip',
128 | test: new RegExp(
129 | '\\.(' +
130 | config.build.productionGzipExtensions.join('|') +
131 | ')$'
132 | ),
133 | threshold: 10240,
134 | minRatio: 0.8
135 | })
136 | )
137 | }
138 |
139 | if (config.build.bundleAnalyzerReport) {
140 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
141 | webpackConfig.plugins.push(new BundleAnalyzerPlugin())
142 | }
143 |
144 | module.exports = webpackConfig
145 |
--------------------------------------------------------------------------------
/video-colors/config/dev.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const merge = require('webpack-merge')
3 | const prodEnv = require('./prod.env')
4 |
5 | module.exports = merge(prodEnv, {
6 | NODE_ENV: '"development"'
7 | })
8 |
--------------------------------------------------------------------------------
/video-colors/config/index.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | // Template version: 1.2.5
3 | // see http://vuejs-templates.github.io/webpack for documentation.
4 |
5 | const path = require('path')
6 |
7 | module.exports = {
8 | dev: {
9 |
10 | // Paths
11 | assetsSubDirectory: 'static',
12 | assetsPublicPath: '/',
13 | proxyTable: {},
14 |
15 | // Various Dev Server settings
16 | host: 'localhost', // can be overwritten by process.env.HOST
17 | port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
18 | autoOpenBrowser: false,
19 | errorOverlay: true,
20 | notifyOnErrors: true,
21 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
22 |
23 | // Use Eslint Loader?
24 | // If true, your code will be linted during bundling and
25 | // linting errors and warnings will be shown in the console.
26 | useEslint: true,
27 | // If true, eslint errors and warnings will also be shown in the error overlay
28 | // in the browser.
29 | showEslintErrorsInOverlay: false,
30 |
31 | /**
32 | * Source Maps
33 | */
34 |
35 | // https://webpack.js.org/configuration/devtool/#development
36 | devtool: 'eval-source-map',
37 |
38 | // If you have problems debugging vue-files in devtools,
39 | // set this to false - it *may* help
40 | // https://vue-loader.vuejs.org/en/options.html#cachebusting
41 | cacheBusting: true,
42 |
43 | // CSS Sourcemaps off by default because relative paths are "buggy"
44 | // with this option, according to the CSS-Loader README
45 | // (https://github.com/webpack/css-loader#sourcemaps)
46 | // In our experience, they generally work as expected,
47 | // just be aware of this issue when enabling this option.
48 | cssSourceMap: false,
49 | },
50 |
51 | build: {
52 | // Template for index.html
53 | index: path.resolve(__dirname, '../dist/index.html'),
54 |
55 | // Paths
56 | assetsRoot: path.resolve(__dirname, '../dist'),
57 | assetsSubDirectory: 'static',
58 | assetsPublicPath: '/',
59 |
60 | /**
61 | * Source Maps
62 | */
63 |
64 | productionSourceMap: true,
65 | // https://webpack.js.org/configuration/devtool/#production
66 | devtool: '#source-map',
67 |
68 | // Gzip off by default as many popular static hosts such as
69 | // Surge or Netlify already gzip all static assets for you.
70 | // Before setting to `true`, make sure to:
71 | // npm install --save-dev compression-webpack-plugin
72 | productionGzip: false,
73 | productionGzipExtensions: ['js', 'css'],
74 |
75 | // Run the build command with an extra argument to
76 | // View the bundle analyzer report after build finishes:
77 | // `npm run build --report`
78 | // Set to `true` or `false` to always turn it on or off
79 | bundleAnalyzerReport: process.env.npm_config_report
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/video-colors/config/prod.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | module.exports = {
3 | NODE_ENV: '"production"'
4 | }
5 |
--------------------------------------------------------------------------------
/video-colors/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | video-colors
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/video-colors/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "video-colors",
3 | "version": "1.0.0",
4 | "description": "A Vue.js project",
5 | "author": "",
6 | "private": true,
7 | "scripts": {
8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
9 | "start": "npm run dev",
10 | "lint": "eslint --ext .js,.vue src",
11 | "build": "node build/build.js"
12 | },
13 | "dependencies": {
14 | "d3": "^4.12.0",
15 | "vue": "^2.5.2",
16 | "worker-loader": "^1.1.0"
17 | },
18 | "devDependencies": {
19 | "autoprefixer": "^7.1.2",
20 | "babel-core": "^6.22.1",
21 | "babel-eslint": "^7.1.1",
22 | "babel-loader": "^7.1.1",
23 | "babel-plugin-transform-runtime": "^6.22.0",
24 | "babel-preset-env": "^1.3.2",
25 | "babel-preset-stage-2": "^6.22.0",
26 | "chalk": "^2.0.1",
27 | "copy-webpack-plugin": "^4.0.1",
28 | "css-loader": "^0.28.0",
29 | "eslint": "^3.19.0",
30 | "eslint-config-standard": "^10.2.1",
31 | "eslint-friendly-formatter": "^3.0.0",
32 | "eslint-loader": "^1.7.1",
33 | "eslint-plugin-html": "^3.0.0",
34 | "eslint-plugin-import": "^2.7.0",
35 | "eslint-plugin-node": "^5.2.0",
36 | "eslint-plugin-promise": "^3.4.0",
37 | "eslint-plugin-standard": "^3.0.1",
38 | "eventsource-polyfill": "^0.9.6",
39 | "extract-text-webpack-plugin": "^3.0.0",
40 | "file-loader": "^1.1.4",
41 | "friendly-errors-webpack-plugin": "^1.6.1",
42 | "html-webpack-plugin": "^2.30.1",
43 | "node-notifier": "^5.1.2",
44 | "optimize-css-assets-webpack-plugin": "^3.2.0",
45 | "ora": "^1.2.0",
46 | "portfinder": "^1.0.13",
47 | "postcss-import": "^11.0.0",
48 | "postcss-loader": "^2.0.8",
49 | "rimraf": "^2.6.0",
50 | "semver": "^5.3.0",
51 | "shelljs": "^0.7.6",
52 | "uglifyjs-webpack-plugin": "^1.1.1",
53 | "url-loader": "^0.5.8",
54 | "vue-loader": "^13.3.0",
55 | "vue-style-loader": "^3.0.1",
56 | "vue-template-compiler": "^2.5.2",
57 | "webpack": "^3.6.0",
58 | "webpack-bundle-analyzer": "^2.9.0",
59 | "webpack-dev-server": "^2.9.1",
60 | "webpack-merge": "^4.1.0"
61 | },
62 | "engines": {
63 | "node": ">= 4.0.0",
64 | "npm": ">= 3.0.0"
65 | },
66 | "browserslist": [
67 | "> 1%",
68 | "last 2 versions",
69 | "not ie <= 8"
70 | ]
71 | }
72 |
--------------------------------------------------------------------------------
/video-colors/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
87 |
88 |
121 |
--------------------------------------------------------------------------------
/video-colors/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ramsaylanier/vue-tutorials/26cada54a6f81bc41c0fe786d1d278faf5431e10/video-colors/src/assets/logo.png
--------------------------------------------------------------------------------
/video-colors/src/assets/test.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ramsaylanier/vue-tutorials/26cada54a6f81bc41c0fe786d1d278faf5431e10/video-colors/src/assets/test.mp4
--------------------------------------------------------------------------------
/video-colors/src/chart.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
115 |
116 |
122 |
--------------------------------------------------------------------------------
/video-colors/src/main.js:
--------------------------------------------------------------------------------
1 | // The Vue build version to load with the `import` command
2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
3 | import Vue from 'vue'
4 | import App from './App'
5 |
6 | Vue.config.productionTip = false
7 |
8 | /* eslint-disable no-new */
9 | new Vue({
10 | el: '#app',
11 | template: ' ',
12 | components: { App }
13 | })
14 |
--------------------------------------------------------------------------------
/video-colors/src/worker.js:
--------------------------------------------------------------------------------
1 |
2 | onmessage = function (e) {
3 | const data = e.data
4 | const BLOCKSIZE = 5
5 | const STEPS = 4
6 | let i = -4
7 | let count = 0
8 | let rgb = {r: 0, g: 0, b: 0}
9 |
10 | let length = data.data.length
11 | while ((i += BLOCKSIZE * STEPS) < length) {
12 | ++count
13 | rgb.r += data.data[i]
14 | rgb.g += data.data[i + 1]
15 | rgb.b += data.data[i + 2]
16 | }
17 |
18 | // ~~ used to floor values
19 | rgb.r = ~~(rgb.r / count)
20 | rgb.g = ~~(rgb.g / count)
21 | rgb.b = ~~(rgb.b / count)
22 |
23 | postMessage(rgb)
24 | }
25 |
--------------------------------------------------------------------------------
/video-colors/static/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ramsaylanier/vue-tutorials/26cada54a6f81bc41c0fe786d1d278faf5431e10/video-colors/static/.gitkeep
--------------------------------------------------------------------------------