diff --git a/.gitignore b/.gitignore index 59e9f56..44b01e3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ node_modules -.tmp server/.env diff --git a/README.md b/README.md index 5ad047d..c7112dc 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ A friendly, proven starting place for your next hapi plugin or deployment

- + Slack: hapihour/hapipal

@@ -16,17 +16,16 @@ Lead Maintainer - [Devin Ivy](https://github.com/devinivy) **Features** - - Supports hapi v20+ and nodejs v12+. + - Supports hapi v20+ and Node.js v12+. - Setup with [hpal-debug](https://github.com/hapipal/hpal-debug) hapi CLI debugging tools. - - Provides conventions for building plugins by mapping the entire hapi plugin API onto files and folders, using [haute-couture](https://github.com/hapipal/haute-couture). + - Provides clear, customizable hapi file and folder conventions using [haute-couture](https://github.com/hapipal/haute-couture). - Designed to allow you to deploy your plugin on its own or as part of a larger application. - Textbook integrations with Objection ORM, Swagger UI, and more via [flavors](#flavors). - Fully setup with a [lab](https://github.com/hapijs/lab) test suite and [eslint](https://github.com/eslint/eslint) configuration. - - Powerful, [12factor](https://12factor.net/)-oriented deployment configuration using - [confidence](https://github.com/hapijs/confidence) and [dotenv](https://github.com/motdotla/dotenv). + - Powerful [12factor](https://12factor.net/)-oriented deployment configuration using + [confidence](https://github.com/hapipal/confidence) and [dotenv](https://github.com/motdotla/dotenv). - Up-to-date versions of all dependencies. - Follows established hapi best practices out of the box. - - The code is minimal and completely generic– no need to find-and-replace with your project name to get started. ## Getting Started > If you're interested to hear about why we came together to create pal, check out our Medium article [Introducing hapi pal](https://medium.com/@hapipal/introducing-hapi-pal-550c13f30c5b). @@ -34,7 +33,7 @@ Lead Maintainer - [Devin Ivy](https://github.com/devinivy) > Below is a simple tutorial to create your first route. For a more in-depth look at the pal ecosystem, database integration, etc. see [our official starting guide](https://hapipal.com/getting-started). ```sh -npx hpal new my-project +npm init @hapipal my-project cd ./my-project npm install ``` @@ -42,21 +41,7 @@ npm install
(click to expand) -The [npx](https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b) command comes with npm 5.2+ and higher. Here you can find instructions for older npm versions. - - -```sh -npm install --global hpal -hpal new my-project -cd ./my-project -npm install -``` -Going forward, any instructions that use npx can directly use your global installation of `hpal` instead. Just replace CLI instructions that say `npx hpal` with `hpal`. -
-
- (click to expand) - -Perhaps you'd like to perform a manual installation without any fancy CLI tools—that's possible too! Here you can find instructions for installation using only git. +Perhaps you'd like to perform a manual installation without any fancy CLI tools—that's possible too! Click [here](https://github.com/hapipal/boilerplate/generate) to create a new repository using this one as a template. Or expand to find instructions for installation using only git. ```sh @@ -99,7 +84,7 @@ module.exports = { }; ``` -Let's fill-in the `method` and `path` so that the route we hit is at `get /random-quotation`, and write the `handler` to serve a random quotation from a list. Our handler doesn't need to do anything asynchronous or use the [response toolkit](https://github.com/hapijs/hapi/blob/master/API.md#response-toolkit), so the route handler's signature appears a little simpler than before. +Let's fill-in the `method` and `path` so that the route we hit is at `get /random-quotation`, and write the `handler` to serve a random quotation from a list. Our handler doesn't need to do anything asynchronous or use the [response toolkit](https://hapi.dev/api/#response-toolkit), so the route handler's signature appears a little simpler than before. ```js // lib/routes/random-quotation.js @@ -182,12 +167,7 @@ git cherry-pick flavor-one flavor-two #### Swagger > `git cherry-pick swagger` [[view](https://github.com/hapipal/boilerplate/commit/swagger)] -Integrates [hapi-swagger](https://github.com/glennjones/hapi-swagger) onto the server with some reasonable default configuration. - -#### Custom Swagger -> `git cherry-pick custom-swagger` [[view](https://github.com/hapipal/boilerplate/commit/custom-swagger)] - -Integrates [hapi-swagger](https://github.com/glennjones/hapi-swagger) onto the server with some reasonable default configuration, and also includes an editable handlebars template for swagger-ui. +Integrates [hapi-swagger](https://github.com/glennjones/hapi-swagger) onto the server with a suitable default configuration. If you need to customize the swagger templates, then use hapi-swagger's [`templates` option](https://github.com/glennjones/hapi-swagger/blob/master/optionsreference.md#ui) to serve your own custom version of the [Swagger UI page templates](https://github.com/glennjones/hapi-swagger/tree/master/templates). #### Objection ORM > `git cherry-pick objection` [[view](https://github.com/hapipal/boilerplate/commit/objection)] @@ -195,11 +175,11 @@ Integrates [hapi-swagger](https://github.com/glennjones/hapi-swagger) onto the s Integrates [Objection ORM](https://github.com/Vincit/objection.js) into your server and plugin using the hapi plugin [schwifty](https://github.com/hapipal/schwifty). This is a great way to get started with a SQL-oriented plugin. Adds a `models/` directory to your plugin where Objection models should be placed, and a `migrations/` directory where your migrations should be placed. Configured to work with SQLite out of the box. ##### Using the knex CLI -We've added an npm script for `knex` so that you can avoid writing the whole path to the knex CLI (`node_modules/.bin/knex`) when running commands. To use the knex CLI, you may write your commands as `npm run knex -- `. +The knex CLI is installed locally, and a [knexfile](http://knexjs.org/#knexfile) is added to the root of your project so that the connection info is available to it. To use the CLI, you may run it using npx. -For example, to create a new migration, +For example, to create a new migration: ``` -npm run knex -- migrate:make my-first-migration +npx knex migrate:make my-first-migration ``` #### Deployment @@ -212,31 +192,28 @@ By default all deployment-oriented dependencies are placed in package.json's `de Sets up a Dockerfile and docker-compose.yml file for usage in local development. The Dockerfile is fully production ready, and just needs to integrated into a build system of your choice that supports Docker 17.05 or higher, and Docker Compose files with version v3.4. This flavor also introduces two `build` and four `docker` npm scripts, which are described in the [`DOCKER.md`](https://github.com/hapipal/boilerplate/blob/flavor-docker/DOCKER.md) file that comes with the flavor. -#### Templated Site -> `git cherry-pick templated-site` [[view](https://github.com/hapipal/boilerplate/commit/templated-site)] - -Sets-up [handlebars](https://github.com/wycats/handlebars.js/) templating with a useful layout and openly serves the `lib/public` directory, which contains folders to place javascript and CSS. This flavor additionally introduces three npm scripts: one to minify front-end javascript (`npm run build:js`) with [uglify](https://github.com/mishoo/UglifyJS2); one to minify CSS with [PostCSS](https://github.com/postcss/postcss)/[cssnano](https://github.com/ben-eb/cssnano) (`npm run build:css`); and one to do both (`npm run build`). Lastly, this flavor introduces a plugin option `developmentMode` that controls whether the minified or un-minified javascript and CSS are served on the page. The `developmentMode` is configured to be active when `NODE_ENV` is not `production`. - #### Fancy Templated Site > `git cherry-pick fancy-templated-site` [[view](https://github.com/hapipal/boilerplate/commit/fancy-templated-site)] -Building on top of the [templated site flavor](#templated-site), this flavor also incorporates [browserify](https://github.com/substack/node-browserify), [Sass](https://www.npmjs.com/package/node-sass), and [Browsersync](https://github.com/Browsersync/browser-sync). As such, there are two new npm scripts: one to pre-build javascript from nodejs-style to ES5 using browserify and [Babel](https://github.com/babel/babel) (`npm run prebuild:js`); and one to pre-build CSS from SCSS using node-sass. When `developmentMode` is active browser-sync will rebuild SCSS and nodejs-style javascript, then reload the page or stylesheets as necessary. +Sets-up [handlebars](https://github.com/wycats/handlebars.js/) templating with a useful layout and openly serves the `lib/public` directory, which contains folders to place javascript and CSS. This flavor introduces several npm scripts: one to minify front-end javascript with [uglify](https://github.com/mishoo/UglifyJS2) (`npm run build:js`); one to minify CSS with [PostCSS](https://github.com/postcss/postcss)/[cssnano](https://github.com/ben-eb/cssnano) (`npm run build:css`); and one to do both (`npm run build`). A plugin option `developmentMode` controls whether the minified or un-minified javascript and CSS are served on the page. The `developmentMode` is configured to be active when `NODE_ENV` is not `production`. + +This flavor additionally incorporates [browserify](https://github.com/substack/node-browserify), [Sass](https://www.npmjs.com/package/node-sass), and [Browsersync](https://github.com/Browsersync/browser-sync). As such, there are scripts to support the pre-building process: one to pre-build javascript from Node.js-style to ES5 using browserify and [Babel](https://github.com/babel/babel) (`npm run prebuild:js`); and one to pre-build CSS from SCSS using node-sass. When `developmentMode` is active browser-sync will rebuild SCSS and Node.js-style javascript, then reload the page or stylesheets as necessary. ### Versioning > Note: most of the time you'll be pulling in flavors at the time you install the pal boilerplate, in which case you don't need to worry much about flavor versioning. -It's worth noting that over time these flavor tags may point to different commits. The flavors are updated to keep-up with the latest pal boilerplate. For this reason, as flavor tags move, we leave static versioned tags for your convenience. Tags are named as such, +It's worth noting that over time these flavor tags may point to different commits. The flavors are updated to keep-up with the latest pal boilerplate. For this reason, as flavor tags move, we leave static versioned tags for your convenience. Tags are named as such: ``` -v.. ``` -where, +where: - `` - the name of this flavor. Identical to the unversioned tag for this flavor. - `` - the major version of the flavor, identical to the major version of the pal boilerplate that it is compatible with. - `` - the minor version of the flavor, bumped when a feature is added to the flavor (rare), but more typically when its dependencies are updated. - `` - the patch version of the flavor, bumped when a bug is fixed in the flavor, or the flavor requires update to account for bugs in the version of the pal boilerplate with which it is compatible. -For example the first version of the "custom swagger" flavor is, +For example the first version of the "custom swagger" flavor is: ``` custom-swagger-v1.0.0 ``` diff --git a/lib/index.js b/lib/index.js index c6a73d0..0a6a010 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,6 +1,6 @@ 'use strict'; -const HauteCouture = require('haute-couture'); +const HauteCouture = require('@hapipal/haute-couture'); const Package = require('../package.json'); exports.plugin = { @@ -9,6 +9,6 @@ exports.plugin = { // Custom plugin code can go here - await HauteCouture.using()(server, options); + await HauteCouture.compose(server, options); } }; diff --git a/package.json b/package.json index 016599d..18c1769 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hapipal-boilerplate", - "version": "2.5.1", + "version": "3.0.0", "main": "lib/index.js", "scripts": { "build:test": "docker-compose build test", @@ -17,20 +17,21 @@ "@hapi/boom": "9.x.x", "@hapi/glue": "8.x.x", "@hapi/hapi": "20.x.x", - "confidence": "4.x.x", - "haute-couture": "3.x.x", - "joi": "17.x.x", - "toys": "2.x.x" + "@hapipal/confidence": "6.x.x", + "@hapipal/haute-couture": "4.x.x", + "@hapipal/toys": "3.x.x", + "exiting": "6.x.x", + "joi": "17.x.x" }, "devDependencies": { "@hapi/code": "8.x.x", "@hapi/eslint-config-hapi": "13.x.x", "@hapi/eslint-plugin-hapi": "4.x.x", - "@hapi/lab": "23.x.x", + "@hapi/lab": "24.x.x", + "@hapipal/hpal": "3.x.x", + "@hapipal/hpal-debug": "2.x.x", "babel-eslint": "10.x.x", "eslint": "7.x.x", - "hpal": "2.x.x", - "hpal-debug": "1.x.x", "nodemon": "2.x.x" } } diff --git a/server/index.js b/server/index.js index c6d9f9e..4c997c6 100644 --- a/server/index.js +++ b/server/index.js @@ -1,29 +1,28 @@ 'use strict'; const Glue = require('@hapi/glue'); +const Exiting = require('exiting'); const Manifest = require('./manifest'); -exports.deployment = async (start) => { +exports.deployment = async ({ start } = {}) => { - const manifest = Manifest.get('/'); + const manifest = Manifest.get('/', process.env); const server = await Glue.compose(manifest, { relativeTo: __dirname }); - await server.initialize(); - - if (!start) { + if (start) { + await Exiting.createManager(server).start(); + server.log(['start'], `Server started at ${server.info.uri}`); return server; } - await server.start(); - - console.log(`Server started at ${server.info.uri}`); + await server.initialize(); return server; }; -if (!module.parent) { +if (require.main === module) { - exports.deployment(true); + exports.deployment({ start: true }); process.on('unhandledRejection', (err) => { diff --git a/server/manifest.js b/server/manifest.js index 8c40884..3eb93be 100644 --- a/server/manifest.js +++ b/server/manifest.js @@ -1,21 +1,21 @@ 'use strict'; -const Confidence = require('confidence'); -const Toys = require('toys'); +const Confidence = require('@hapipal/confidence'); +const Toys = require('@hapipal/toys'); // Glue manifest as a confidence store module.exports = new Confidence.Store({ server: { host: '0.0.0.0', port: { - $env: 'PORT', + $param: 'PORT', $coerce: 'number', $default: 3000 }, debug: { - $filter: { $env: 'NODE_ENV' }, + $filter: 'NODE_ENV', $default: { - log: ['error'], + log: ['error', 'start'], request: ['error'] }, production: { @@ -31,8 +31,8 @@ module.exports = new Confidence.Store({ }, { plugin: { - $filter: { $env: 'NODE_ENV' }, - $default: 'hpal-debug', + $filter: 'NODE_ENV', + $default: '@hapipal/hpal-debug', production: Toys.noop } }