### Run Vision Examples Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/vision/7/api.md Instructions to clone the Vision repository, install dependencies, and run specific templating engine examples. ```bash git clone https://github.com/hapijs/vision.git && cd vision npm install node examples/handlebars ``` -------------------------------- ### Setting up Basic Authentication Strategy Source: https://github.com/hapijs/hapi.dev/blob/master/docs/tutorials/en_US/auth.md This example demonstrates how to set up a basic authentication strategy using the @hapi/basic plugin. It includes defining user data, a validation function that uses Bcrypt to compare passwords, registering the plugin, and configuring the authentication strategy for a route. Ensure Bcrypt is installed (`npm install bcrypt`). ```javascript 'use strict'; const Bcrypt = require('bcrypt'); const Hapi = require('@hapi/hapi'); const users = { john: { username: 'john', password: '$2a$10$iqJSHD.BGr0E2IxQwYgJmeP3NvhPrXAeLSaGCj6IR/XU5QtjVu5Tm', // 'secret' name: 'John Doe', id: '2133d32a', }, }; const validate = async (request, username, password) => { const user = users[username]; if (!user) { return { credentials: null, isValid: false }; } const isValid = await Bcrypt.compare(password, user.password); const credentials = { id: user.id, name: user.name }; return { isValid, credentials }; }; const start = async () => { const server = Hapi.server({ port: 4000 }); await server.register(require('@hapi/basic')); server.auth.strategy('simple', 'basic', { validate }); server.route({ method: 'GET', path: '/', options: { auth: 'simple', }, handler: function (request, h) { return 'welcome'; }, }); await server.start(); console.log('server running at: ' + server.info.uri); }; start(); ``` -------------------------------- ### Lab Experiment with Setup Hooks Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/lab/25/api.md Shows how to organize tests into experiments and use `before()` and `beforeEach()` hooks for setup operations. These hooks can return Promises for asynchronous setup. ```javascript lab.experiment('math', () => { lab.before(() => { return new Promise((resolve) => { // Wait 1 second setTimeout(() => { resolve(); }, 1000); }); }); lab.beforeEach(() => { // Run before every single test }); lab.test('returns true when 1 + 1 equals 2', () => { expect(1 + 1).to.equal(2); }); }); ``` -------------------------------- ### await server.initialize() Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/hapi/21/api.md Initializes the server, starting caches and finalizing plugin registration, without starting the connection listeners. Recommended to call before starting the server. ```APIDOC ## await server.initialize() ### Description Initializes the server (starts the caches, finalizes plugin registration) but does not start listening on the connection port. ### Return Value none. ### Note If initialization fails, the server is in an undefined state and should be shut down using `server.stop()`. It is recommended to abort the process if the server fails to start properly. ### Example ```js const Hapi = require('@hapi/hapi'); const Hoek = require('@hapi/hoek'); async function example() { const server = Hapi.server({ port: 80 }); await server.initialize(); } ``` ``` -------------------------------- ### Setting up @hapi/cookie Authentication Strategy Source: https://github.com/hapijs/hapi.dev/blob/master/docs/tutorials/en_US/auth.md This example demonstrates the complete setup for cookie-based authentication using the @hapi/cookie plugin. It includes user data, server initialization, strategy configuration, and route definitions for home, login, and a POST login handler. The home route is protected, requiring authentication, while the login routes are accessible. ```javascript "use strict"; const Bcrypt = require('bcrypt'); const Hapi = require('@hapi/hapi'); const users = [ { username: 'john', password: '$2a$10$iqJSHD.BGr0E2IxQwYgJmeP3NvhPrXAeLSaGCj6IR/XU5QtjVu5Tm', // 'secret' name: 'John Doe', id: '2133d32a', }, ]; const start = async () => { const server = Hapi.server({ port: 4000 }); await server.register(require('@hapi/cookie')); server.auth.strategy('session', 'cookie', { cookie: { name: 'sid-example', password: '!wsYhFA*C2U6nz=Bu^%A@^F#SF3&kSR6', isSecure: false, }, redirectTo: '/login', validate: async (request, session) => { const account = await users.find((user) => user.id === session.id); if (!account) { return { isValid: false }; } return { isValid: true, credentials: account }; }, }); server.auth.default('session'); server.route([ { method: 'GET', path: '/', handler: function (request, h) { return 'Welcome to the restricted home page!'; }, }, { method: 'GET', path: '/login', handler: function (request, h) { return ` Login page

Please Log In

Username:
Password:
`; }, options: { auth: false, }, }, { method: 'POST', path: '/login', handler: async (request, h) => { const { username, password } = request.payload; const account = users.find((user) => user.username === username); if (!account || !(await Bcrypt.compare(password, account.password))) { return h.redirect('/login'); } request.cookieAuth.set({ id: account.id }); return h.redirect('/'); }, options: { auth: { mode: 'try', }, }, }, ]); await server.start(); console.log('server running at: ' + server.info.uri); }; start(); ``` -------------------------------- ### Add a Route to Hapi Server Source: https://github.com/hapijs/hapi.dev/blob/master/docs/tutorials/en_US/getting-started.md Define a GET route for the root path that returns 'Hello World!'. This example builds upon the basic server setup. ```javascript "use strict"; const Hapi = require('@hapi/hapi'); const init = async () => { const server = Hapi.server({ port: 3000, host: 'localhost', }); server.route({ method: 'GET', path: '/', handler: (request, h) => { return 'Hello World!'; }, }); await server.start(); console.log('Server running on %s', server.info.uri); }; process.on('unhandledRejection', (err) => { console.log(err); process.exit(1); }); init(); ``` -------------------------------- ### Basic Scooter Usage Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/scooter/7/api.md This example demonstrates how to register the Scooter plugin with a Hapi server and define a route that returns user-agent information. Ensure `@hapi/hapi` and `@hapi/scooter` are installed. ```javascript const Hapi = require('@hapi/hapi'); const Scooter = require('@hapi/scooter'); const start = async () => { const server = new Hapi.Server(); server.route({ method: 'GET', path: '/user-agent', handler: (request, h) => { return request.plugins.scooter; }, }); await server.register(Scooter); await server.start(); console.log(server.info.uri + '/user-agent'); }; start(); ``` -------------------------------- ### Quick Start with @hapi/sse Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/sse/1/api.md Initialize a hapi server, register the SsePlugin, define a subscription endpoint, and start the server. You can then publish events to specific rooms. ```typescript import Hapi from '@hapi/hapi'; import { SsePlugin } from '@hapi/sse'; const server = Hapi.server({ port: 3000 }); await server.register({ plugin: SsePlugin }); server.sse.subscription('/chat/{room}'); await server.start(); // Publish from anywhere await server.sse.publish( '/chat/general', { text: 'hello', user: 'alice' }, { event: 'message' }, ); ``` -------------------------------- ### Start Hapi Server Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/hapi/21/api.md Starts the Hapi server and logs its URI to the console. Ensure the server is properly shut down if it fails to start. ```javascript const Hapi = require('@hapi/hapi'); async function example() { const server = Hapi.server({ port: 80 }); await server.start(); console.log('Server started at: ' + server.info.uri); } ``` -------------------------------- ### Run Specific Vision Example Directories Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/vision/7/api.md Command examples to run specific templating engine examples within the Vision repository, such as Mustache or JSX. ```bash node examples/mustache node examples/mustache/partials node examples/jsx ``` -------------------------------- ### Start Hapi Server Entry Point Source: https://github.com/hapijs/hapi.dev/blob/master/docs/tutorials/en_US/testing.md This script serves as the main entry point for starting the Hapi server in a production or development environment. It imports the `start` function from the server module. ```javascript `use strict`; const { start } = require('lib/server'); start(); ``` -------------------------------- ### Initialize Hapi Server for Testing Source: https://github.com/hapijs/hapi.dev/blob/master/docs/tutorials/en_US/testing.md This code sets up a Hapi server instance and exports initialization and start functions. The `init` function is used for testing as it initializes the server without starting it, while `start` is for normal server execution. ```javascript "use strict"; const Hapi = require('@hapi/hapi'); const server = Hapi.server({ port: 3000, host: 'localhost', }); server.route({ method: 'GET', path: '/', handler: function () { return 'Hello World!'; }, }); exports.init = async () => { await server.initialize(); return server; }; exports.start = async () => { await server.start(); console.log(`Server running at: ${server.info.uri}`); return server; }; process.on('unhandledRejection', (err) => { console.log(err); process.exit(1); }); ``` -------------------------------- ### Initialize Server with await server.initialize() Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/hapi/21/api.md Initializes the server by starting caches and finalizing plugin registration without starting the connection listeners. If initialization fails, the server is in an undefined state and should be shut down. ```javascript const Hapi = require('@hapi/hapi'); const Hoek = require('@hapi/hoek'); async function example() { const server = Hapi.server({ port: 80 }); await server.initialize(); } ``` -------------------------------- ### Install with yarn Source: https://github.com/hapijs/hapi.dev/blob/master/docs/module/[name]/api/[version].md Use this command to install the hapi module using yarn. ```console yarn add @hapi/hapi@19.2.0 ``` -------------------------------- ### Initialize Server Views and Render Template Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/vision/7/api.md Initializes the server's view manager with a specific engine and template path, then renders a template using provided context. This example demonstrates the typical setup and usage of the Vision plugin for rendering HTML templates. ```javascript const Hapi = require('@hapi/hapi'); const server = Hapi.Server({ port: 3000 }); const internals = {}; internals.provision = async () => { await server.register(require('@hapi/vision')); server.views({ engines: { html: require('handlebars') }, path: __dirname + '/templates', }); const context = { title: 'Views Example', message: 'Hello, World', }; return server.render('hello', context); }; internals.provision(); ``` -------------------------------- ### Start Development Server Source: https://github.com/hapijs/hapi.dev/blob/master/README.md Starts the development server with hot reload. The site will be available at http://localhost:5173. ```bash pnpm dev ``` -------------------------------- ### Install @hapi/hapi with yarn Source: https://github.com/hapijs/hapi.dev/blob/master/docs/api/[version].md Use this command to install the @hapi/hapi package using yarn. ```console yarn add @hapi/hapi@{{ $params.fullVersion }} ``` -------------------------------- ### Initializing and Using Oppsy Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/oppsy/3/api.md Demonstrates how to create an Oppsy instance, listen for 'ops' events, and start data collection. ```APIDOC ## Usage ```js const Hapi = require('@hapi/hapi'); const Oppsy = require('@hapi/oppsy'); const server = new Hapi.Server(); const oppsy = new Oppsy(server); oppsy.on('ops', (data) => { console.log(data); }); await server.start(); oppsy.start(1000); ``` This creates a new Oppsy object and starts collecting information every 1000 milliseconds. ``` -------------------------------- ### Install with pnpm Source: https://github.com/hapijs/hapi.dev/blob/master/docs/module/[name]/api/[version].md Use this command to install the hapi module using pnpm. ```console pnpm add @hapi/hapi@19.2.0 ``` -------------------------------- ### Install with npm Source: https://github.com/hapijs/hapi.dev/blob/master/docs/module/[name]/api/[version].md Use this command to install the hapi module using npm. ```console npm install @hapi/hapi@19.2.0 ``` -------------------------------- ### Server Start Event Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/hapi/21/api.md Emitted when the server is started using server.start(). The handler takes no arguments. ```APIDOC ## 'start' Event ### Description Emitted when the server is started using `server.start()`. The handler takes no arguments. ### Signature `function()` ### Example ```js server.events.on('start', () => { console.log('Server started'); }); ``` ``` -------------------------------- ### Install @hapi/sse Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/sse/1/api.md Install the @hapi/sse package using npm. Ensure you have compatible versions of @hapi/hapi and @hapi/boom installed. ```bash npm install @hapi/sse ``` -------------------------------- ### Install @hapi/hapi with npm Source: https://github.com/hapijs/hapi.dev/blob/master/docs/api/[version].md Use this command to install the @hapi/hapi package using npm. ```console npm install @hapi/hapi@{{ $params.fullVersion }} ``` -------------------------------- ### Install @hapi/hapi with pnpm Source: https://github.com/hapijs/hapi.dev/blob/master/docs/api/[version].md Use this command to install the @hapi/hapi package using pnpm. ```console pnpm add @hapi/hapi@{{ $params.fullVersion }} ``` -------------------------------- ### Example Lifecycle Method Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/hapi/20/api.md This example demonstrates a basic lifecycle method that throws a Boom error for a specific query parameter or returns a success string. ```APIDOC ```js const handler = function (request, h) { if (request.query.forbidden) { throw Boom.badRequest(); } return 'success'; }; ``` ``` -------------------------------- ### Example Lifecycle Method Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/hapi/21/api.md A basic example of a route handler lifecycle method. It throws an error for a bad request or returns 'success'. ```javascript const handler = function (request, h) { if (request.query.forbidden) { throw Boom.badRequest(); } return 'success'; }; ``` -------------------------------- ### Install Joi for Hapi Source: https://github.com/hapijs/hapi.dev/blob/master/docs/tutorials/en_US/express-to-hapi.md Install the Joi package for data validation in Hapi.js applications. ```bash npm install joi ``` -------------------------------- ### oppsy.start(interval) Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/oppsy/3/api.md Starts the Oppsy object to begin collecting network and server information at a specified interval. ```APIDOC #### oppsy.start(interval) Starts an Oppsy object collecting network and server information. - `interval` - number of milliseconds to wait between each data sampling. ``` -------------------------------- ### Define a Basic GET Route Source: https://github.com/hapijs/hapi.dev/blob/master/docs/tutorials/en_US/routing.md Defines a simple GET route for the root path. The handler returns a 'Hello World!' string. ```javascript server.route({ method: 'GET', path: '/', handler: function (request, h) { return 'Hello World!'; }, }); ``` -------------------------------- ### Recommended ESLint Configuration Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/eslint-plugin/6/api.md Use this configuration for general hapi style guide rules. Add @hapi/eslint-plugin to your package.json. ```json { "extends": "plugin:@hapi/recommended" } ``` -------------------------------- ### Simulate a GET Request Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/hapi/21/api.md Injects a GET request to the root path and logs the result. This is a basic example of using server.inject() for testing. ```javascript const Hapi = require('@hapi/hapi'); async function example() { const server = Hapi.server({ port: 80 }); server.route({ method: 'GET', path: '/', handler: () => 'Success!' }); const res = await server.inject('/'); console.log(res.result); // 'Success!' } ``` -------------------------------- ### Server: Register Nes and broadcast a message Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/nes/13/api.md Registers Nes and starts the server, then broadcasts a message to all connected clients. ```javascript const Hapi = require('@hapi/hapi'); const Nes = require('@hapi/nes'); const server = new Hapi.Server(); const start = async () => { await server.register(Nes); await server.start(); server.broadcast('welcome!'); }; start(); ``` -------------------------------- ### Get Cookie Value with Hapi Source: https://github.com/hapijs/hapi.dev/blob/master/docs/tutorials/en_US/express-to-hapi.md Hapi accesses cookie values through `request.state`. This example demonstrates setting a cookie and then returning its value. ```javascript const Hapi = require('@hapi/hapi'); const server = Hapi.server({ port: 8000 }); server.state('username', { ttl: null, isSecure: true, isHttpOnly: true, }); server.route({ method: 'GET', path: '/', handler: async (request, h) => { h.state('username', 'tom'); return h.response(request.state.username); }, }); ``` -------------------------------- ### Client Initialization and Options Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/nes/13/api.md Explains how to create a new Nes client instance and the available configuration options. ```APIDOC ## `new Client(url, [options])` Creates a new client object where: - `url` - the WebSocket address to connect to (e.g. `'wss://localhost:8000'`). - `option` - optional configuration object where: - `ws` - available only when the client is used in node.js and passed as-is to the [**ws** module](https://www.npmjs.com/package/ws). - `timeout` - server response timeout in milliseconds. Defaults to `false` (no timeout). ``` -------------------------------- ### Get Cookie Value with Express Source: https://github.com/hapijs/hapi.dev/blob/master/docs/tutorials/en_US/express-to-hapi.md Express retrieves cookie values from `req.cookies` after the `cookieParser` middleware has been applied. This example also sets a cookie. ```javascript var express = require('express'); var app = express(); var cookieParser = require('cookie-parser); app.use(cookieParser()); app.get('/', (req, res) => { res.cookie('username', 'tom', { maxAge: null, secure: true, httpOnly: true }) res.send(req.cookies.username); }); ``` -------------------------------- ### Register Vision Plugin with Hapi Server Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/vision/7/api.md Basic setup for integrating the Vision plugin into a Hapi server. Ensure Vision is registered before starting the server. ```javascript const Hapi = require('@hapi/hapi'); const Vision = require('@hapi/vision'); const server = Hapi.Server({ port: 3000 }); const provision = async () => { await server.register(Vision); await server.start(); console.log('Server running at:', server.info.uri); }; provision(); ``` -------------------------------- ### Basic Router Usage Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/call/9/api.md Demonstrates creating a router instance, adding routes with different configurations, and matching routes. ```javascript const Call = require('@hapi/call'); // Create new router const router = new Call.Router(); // Add route router.add({ method: 'get', path: '/' }, { label: 'root-path' }); // Add another route router.add({ method: 'post', path: '/users' }, 'route specific data'); // Add another route with dynamic path router.add({ method: 'put', path: '/users/{userId}' }, () => { /* ...handler... */ }); // Match route router.route('post', '/users'); /* If matching route is found, it returns an object containing { params: {}, paramsArray: [], route: 'route specific data'; } */ // Match route router.route('put', '/users/1234'); /* returns { params: { userId: '1234' }, paramsArray: [ '1234' ], route: [Function] } */ ``` -------------------------------- ### Client API Methods Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/catbox/12/api.md The Client object provides a low-level cache abstraction with methods for starting, stopping, getting, setting, dropping, and validating cache items. ```APIDOC ## Client Methods ### `start()` - **Description**: Creates a connection to the cache server. Must be called before any other method is available. - **Return Value**: Throws an error if the request failed. ### `stop()` - **Description**: Terminates the connection to the cache server. - **Return Value**: Throws an error if the request failed. ### `get(key)` - **Description**: Retrieve an item from the cache engine if found. - **Parameters**: - `key` (object) - A cache key object with `segment` and `id` properties. - **Return Value**: - `null` if the item is not found. - Throws an error if the request failed. - Otherwise, an object with `item`, `stored`, and `ttl` properties. ### `set(key, value, ttl)` - **Description**: Store an item in the cache for a specified length of time. - **Parameters**: - `key` (object) - A cache key object with `segment` and `id` properties. - `value` (string | object) - The string or object value to be stored. - `ttl` (number) - A time-to-live value in milliseconds. - **Return Value**: Throws an error if the request failed. ### `drop(key)` - **Description**: Remove an item from cache. - **Parameters**: - `key` (object) - A cache key object with `segment` and `id` properties. - **Return Value**: Throws an error if the request failed. ### `isReady()` - **Description**: Returns `true` if the cache engine determines itself as ready, `false` otherwise. ### `validateSegmentName(segment)` - **Description**: Returns `null` if the segment name is valid, otherwise should return an instance of `Error`. - **Parameters**: - `segment` (string) - The segment name to validate. ### Cache Key Object Any method with a `key` argument takes an object with the following required properties: - **`segment`** (string) - A caching segment name string. - **`id`** (string) - A unique item identifier string (per segment). ``` -------------------------------- ### Create a Basic Hapi Server Source: https://github.com/hapijs/hapi.dev/blob/master/docs/tutorials/en_US/getting-started.md Initialize a new hapi server with connection details and start it. Ensure proper error handling for unhandled rejections. ```javascript "use strict"; const Hapi = require('@hapi/hapi'); const init = async () => { const server = Hapi.server({ port: 3000, host: 'localhost', }); await server.start(); console.log('Server running on %s', server.info.uri); }; process.on('unhandledRejection', (err) => { console.log(err); process.exit(1); }); init(); ``` -------------------------------- ### await server.start() Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/hapi/21/api.md Starts the server, making it listen for incoming requests on the configured port. If the connection is configured with `autoListen` set to `false`, it will not automatically listen. ```APIDOC ## await server.start() ### Description Starts the server by listening for incoming requests on the configured port (unless the connection was configured with [`autoListen`](#server.options.autoListen) set to `false`). Return value: none. Note that if the method fails and throws an error, the server is considered to be in an undefined state and should be shut down. In most cases it would be impossible to fully recover as the various plugins, caches, and other event listeners will get confused by repeated attempts to start the server or make assumptions about the healthy state of the environment. It is recommended to abort the process when the server fails to start properly. If you must try to resume after an error, call [`server.stop()`](#server.stop()) first to reset the server state. If a started server is started again, the second call to `server.start()` is ignored. No events will be emitted and no extension points invoked. ### Request Example ```js const Hapi = require('@hapi/hapi'); async function example() { const server = Hapi.server({ port: 80 }); await server.start(); console.log('Server started at: ' + server.info.uri); } ``` ``` -------------------------------- ### Get SSE Statistics Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/sse/1/api.md Retrieves built-in performance metrics tracked by the SSE plugin since server start. This includes connection counts, publish/broadcast operations, and delivered events. ```typescript const stats = server.sse.stats(); // { // totalConnections: 150, // totalDisconnections: 108, // totalPublishes: 5230, // totalBroadcasts: 12, // totalEventsDelivered: 48700, // activeSessions: 42, // } ``` -------------------------------- ### Hapi Route Test with Lab Source: https://github.com/hapijs/hapi.dev/blob/master/docs/tutorials/en_US/testing.md A basic test for a GET route, checking for a 200 status code. Uses 'lab' for test structure and '@hapi/code' for assertions. Ensure 'init' is used for server setup and 'stop' for teardown. ```javascript 'use strict'; const Lab = require('@hapi/lab'); const { expect } = require('@hapi/code'); const { afterEach, beforeEach, describe, it } = (exports.lab = Lab.script()); const { init } = require('../lib/server'); describe('GET /', () => { let server; beforeEach(async () => { server = await init(); }); afterEach(async () => { await server.stop(); }); it('responds with 200', async () => { const res = await server.inject({ method: 'get', url: '/', }); expect(res.statusCode).to.equal(200); }); }); ``` -------------------------------- ### Basic Static File Server Setup Source: https://github.com/hapijs/hapi.dev/blob/master/docs/tutorials/en_US/serving-files.md Use this snippet to set up a basic file server in Hapi. Ensure you have registered the Inert plugin and configured the routes.files.relativeTo option to point to your static assets directory. ```javascript const Path = require('path'); const Hapi = require('@hapi/hapi'); const Inert = require('@hapi/inert'); const init = async () => { const server = new Hapi.Server({ port: 3000, routes: { files: { relativeTo: Path.join(__dirname, 'public'), }, }, }); await server.register(Inert); server.route({ method: 'GET', path: '/{param*}', handler: { directory: { path: '.', redirectToSlash: true, }, }, }); await server.start(); console.log('Server running at:', server.info.uri); }; init(); ``` -------------------------------- ### Promise-based Setup and Test in Lab Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/lab/25/api.md Illustrates using Promises directly with `before()` and `test()` methods in Lab for asynchronous operations. This allows chaining asynchronous actions within tests. ```javascript lab.experiment('math', () => { lab.before(() => { return aFunctionReturningAPromise(); }); lab.test('returns true when 1 + 1 equals 2', () => { return aFunctionReturningAPromise().then((aValue) => { expect(aValue).to.equal(expectedValue); }); }); }); ``` -------------------------------- ### Server: Setup authentication and route Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/nes/13/api.md Registers Nes and Basic authentication, sets up a user validation strategy, and defines an authenticated route. ```javascript const Hapi = require('@hapi/hapi'); const Basic = require('@hapi/basic'); const Bcrypt = require('bcrypt'); const Nes = require('@hapi/nes'); const server = new Hapi.Server(); const start = async () => { await server.register([Basic, Nes]); // Set up HTTP Basic authentication const users = { john: { username: 'john', password: '$2a$10$iqJSHD.BGr0E2IxQwYgJmeP3NvhPrXAeLSaGCj6IR/XU5QtjVu5Tm', // 'secret' name: 'John Doe', id: '2133d32a', }, }; const validate = async (request, username, password) => { const user = users[username]; if (!user) { return { isValid: false }; } const isValid = await Bcrypt.compare(password, user.password); const credentials = { id: user.id, name: user.name }; return { isValid, credentials }; }; server.auth.strategy('simple', 'basic', { validate }); // Configure route with authentication server.route({ method: 'GET', path: '/h', config: { id: 'hello', handler: (request, h) => { return `Hello ${request.auth.credentials.name}`; }, }, }); await server.start(); }; start(); ``` -------------------------------- ### Install Dependencies with pnpm Source: https://github.com/hapijs/hapi.dev/blob/master/README.md Installs project dependencies using pnpm. Ensure Node.js v22+ and pnpm are installed. ```bash pnpm install ``` -------------------------------- ### Basic Test Script with Lab Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/lab/25/api.md This is a basic example of how to set up a test file using Lab. It requires the @hapi/code assertion library and exports the Lab script for defining tests. ```javascript const Code = require('@hapi/code'); const Lab = require('@hapi/lab'); const { expect } = Code; const { it } = (exports.lab = Lab.script()); it('returns true when 1 + 1 equals 2', () => { expect(1 + 1).to.equal(2); }); ``` -------------------------------- ### Initialize Catbox Redis Client Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/catbox-redis/7/api.md Demonstrates how to initialize a Catbox client with the Redis engine and custom options. ```javascript const Catbox = require('@hapi/catbox'); const { Engine: CatboxRedis } = require('@hapi/catbox-redis'); const cache = new Catbox.Client(CatboxRedis, { partition: 'my_cached_data', host: 'redis-cluster.domain.com', port: 6379, db: 0, tls: {}, }); ``` -------------------------------- ### Router Initialization and Route Addition Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/call/9/api.md Demonstrates how to create a new Call router instance and add routes with different configurations. ```APIDOC ## Router Initialization and Route Addition ### Description This section shows how to initialize a new router and add routes to it. Routes can be defined with specific methods and paths, and associated with data or handler functions. ### Method `new Call.Router()` - Constructor for the router. `router.add(routeDefinition, routeData)` - Method to add a route. ### Parameters #### `router.add` Parameters - **routeDefinition** (object) - Required - An object containing `method` (string) and `path` (string). - **routeData** (any) - Required - Data associated with the route, can be a string, object, or function. ### Request Example ```javascript const Call = require('@hapi/call'); // Create new router const router = new Call.Router(); // Add route router.add({ method: 'get', path: '/' }, { label: 'root-path' }); // Add another route router.add({ method: 'post', path: '/users' }, 'route specific data'); // Add another route with dynamic path router.add({ method: 'put', path: '/users/{userId}' }, () => { /* ...handler... */ }); ``` ``` -------------------------------- ### Install express-validator Source: https://github.com/hapijs/hapi.dev/blob/master/docs/tutorials/en_US/express-to-hapi.md Install the express-validator package for Express.js applications. ```bash npm install express-validator ``` -------------------------------- ### script.describe(title, [options], content) Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/lab/25/api.md Sets up an experiment (a group of tests), identical to `script.experiment()`. ```APIDOC ## script.describe(title, [options], content) ### Description Same as `script.experiment(title, [options], content)`. ### Parameters - **title** (string) - The experiment description. - **options** (object) - Optional settings: `skip` (boolean), `only` (boolean), `timeout` (number). - **content** (function) - A function with signature `function()` which can setup other experiments or tests. ``` -------------------------------- ### Load Multiple Plugins with Options Source: https://github.com/hapijs/hapi.dev/blob/master/docs/tutorials/en_US/plugins.md Illustrates registering an array of plugins, each with its own specific options. ```javascript const start = async function () { const server = Hapi.server(); await server.register([ { plugin: require('plugin1'), options: {}, }, { plugin: require('plugin2'), options: {}, }, ]); }; ``` -------------------------------- ### Log Server Start Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/hapi/21/api.md Logs a message when the Hapi server has successfully started. ```javascript server.events.on('start', () => { console.log('Server started'); }); ``` -------------------------------- ### script.suite(title, [options], content) Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/lab/25/api.md Sets up a test suite, which is a group of experiments, identical to `script.experiment()`. ```APIDOC ## script.suite(title, [options], content) ### Description Same as `script.experiment(title, [options], content)`. ### Parameters - **title** (string) - The suite description. - **options** (object) - Optional settings: `skip` (boolean), `only` (boolean), `timeout` (number). - **content** (function) - A function with signature `function()` which can setup other experiments or tests. ``` -------------------------------- ### Load Single and Multiple Plugins Source: https://github.com/hapijs/hapi.dev/blob/master/docs/tutorials/en_US/plugins.md Demonstrates loading a single plugin and multiple plugins using server.register(). ```javascript const start = async function () { const server = Hapi.server(); // load one plugin await server.register(require('myplugin')); // load multiple plugins await server.register([require('myplugin'), require('yourplugin')]); }; ``` -------------------------------- ### Load Plugin with Options Source: https://github.com/hapijs/hapi.dev/blob/master/docs/tutorials/en_US/plugins.md Shows how to pass options to a plugin during registration by providing an object with 'plugin' and 'options' keys. ```javascript const start = async function () { const server = Hapi.server(); await server.register({ plugin: require('myplugin'), options: { message: 'hello', }, }); }; ``` -------------------------------- ### Alias Example for 'help' Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/bossy/5/api.md Demonstrates how to define an alias for a command line argument. The 'h' key is set as an alias for the 'help' argument. ```js h: { alias: 'help'; } ``` -------------------------------- ### Install Bell for Hapi Source: https://github.com/hapijs/hapi.dev/blob/master/docs/tutorials/en_US/express-to-hapi.md Install the '@hapi/bell' npm package to enable third-party authentication in a Hapi application. ```bash npm install '@hapi/bell' ``` -------------------------------- ### For Loop Rule - Start Iterator Configuration Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/eslint-plugin/6/api.md Configures the starting variable name for for loop iterators. Defaults to 'i'. ```javascript "@hapi/for-loop": ["error", {"startIterator": "index"}] ``` -------------------------------- ### Slack Provider Params Example Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/bell/providers.md Example of using `providerParams` to authenticate a user in a specific Slack team. ```javascript providerParams: { team: 'T0XXXXXX'; } ``` -------------------------------- ### Basic Static File Server Setup Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/inert/7/api.md Sets up a Hapi.js server to serve static HTML content from the 'public' directory. Ensure the 'public' directory exists in your project root. This configuration uses the 'directory' handler for serving files. ```javascript const Path = require('path'); const Hapi = require('@hapi/hapi'); const Inert = require('@hapi/inert'); const server = new Hapi.Server({ port: 3000, routes: { files: { relativeTo: Path.join(__dirname, 'public'), }, }, }); const provision = async () => { await server.register(Inert); server.route({ method: 'GET', path: '/{param*}', handler: { directory: { path: '.', redirectToSlash: true, index: true, }, }, }); await server.start(); console.log('Server running at:', server.info.uri); }; provision(); ``` -------------------------------- ### Setup Hapi Server with Vision and Handlebars Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/vision/7/api.md This snippet demonstrates how to set up a Hapi server with the Vision plugin and Handlebars for rendering HTML templates. It configures the view engine and path, and defines a route that uses `h.view()` to render a template with context. ```javascript const Hapi = require('@hapi/hapi'); const server = Hapi.Server({ port: 3000 }); const internals = {}; internals.provision = async () => { await server.register(require('@hapi/vision')); server.views({ engines: { html: require('handlebars') }, path: __dirname + '/templates', }); const rootHandler = function (request, h) { const context = { title: 'Views Example', message: 'Hello, World', }; return h.view('hello', context); }; server.route({ method: 'GET', path: '/', handler: rootHandler }); }; internals.provision(); ``` -------------------------------- ### Example Validation Error Response Source: https://github.com/hapijs/hapi.dev/blob/master/docs/tutorials/en_US/validation.md This is an example of the JSON error response returned when payload validation fails. ```json { "error": "Bad Request", "message": "Invalid request payload input", "statusCode": 400 } ``` -------------------------------- ### Create a Simple Plugin Source: https://github.com/hapijs/hapi.dev/blob/master/docs/tutorials/en_US/plugins.md Define a plugin as an object with 'name', 'version', and an async 'register' function. The 'register' function receives the server instance and options, and can be used to add routes or perform other setup tasks. ```javascript 'use strict'; const myPlugin = { name: 'myPlugin', version: '1.0.0', register: async function (server, options) { // Create a route for example server.route({ method: 'GET', path: '/test', handler: function (request, h) { return 'hello, world'; }, }); // etc ... await someAsyncMethods(); }, }; ``` -------------------------------- ### Configure oxfmt with Hapi Style Guide Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/oxc-plugin/1/api.md Integrate the Hapi style guide formatting rules into your oxfmt configuration. ```typescript import { defineConfig } from 'oxfmt'; import DefaultOxfmtConfig from '@hapi/oxc-plugin/oxfmt'; export default defineConfig({ ...DefaultOxfmtConfig, }); ``` -------------------------------- ### get(uri, [options]) Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/wreck/18/api.md Convenience method for making GET requests. It returns a promise that resolves with the response object and payload. ```APIDOC ## get(uri, [options]) ### Description Convenience method for making GET requests. It returns a promise that resolves with the response object and payload. ### Parameters #### Path Parameters - `uri` (string) - The URI of the requested resource. - `options` (object) - Optional config object containing settings for both `request` and `read` operations. ### Returns A promise that resolves into an object with the following properties: - `res` (HTTP Incoming Message object) - The HTTP Incoming Message object, which is a readable stream that has "ended" and contains no more data to read. - `payload` (Buffer or object) - The payload in the form of a Buffer or (optionally) parsed JavaScript object (JSON). ### Throws Any error that may have occurred during handling of the request or a Boom error object if the response has an error status code (i.e. 4xx or 5xx). If the error is a boom error object it will have the following properties in addition to the standard boom properties: - `data.isResponseError` (boolean) - indicates if the error is a result of an error response status code - `data.headers` (object) - containing the response headers - `data.payload` (Buffer or object) - the payload in the form of a Buffer or as a parsed object - `data.res` (HTTP Incoming Message object) - the HTTP Incoming Message object. ``` -------------------------------- ### Preview Built Site Source: https://github.com/hapijs/hapi.dev/blob/master/README.md Previews the statically generated site. This command is useful for testing the production build locally. ```bash pnpm preview ``` -------------------------------- ### Install c8 for ESM Coverage Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/lab/25/api.md Install c8 as a development dependency to enable code coverage for ES modules when using Lab. ```bash npm install --save-dev c8 ``` -------------------------------- ### Install Passport and Twitter Strategy for Express Source: https://github.com/hapijs/hapi.dev/blob/master/docs/tutorials/en_US/express-to-hapi.md Install the necessary npm packages for Passport and the Twitter authentication strategy in an Express application. ```bash npm install passport passport-twitter ``` -------------------------------- ### Client Initialization Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/nes/14/api.md Creates a new Nes client instance to connect to a WebSocket server. ```APIDOC ## new Client(url, [options]) Creates a new client object where: - `url` - the WebSocket address to connect to (e.g. `'wss://localhost:8000'`). - `option` - optional configuration object where: - `ws` - available only when the client is used in node.js and passed as-is to the [**ws** module](https://www.npmjs.com/package/ws). - `timeout` - server response timeout in milliseconds. Defaults to `false` (no timeout). ``` -------------------------------- ### Hapi Input Validation Example Source: https://github.com/hapijs/hapi.dev/blob/master/docs/tutorials/en_US/express-to-hapi.md Example of validating request payload in Hapi using Joi. Define the expected schema for the payload. ```javascript const Joi = require('joi'); server.route({ method: 'POST', path: '/post', handler: (request, h) => { return 'Blog post added!'; }, options: { validate: { payload: Joi.object({ post: Joi.string().max(140), }), }, }, }); ``` -------------------------------- ### Basic GET Request with Wreck Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/wreck/18/api.md Demonstrates a simple GET request to a URL and logs the payload. Ensure Wreck is required before use. ```javascript const Wreck = require('@hapi/wreck'); const example = async function () { const { res, payload } = await Wreck.get('http://example.com'); console.log(payload.toString()); }; try { example(); } catch (ex) { console.error(ex); } ``` -------------------------------- ### new Oppsy(server, [config]) Source: https://github.com/hapijs/hapi.dev/blob/master/generated/markdown/oppsy/3/api.md Constructor for the Oppsy object. Initializes Oppsy with a Hapi server instance and optional configuration. ```APIDOC ### new Oppsy(server, [config]) Creates a new Oppsy object. - `server` - the hapi server to collect information about. - `[config]` - optional configuration object - `httpAgents` - the list of httpAgents to report socket information about. Can be a single http.Agent or an array of agents objects. Defaults to Http.globalAgent. - `httpsAgents` - the list of httpsAgents to report socket information about. Can be a single https.Agent or an array of agents. Defaults to Https.globalAgent. The oppsy object is an EventEmitter so it exposes the same API(`.on` and `.emit`) as the Node EventEmitter object. After it is started, it emits an "ops" event after a set interval with the collected ops information as the event payload. ```