diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml
index 6671f9a..569efa1 100644
--- a/.github/workflows/testing.yml
+++ b/.github/workflows/testing.yml
@@ -6,6 +6,7 @@ on:
jobs:
+
unit-test:
strategy:
matrix:
@@ -27,8 +28,32 @@ jobs:
- name: Install dependencies
run: npm install
- - name: Run Tests
- run: npm test
+ - name: Run Unit Tests
+ run: npm run test-unit
+
+
+ endpoint-test:
+ strategy:
+ matrix:
+ os: [ubuntu-latest, windows-latest, macos-latest]
+
+ name: Endpoint Tests (${{ matrix.os }})
+ runs-on: ${{ matrix.os }}
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 20
+
+ - name: Install dependencies
+ run: npm install
+
+ - name: Run Endpoint Tests
+ run: npm run test-endpoints
+
linting:
name: Linting
diff --git a/.gitignore b/.gitignore
index 1ac4fed..49124ee 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
**/.vercel/
**/.sherpa/
+**/.sherpa-dev/
**/sherpa.TS_VALIDATION_BUFFER.ts
/node_modules
/dist
diff --git a/README.md b/README.md
index dfafb0d..fc3f211 100644
--- a/README.md
+++ b/README.md
@@ -1,827 +1,41 @@
-
-# SherpaJS - Serverless Web Framework
-
-[](https://github.com/sellersindustry/SherpaJS/actions/workflows/testing.yml)
-> [!TIP]
-> **The documenation is a bit of a mess right now, to get an overview really quick just checkout the [server example](https://github.com/sellersindustry/SherpaJS-template-server).**
-> [!IMPORTANT]
-> This project is in early development, so it is possible for you to run into issues. If you run into any issues please just create a new issue and link your code. Feel free to debug or update the code!
->
-> - If you have an issue, [let us know](https://github.com/sellersindustry/SherpaJS/issues), even if you fix it. It could help us build a better linter.
-> - If the documentation is confusing some place, [ask](https://github.com/sellersindustry/SherpaJS/issues). Also feel free to make a pull request with the updates.
-> - Have a suggested change or feature? [Submit a Ticket](https://github.com/sellersindustry/SherpaJS/issues)
-> - Need a module that isn't built? Please help us build the SherpaJS Community and built it following our [build guide](#create-a-module), then [submit your module to the community](https://github.com/sellersindustry/SherpaJS/issues).
->
-> [Development Notes](#development)
+
-SherpaJS empowers developers to effortlessly construct **modular and agnostic serverless applications**. Developers can easily build serverless web server using a directory-based structure, inspired by NextJS and even import pre-built modules at endpoints. SherpaJS servers can then be compiled to a variety of different web platforms including Vercel Serverless and local Server (with more to come later).
+
+
+
+
-
-
-
-## Table of Contents
- - [Supported Platforms](#deploy-a-server)
- - [Community Modules](#community-modules)
- - [Installation](#installation)
- - [Commands](#commands)
- - [Servers](#servers)
- - [Create a Server](#creating-a-server)
- - [Configuration](#server-configuration)
- - [Deploy a Server](#deploy-a-server)
- - Routing
- - [Routes](#routes)
- - [Endpoints](#endpoints)
- - [Static Assets](#static-assets)
- - [Modules](#modules)
- - [Create a Module](#creating-a-module)
- - [Configuration](#module-configuration)
- - [Development & Contributing](#development)
-
-
-
-
-
-
-## Community Modules
-| Module | Description |
-|---|---|
-| [Static Flags](https://github.com/sellersindustry/SherpaJS-static-flags) | Create static flags of booleans, strings, or numbers |
-| [Events](https://github.com/sellersindustry/SherpaJS-events) | Create event sending endpoints for analytics platforms like PostHog using [Metadapter Events](https://github.com/sellersindustry/metadapter-event) |
-
-
-
-
-
-## Installation
-To install SherpaJS, simply run the following command in your terminal:
-```bash
-npm install sherpa-core -g
-```
-This command will globally install the SherpaJS core package, enabling you to utilize its features across your system. Once installed, you can easily run the SherpaJS command-line interface (CLI) using the following command:
-```bash
-sherpa
-npx sherpa
-```
-This command initializes the SherpaJS CLI, allowing you to efficiently manage and configure your modular microservice endpoints. [Learn about CLI Commands](#commands).
-
-
-
-
-
-
-## Commands
-CLI for SherpaJS - Modular Microservices Framework
-
-```bash
-sherpa [options] [command]
-```
-
-#### Options:
- - `-V`, `--version` output the version number
- - `-h`, `--help` display help for command
-
-#### Commands:
- - `build [options]` Build SherpaJS Server
- - `clean [options]` Remove SherpaJS Build Directories
- - `help [command]` display help for command
-
-
-
-
-
-### Build Command
-Build SherpaJS Server.
-```bash
-sherpa build [options]
-```
-
-#### Options:
- - `-i`, `--input ` path to SherpaJS server, defaults to current directory
- - `-o`, `--output ` path to server output, defaults to input directory
- - `-b`, `--bundler ` platform bundler ("**Vercel**", "*local**", *default: "local"*)
- - `-v`, `--variable [key values...]` Specify optional environment variables as key=value pairs Ex. `foo=bar test="1234 HI"`
- - `--dev` enable development mode, does not minify output
- - `-h`, `--help` display help for command
-
-
-
-
-
-### Start Command
-Start SherpaJS Server Locally. Ensure you have created a [local build](#build-command).
-```bash
-sherpa start [options]
-```
-
-#### Options:
- - `-i`, `--input ` path to SherpaJS server, defaults to current directory
- - `-p`, `--port ` port number (default: "3000")
- - `-h`, `--help` display help for command
-
-
-
-
-
-### Clean Command
-Remove SherpaJS Build Directories.
-```bash
-sherpa clean [options]
-```
-
-#### Options:
- - `-i`, `--input ` path to SherpaJS build directories, defaults to current directory
- - `-h`, `--help` display help for command
-
-
-
-
-
-
-## Servers
-A SherpaJS server is a backend web server framework, akin to Flask, primarily
-designed for creating serverless applications, offering developers a
-lightweight and modular approach to building scalable backend services in JavaScript.
-
-### Creating a Server
-Creating a new server is extremely easy and can be done within a couple of
-minutes. Check out the [SherpaJS Server Template](https://github.com/sellersindustry/SherpaJS-template-server)
-for an example of how to build your server.
-
-#### Step 1
-Setup a new NodeJS project with `npm init`.
-
-#### Step 2
-Install SherpaJS with `npm install sherpa-core`.
-
-#### Step 3
-Create a new server configuration file in the root directory of your server name `sherpa.server.ts`. This file will default export a [server configuration](#server-configuration).
-
-```typescript
-// sherpa.server.ts
-import { SherpaJS } from "sherpa-core";
+---
-export default SherpaJS.New.server({
- context: { // contexts are provided to endpoints, and are optional
- example: "foo"
- }
-});
-```
-#### Step 4
-Create an your endpoints in the `/routes` directory. See an example below or [learn about endpoints](#endpoints).
+## Getting Started
+SherpaJS is a modular and agnostic serverless JavaScript web framework, that allows developers to easily build backend serverless web applications.
-```typescript
-// ./routes/index.ts
-import { Request, Response, Context } from "sherpa-core";
-
-export function GET(request:Request, context:Context) {
- return Response.text("Hello World!");
-}
-```
-
-> [!NOTE]
-> It's here where you can load pre-build SherpaJS modules and provide them with context.
-> [Loading Modules](#module-endpoint)
-
-
-#### Step 6
-Build the local server with `sherpa build` [command](#build-command). This
-will create a NodeJS file at `./.sherpa/index.js` which you can start at using
-`node ./.sherpa/index.js` see [local server platform](#local-server) for additional information.
-
-That's it! You're now ready to start building powerful serverless web
-applications with SherpaJS. Happy coding! ⚓
-
-
-
-
-
-### Server Configuration
-Sherpa servers are configured using a `sherpa.server.ts` file, where you define
-the structure and behavior of your server. This configuration file serves as
-the entry point for your Sherpa server.
-
-
-#### Config File
-The file must located at `sherpa.server.ts` and have a default export of the
-config and use the `SherpaJS.New.server` function as follows:
-```typescript
-import SherpaJS from "sherpa-core";
-
-export default SherpaJS.New.server();
-```
-
-#### Config Structure
- - **Context:** An optional property that allows you to define a context
- object. Contexts are provided to endpoints and can contain any
- additional data or settings needed for request processing.
-
-The configuration provided to the server must match the TypeScript object as follows:
-```typescript
-export type Context = unknown;
-
-export type ServerConfig = {
- context: Schema;
-};
-```
-
-#### Example Config
-```typescript
-// sherpa.server.ts
-import { SherpaJS } from "sherpa-core";
-
-export default SherpaJS.New.server({
- context: {
- serverSecret: "foo",
- allowThingy: true
- }
-});
-```
-
-```typescript
-// sherpa.server.ts
-import { SherpaJS } from "sherpa-core";
-
-type ConfigExample = { serverSecret:string, allowThingy:boolean };
-export default SherpaJS.New.server({
- context: {
- serverSecret: "foo",
- allowThingy: true
- }
-});
-```
-
-
-
-
-### Environment Variables
-The `.env` environment file is loaded into your server when the system is
-compiled. Any environment variables provided by hosting services (like Vercel)
-will also automatically be included in your build.
-
-
-
-
-
-
-### Deploy a Server
-SherpaJS can compile to various different web platforms, with more to come
-later. [Want to support a new framework? Submit a Ticket](https://github.com/sellersindustry/SherpaJS/issues).
-See the [build command](#build-command) to compile to each platform.
-
-
-#### Vercel Serverless
-Building to Vercel will generate a Vercel serverless server in the `.vercel`
-directory relative to your output. When your SherpaJS server repository is
-deployed Vercel this folder will automatically be deployed. Ensure your build
-command is set to build SherpaJS with the Vercel bundler.
-
-
-#### Local Server
-Building to local server will generate a NodeJS server, that utilizes the built
-in HTTP service. This server will be located at the `.sherpa/index.js` relative
-to your output. By default the port number is `3000` but you can provide an
-different port number with an argument `node ./.sherpa/index.js 5000`.
-
-
-
-
-
-
-## Routes
-Routes in SherpaJS provide a flexible and intuitive way to define
-[endpoints](#endpoints) and handle incoming requests within your microservice
-architecture. Drawing inspiration from Next.js, SherpaJS routes follow a
-directory-based structure located in the `/routes` directory of your module.
-
-
-### Structure of Routes
-In the `/routes` directory, you can create additional directories to organize
-your routes. For instance, you might have a directory like `/example`, which
-contains specific endpoints related to a particular feature or functionality.
-Each endpoint within a route is represented by a file named `index.ts`.
-
-Subroutes are located relative to the modules. For example if an endpoint is
-defined in a module at `/example` and the module is loaded at `/app-1/foo` then
-the example endpoint will be accessed at `/app-1/foo/example`.
-
-### Dynamic Routes
-To define a dynamic route, simply name a directory using square brackets, such
-as `[id]`. Within a dynamic route directory, you can access the parameter value
-from the request object in your endpoint logic. For example, if you have a
-dynamic route named `[id]`, you can access the parameter using
-`request.params.path.get("id")`, to learn more see [endpoint requests](#requests).
-
-### Examples of Route Structures
-```less
-/routes
-│
-├── /users
-│ └── index.ts // Endpoint logic for "/users"
-│
-├── /posts
-│ └── index.ts // Endpoint logic for "/posts"
-│
-├── /auth
-│ └── index.ts // Endpoint logic for "/auth"
-
-```
-
-```less
-/routes
-│
-├── /example
-│ ├── index.ts // Endpoint logic for "/example"
-│ ├── /subroute
-│ └── index.ts // Endpoint logic for "/example/subroute"
-│
-├── /[id]
-│ └── index.ts // Endpoint logic for "/[id]" access "[id]" with request.params.path.get("id")
-```
-
-```less
-/routes
-│
-├── /products
-│ ├── index.ts // Endpoint logic for "/products"
-│ ├── /[productID]
-│ │ └── index.ts // Endpoint logic for "/products/[productID]" access "[productID]" with request.params.path.get("productID")
-│ │
-│ └── /category
-│ └── index.ts // Endpoint logic for "/products/category"
-
-```
+ * Check out the [documentation](https://docs.page/sellersindustry/SherpaJS)
+ * Check out the [server template example](https://github.com/sellersindustry/SherpaJS-template-server)
+ * Check out the [module template example](https://github.com/sellersindustry/SherpaJS-template-module)
-## Endpoints
-Endpoints represent the individual points of access within your microservice
-architecture, allowing clients to interact with specific functionalities or
-resources. Endpoints are defined within route files `index.ts` and are
-associated with specific HTTP methods (GET, POST, PATCH, PUT, DELETE) to
-perform corresponding actions.
-
-### Function Endpoint
-Each endpoint is defined within a route file using the corresponding
-HTTP method function. These functions provide access to the incoming request
-and the environment, allowing developers to customize the endpoint's behavior
-based on the request data and the server environment.
-
-Endpoint can be defined by exporting a function with the desired method name.
-The following HTTP methods are supported: `GET`, `POST`, `PATCH`, `PUT`, and
-`DELETE`.
-
-Endpoint functions receive two parameters: the [request](#requests) which
-contains the HTTP request information and the [context](#context) which is
-additional properties provided to configure the endpoint. The context is either
-provided by the [server configuration](#server-config), if it's the root route
-or the [module loader](#module-endpoint), if it's a module route.
-
-A response should be returned by the function, using the
-[SherpaJS Response utility](#response).
-
-```typescript
-import { Request, Context, Response } from "sherpa-core";
-
-// Example GET endpoint
-export function GET(request:Request, context:Context) {
- return Response.text("Hello World");
-}
-
-// Example POST endpoint
-export function POST(request:Request, env:Environment) {
- return Response.text("Example POST", { status: 201 });
-}
-
-// Example DELETE endpoint
-export function DELETE(request:Request, env:Environment) {
- return Response.JSON({ message: "DELETE request received" }, { status: 204 });
-}
-```
-
-
-### View Endpoint
-Endpoints can also render views, this include HTML _(more to come soon)_ files.
-To render a view simply place the view file (named `index.html`) in the
-endpoint directory.
-
-When rendering a view you are not allowed to also have a `GET` method in your
-function endpoint. Additionally, function endpoints are not required when a view
-is provided. View endpoints do not support module endpoints.
-
-
-### Module Endpoint
-SherpaJS allows endpoint modules to be loaded, which is a set of endpoints
-built by the [community](#community-modules) or [your self](#creating-a-module).
-By integrating these prebuilt modules which can range from authentication to
-analytics into your server, you can easily extend your server's
-functionality without duplicating code. This promotes code organization,
-modularity, and reusability, simplifying development and accelerating
-time-to-market for your web applications.
-
-Modules are loaded in the same endpoint file (`index.ts`) as a regular endpoint,
-but instead of export HTTP methods you export a loaded module. Simply import the
-module and use the `load` method, while providing the context.
-
-This entry point can either be a relative directory (in which case you must
-specify the `sherpa.module` file) or a NPM package name.
-
-```typescript
-// index.ts
-import StaticFlags from "sherpajs-static-flags";
-
-export default StaticFlags.load({
- test: "Hello World"
-});
-```
-
-```typescript
-// index.ts
-import ExampleModule from "../../modules/sherpa.module";
-
-export default ExampleModule.load({
- test: "Hello World"
-});
-```
-
-
-### Requests
-The request as a typescript type. Parameters are parsed are parsed as the types
-they are provided as and if multiple are provided as an array.
-
-```typescript
-enum BodyType {
- JSON = "JSON",
- Text = "Text",
- None = "None"
-}
-
-type Body = Record|string|undefined;
-
-interface Request {
- readonly url:string;
- readonly params:{ path:Parameters, query:Parameters };
- readonly method:keyof typeof Method;
- readonly headers:Headers;
- readonly body:Body;
- readonly bodyType:keyof typeof BodyType;
-}
-```
-
-#### Request Example
- - `doc/abc/def/page/2?thing1=foo,bar&thing2=true&thing2=false&thing3=4`
- - `doc/[testID]/[testID]/page/[pageID]`
- - `request.params.path.get("testID")` ➜ `"abc"`
- - `request.params.path.getAll("testID")` ➜ `[ "abc", "def" ]`
- - `request.params.path.has("testID")` ➜ `true`
- - `request.params.path.keys()` ➜ `[ "testID", "pageID" ]`
-```json
-{
- "url": "/regular/dynamic-paths/abc/def/page/2",
- "params": {
- "path": {
- "testID": [ "abc", "def" ],
- "pageID": [ 2 ]
- },
- "query": {
- "thing1": [ "foo", "bar" ],
- "thing2": [ true, false ],
- "thing3": [ 4 ]
- }
- },
- "method": "POST",
- "headers": {
- "content-type": "application/json",
- },
- "bodyType": "JSON",
- "body": {
- "test": "hello world"
- }
-}
-```
-
-
-### Context
-The [context](#context) is additional properties provided to configure the
-endpoint. The context is either provided by the
-[server configuration](#server-config), if it's the root route or the
-[module loader](#module-endpoint), if it's a module route. If the module provides
-a context schema type, the context provided will be verified during build.
-
-
-### Response
-The Response class is used to generate HTTP responses. It provides static
-methods to create different types of responses, such as text, JSON, and
-redirects.
-
-#### Blank Response
-Creates a new response object with default options. Optional provide object that
-specifies custom response options such as headers and status code.
-
-```typescript
-import { Request, Headers } from "sherpa-core";
-Response.new();
-Response.new({ status: 201 });
-Response.new({ status: 201, headers: new Headers() });
-```
-
-#### Text Response
-Generates a text response with the specified text content. Optional provide
-object that specifies custom response options such as headers and status code.
-
-```typescript
-import { Request, Headers } from "sherpa-core";
-Response.text("hello world");
-Response.text("hello world", { status: 201 });
-Response.text("hello world", { status: 201, headers: new Headers() });
-```
-
-
-#### JSON Response
-Generates a JSON response with the specified JSON data. Optional provide
-object that specifies custom response options such as headers and status code.
-
-```typescript
-import { Request, Headers } from "sherpa-core";
-Response.text({ test: "hello world" });
-Response.text({ foo: "bar" }, { status: 201 });
-Response.text({ num: 3 }, { status: 201, headers: new Headers() });
-```
-
-
-#### Redirect Response
-Generates a redirect response with the specified URL. This URL can either be either...
- - Absolute with Origin `https://example.com/foo`
- - Absolute `/foo`
- - Relative `./foo` or `../foo`
-Optional provide object that specifies custom response options such as headers
-and status code.
-
-```typescript
-import { Request, Headers } from "sherpa-core";
-Response.redirect("https://example.com/foo");
-Response.redirect("/foo", { status: 201 });
-Response.redirect("../foo", { status: 201, headers: new Headers() });
-```
-
-
-## Static Assets
-SherpaJS servers can serve static assets under the `public` folder.
-
-
-
-
-
-## Modules
-Modules are self-contained units of functional endpoints. They can do various
-tasks such as analytics, status updates, authentication, and more. There are
-plenty of [community modules](#community-modules), but if what you need doesn't
-exist, developing your own modules is very simple.
-
-
-
-### Creating a Module
-A new module can be created relatively easily in just a couple of minutes. Check
-out the [SherpaJS Module Template](https://github.com/sellersindustry/SherpaJS-template-module)
-for an example of how to build your module.
-
-#### Step 1
-Setup a new NodeJS project with `npm init`.
-
-> [!TIP]
-> You don't have to create a repository to make a module. If you choice you can
-> simply create a new directory in your server and skip to [step 3](#step-3-1).
-
-Ensure your main is set to `sherpa.module.ts` so your ContextSchema and other
-resources are accessible by servers implementing your module.
-```json
-{
- "name": "sherpa-module",
- "version": "0.0.2",
- "main": "sherpa.module.ts",
- "scripts": {
- "build": "sherpa build -b Vercel",
- "dev": "sherpa build -b local && node ./.sherpa/index.js"
- }
-}
-```
-
-#### Step 2
-Install SherpaJS with `npm install sherpa-core`.
-
-#### Step 3
-Then create a module configuration file in the root directory of your modules
-named `sherpa.module.ts`. This file will default export
-a [module configuration](#module-configuration).
-
-
-```typescript
-// sherpa.module.ts
-import { SherpaJS, CreateModuleInterface } from "sherpa-core";
-
-export default SherpaJS.New.module({
- name: "example-module",
- interface: CreateModuleInterface<{ foo: boolean, bar: string }>
-});
-```
-
-Alteratively, you can export any `interface` class with a constructor that
-takes the context as a parameter sets `this.context` within your class. You
-can attach additional methods onto this, that can be used to interact with your
-module.
-
-```typescript
-// sherpa.module.ts
-import { SherpaJS, ModuleInterface } from "sherpa-core";
-
-export default SherpaJS.New.module({
- name: "pass-primary-1",
- interface: class example implements ModuleInterface {
- context:{ foo: number, bar: string };
- constructor(context:{ foo: number, bar: string }) {
- this.context = context;
- }
- }
-});
-```
-
-
-#### Step 4
-To create endpoints for a new module in SherpaJS, you'll create a new
-`/routes` directory the module. Each path inside the route directory will
-correspond to it's relative endpoint. Endpoint logic is implemented in
-javascript file named `index.ts` within these route directories.
-
-A simple implementation of an endpoint can be seen below. For detailed
-instructions on creating routes and endpoints, see the [endpoints](#endpoints)
-section.
-
-```typescript
-// ./route/example/index.ts
-import { Response, Request, Environment } from "sherpa-core";
-
-export function GET(request:Request, env:Environment) {
- return Response({ "hello": "world" });
-}
-```
-
-#### Step 6
-Create a [Sherpa Server](#servers) to test your module. For more details about
-creating server configs see the [creating a server](#creating-a-server) section.
-
-```typescript
-// sherpa.server.ts
-import { SherpaJS } from "sherpa-core";
-
-export default SherpaJS.New.server({
- context: {
- test: true
- }
-});
-```
-
-
-#### Step 7
-Share your module with the world and get it listed as a [SherpaJS Community module](#community-modules) by [submitting a new issue](https://github.com/sellersindustry/SherpaJS/issues/new/choose).
-
-> [!IMPORTANT]
-> Ensure your module...
-> - Is deployed as an NPM package
-> - Contains the documentation on how to set it up, like what properties are required.
-> - Link to the SherpaJS documentation, so people understand how to set it up.
-> - Share your creation with the world!! Help support SherpaJS!!!
-
-**Thanks so much for helping support SherpaJS!!! 🥳🎉**
-
-
-
-### Module Configuration
-Sherpa modules are configured using a `sherpa.module.ts` file, where you define
-the structure and behavior of your module. This configuration file serves as
-the entry point for your Sherpa module.
-
-
-#### Config File
-The file must located at `sherpa.module.ts` and have a default export of the
-config and use the `SherpaJS.New.module` function as follows. You can export
-a class using `ContextSchema`, that acts as a wrapper for validating the
-context when the module is [loaded](#module-endpoint).
-
-```typescript
-// sherpa.module.ts
-import { SherpaJS, CreateModuleInterface } from "sherpa-core";
-
-export default SherpaJS.New.module({
- name: "pass-primary-1",
- interface: CreateModuleInterface<{ foo: boolean, bar: }>
-});
-```
-
-Alteratively, you can export any `interface` class with a constructor that
-takes the context as a parameter sets `this.context` within your class. You
-can attach additional methods onto this, that can be used to interact with your
-module.
-
-```typescript
-// sherpa.module.ts
-import { SherpaJS, ModuleInterface } from "sherpa-core";
-
-export default SherpaJS.New.module({
- name: "pass-primary-1",
- interface: class example implements ModuleInterface {
- context:{ foo: number, bar: string };
- constructor(context:{ foo: number, bar: string }) {
- this.context = context;
- }
- }
-});
-```
-
-You can also export any additional attributes that you need, because `sherpa.module.ts`
-should be the main script defined in your `package.json`.
-
-
-#### Config Structure
- - **Name:** The name of the module.
- - **Interface:** Class that has `constructor(context:[TYPE])` and
- property `context:[TYPE]`.
-
-The configuration provided to the module creator must match the TypeScript object as follows:
-```typescript
-export type ModuleConfig = {
- name: string;
- interface: Class;
-};
-```
-
-#### Example Config
-```typescript
-// sherpa.module.ts
-import { SherpaJS, CreateModuleInterface } from "sherpa-core";
-
-export default SherpaJS.New.module({
- name: "pass-primary-1",
- interface: CreateModuleInterface<{ foo: boolean, bar: }>
-});
-```
-
-
-
-
-
-
-## Development
-This project is in early development, so it is possible for you to run into issues. We do use this product in production, but that doesn't mean there could be issues. If you run into any issues, they will probably be at build time, just let us know.
-
-
-
-
-
-### Contributing
+## Contributing
Any help is very much appreciated. Build some useful modules and [submit them to our community](https://github.com/sellersindustry/SherpaJS/issues/new/choose) module list. Even help with documentation or refactoring code is helpful.
-### Proposed Features
- - Build Test Harness to test standard endpoint features, bug detection, (and later Vercel Deployment).
- - Support more than Text and JSON body payloads
- - Auto reloading development server.
- - Clean Command.
- - Add SherpaJS 500 Error Page.
- - Add SherpaJS 404 Error Page.
- - Ability to add custom 500 and 404 error pages, with HTML in `/errors`.
- - Catch all dynamic routes.
- - Ability to add admin portal
- - Ability to interact with modules. This can allow other endpoints or code
- in the system or admin portals to call special functions that are part of the
- module, with the given context.
- - Import the endpoint which loads the module. The default export
- using SherpaJS.Load.module(path, context, interactionClass); will have
- a added optional variable of a class. The sherpaJS.Load.module will return
- an instatiatied version of tha class with the context.
- - Public Assets
- - Migrate to RUST (Start by Migrating Tooling as it probs takes the longest)
- - Make a document website with [Mintlify](https://mintlify.com/preview).
- - Console Development Server, Live Logs
-
-
-
-
-### Proposed Modules
- - Dynamic redirect service.
- - Authical Authentication Service.
- - GitHub Issue Creator Form for Support
-
-
-
### Credits
+ - [Evan Sellers](https://github.com/SellersEvan)
- Illustration by Icons 8 from Ouch!
diff --git a/docs.json b/docs.json
index a8a81a9..663b63f 100644
--- a/docs.json
+++ b/docs.json
@@ -2,6 +2,9 @@
"name": "SherpaJS",
"description": "Module and Reusable Microservice Platform. Build and modularize custom API endpoints, inspired by NextJS APIs. Export to Vercel and ExpressJS.",
"headerDepth": 5,
+ "logo": "./assets/logos/favicon.png",
+ "logoDark": "./assets/logos/favicon.png",
+ "theme": "#0D95DC",
"sidebar": [[
"Getting Started",
[
@@ -12,16 +15,18 @@
], [
"Building Your Application",
[
- ["Routes - WIP", "/build/routes"],
- ["Endpoints - WIP", "/build/endpoints"],
- ["Static Assets - WIP", "/build/static-assets"],
- ["Server Config - WIP", "/build/server-config"],
- ["Module Config - WIP", "/build/module-config"]
+ ["Routing", "/build/routing"],
+ ["Endpoints", "/build/endpoints"],
+ ["Static Assets", "/build/static-assets"],
+ ["Server Config", "/build/server-config"],
+ ["Module Config", "/build/module-config"],
+ ["Building a Module", "/build/building-a-module"],
+ ["Miscellaneous", "/build/miscellaneous"]
]
], [
"API Reference",
[
- ["Response - WIP", [["Response - WIP", "/api/response"]]],
+ ["Response", "/api/components/response"],
["Request", "/api/components/request"],
["Headers", "/api/components/headers"],
["Parameters", "/api/components/parameters"],
diff --git a/docs/api/cli.mdx b/docs/api/cli.mdx
index bbfc427..da9b9f5 100644
--- a/docs/api/cli.mdx
+++ b/docs/api/cli.mdx
@@ -38,14 +38,15 @@ CLI for SherpaJS - Modular Microservices Framework
sherpa [options] [command]
```
-#### Options:
+**Options:**
- `-V`, `--version` output the version number
- `-h`, `--help` display help for command
-#### Commands:
- - `build [options]` Build SherpaJS Server
- - `start [options]` Start SherpaJS Server Locally
- - `clean [options]` Remove SherpaJS Build Directories
+**Commands:**
+ - `build [options]` Creates a production build of your application
+ - `start [options]` Start a production build of your application
+ - `clean [options]` Removes all build directories of your application
+ - `dev [options]` Start a server in development mode with hot-reload
- `help [command]` display help for command
@@ -53,12 +54,12 @@ sherpa [options] [command]
### Build Command
-Build SherpaJS Server.
+Creates a production build of your application.
```bash
sherpa build [options]
```
-#### Options:
+**Options:**
- `-i`, `--input ` path to SherpaJS server, defaults to current directory
- `-o`, `--output ` path to server output, defaults to input directory
- `-b`, `--bundler ` platform bundler ("**Vercel**", "*local**", *default: "local"*)
@@ -72,12 +73,13 @@ sherpa build [options]
### Start Command
-Start SherpaJS Server Locally. Ensure you have created a [local build](/api/cli#build-command).
+Start a production build of your application. Ensure you have created a local
+build, with [\"sherpa build\"](/api/cli#build-command) first.
```bash
sherpa start [options]
```
-#### Options:
+**Options:**
- `-i`, `--input ` path to SherpaJS server, defaults to current directory
- `-p`, `--port ` port number (default: "3000")
- `-h`, `--help` display help for command
@@ -87,12 +89,29 @@ sherpa start [options]
### Clean Command
-Remove SherpaJS Build Directories.
+Removes all build directories of your application.
```bash
sherpa clean [options]
```
-#### Options:
+**Options:**
- `-i`, `--input ` path to SherpaJS build directories, defaults to current directory
- `-h`, `--help` display help for command
+
+
+
+
+### Dev Command
+Start a server in development mode with hot-reload.
+```bash
+sherpa dev [options]
+```
+
+**Options:**
+ - `-i`, `--input ` path to SherpaJS server, defaults to current directory
+ - `-o`, `--output ` path to server output, defaults to input directory
+ - `-v`, `--variable [key values...]` Specify optional environment variables as key=value pairs Ex. `foo=bar test="1234 HI"`
+ - `-p`, `--port ` port number (default: "3000")
+ - `-h`, `--help` display help for command
+
diff --git a/docs/api/components/parameters.mdx b/docs/api/components/parameters.mdx
index 28489ff..41ee115 100644
--- a/docs/api/components/parameters.mdx
+++ b/docs/api/components/parameters.mdx
@@ -6,6 +6,11 @@ includes numbers and booleans. This class is very similar to the standard
[URLSearchParams class](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)
used in web APIs.
+When parameters come from the [`Request`](/api/components/request) class, from a
+URL they are automatically parsed (booleans and numbers) and seperated by commas.
+See [request examples](/api/components/request#basic-get-request), for more
+information.
+
diff --git a/docs/api/components/request.mdx b/docs/api/components/request.mdx
index d3a824a..a434580 100644
--- a/docs/api/components/request.mdx
+++ b/docs/api/components/request.mdx
@@ -1,5 +1,5 @@
# Request
-The `Request` interface represents an HTTP request with various properties such
+The `Request` class represents an HTTP request with various properties such
as URL, parameters, method, headers, body, and body type. This object is passed
to an endpoint when a request is made.
@@ -10,7 +10,7 @@ to an endpoint when a request is made.
## Properties
### url
- * Type - `string`
+ * Type - `string` *(readonly)*
* Description - The URL of the HTTP request.
@@ -18,7 +18,7 @@ to an endpoint when a request is made.
### params
- * Type - `{ path: Parameters, query: Parameters }`
+ * Type - `{ path: Parameters, query: Parameters }` *(readonly)*
* Description - An object containing `path` and `query` parameters represented
by instances of the [Parameters class](/api/components/parameters).
@@ -27,7 +27,7 @@ to an endpoint when a request is made.
### method
- * Type - `keyof typeof Method`
+ * Type - `keyof typeof Method` *(readonly)*
* Description - The HTTP method of the request, represented as one of the keys
of the [Method](/api/components/request#method-1) enum.
@@ -36,7 +36,7 @@ to an endpoint when a request is made.
### headers
- * Type - `Headers`
+ * Type - `Headers` *(readonly)*
* Description - The headers of the request, represented by an instance
of the [Headers class](/api/components/headers).
@@ -45,7 +45,7 @@ to an endpoint when a request is made.
### body
- * Type - `Body`
+ * Type - `Body` *(readonly)*
* Description - The body of the request, which can be `undefined`, a string,
or a JSON object. The body will be automatically parsed from the request.
@@ -54,7 +54,7 @@ to an endpoint when a request is made.
### bodyType
- * Type - `keyof typeof BodyType`
+ * Type - `keyof typeof BodyType` *(readonly)*
* Description: The type of the request body, represented as one of the keys of
the [BodyType](/api/components/request#bodytypes-1) enum.
diff --git a/docs/api/components/response.mdx b/docs/api/components/response.mdx
new file mode 100644
index 0000000..e308ab5
--- /dev/null
+++ b/docs/api/components/response.mdx
@@ -0,0 +1,232 @@
+# Response
+The `Response` class represents an HTTP response with various properties such
+as status, status text, headers, body, and body type. The object is returned
+from an endpoint when a request is made. The class also has static methods for
+creating creating HTTP response objects with various content types.
+
+
+
+
+
+## Properties
+
+### status
+ * Type - `number` *(readonly)*
+ * Description - The status code for the response. See
+ [HTTP response status codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status)
+ for more information.
+
+
+
+
+
+### statusText
+ * Type - `string` *(readonly)*
+ * Description - The status message for the corresponding status code. See
+ [HTTP response status codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status)
+ for more information.
+
+
+
+
+
+### headers
+ * Type - `Headers` *(readonly)*
+ * Description - The headers of the response, represented by an instance
+ of the [Headers class](/api/components/headers).
+
+
+
+
+
+### body
+ * Type - `Body` *(readonly)*
+ * Description - The body of the response, which can be `undefined`, a string,
+ or a JSON object.
+
+
+
+
+
+### bodyType
+ * Type - `keyof typeof BodyType` *(readonly)*
+ * Description - The type of the response body, represented as one of the keys of
+ the [BodyType](/api/components/response#bodytypes-1) enum.
+
+
+
+
+
+## Static Methods
+
+
+### new
+`static new(options?: Partial): Response` \
+Creates a new response with no body.
+ * `options` (optional): Partial configuration options for the response.
+ * [`headers`](/api/components/headers): The headers to include in the response.
+ * `status`: The HTTP status code of the response.
+
+
+
+
+
+### text
+`static text(text: T, options?: Partial): Response` \
+Creates a new response with a text body.
+ * `text`: The text content for the response body. Can be an object with a `toString` method or a plain string.
+ * `options` (optional): Partial configuration options for the response.
+ * [`headers`](/api/components/headers): The headers to include in the response.
+ * `status`: The HTTP status code of the response.
+
+
+
+
+
+### JSON
+`static JSON }>(JSON: T | Record, options?: Partial): Response` \
+Creates a new response with a JSON body.
+ * `JSON`: The JSON content for the response body. Can be an object with a `toJSON` method or a plain object.
+ * `options` (optional): Partial configuration options for the response.
+ * [`headers`](/api/components/headers): The headers to include in the response.
+ * `status`: The HTTP status code of the response.
+
+
+
+
+
+### HTML
+`static HTML(html: string, options?: Partial): Response` \
+Creates a new response with an HTML body.
+ * `html`: The HTML content for the response body.
+ * `options` (optional): Partial configuration options for the response.
+ * [`headers`](/api/components/headers): The headers to include in the response.
+ * `status`: The HTTP status code of the response.
+
+
+
+
+
+### redirect
+`static redirect(redirect: string): Response` \
+Creates a new redirect response with a `Location` header.
+ * `redirect`: The URL to redirect to.
+
+
+
+
+
+## Enums
+
+### BodyType
+An enum representing the possible types of the request body:
+ * `JSON` - The body is in JSON format.
+ * `Text` - The body is in plain text format.
+ * `HTML` - The body is in HTML format.
+ * `None` - There is no body associated with the request.
+
+
+
+
+
+## Examples
+
+### No Body
+```typescript
+import { Response, Headers } from "sherpa-core";
+
+export function GET() {
+ return new Response();
+}
+
+export function POST() {
+ return new Response({
+ status: 201,
+ headers: {
+ "X-Foo": "bar"
+ }
+ });
+}
+
+export function PUT() {
+ return Response.new({
+ status: 401,
+ headers: new Headers({
+ "X-Foo": "bar"
+ })
+ });
+}
+```
+
+
+
+
+
+### Text Body
+```typescript
+import { Response, Headers } from "sherpa-core";
+
+export function GET() {
+ return Response.text("Hello World!");
+}
+
+export function POST() {
+ return Response.text("Hello World!", {
+ status: 201
+ });
+}
+```
+
+
+
+
+
+### JSON Body
+```typescript
+import { Response, Headers } from "sherpa-core";
+
+export function GET() {
+ return Response.JSON({ "foo": "bar" });
+}
+
+export function POST() {
+ return Response.JSON({ "foo": "bar" }, {
+ status: 201
+ });
+}
+```
+
+
+
+
+
+### HTML Body
+```typescript
+import { Response, Headers } from "sherpa-core";
+
+export function GET() {
+ return Response.HTML("
Hello World
");
+}
+
+export function POST() {
+ return Response.HTML("
Hello World
", {
+ status: 201
+ });
+}
+```
+
+
+
+
+
+### Redirect
+Assuming this endpoint is at route `/example/foo` the user will be redirected
+to `/example/success`.
+
+```typescript
+import { Response, Headers } from "sherpa-core";
+
+export function GET() {
+ return Response.redirect("../success");
+}
+```
diff --git a/docs/assets/logos/favicon.png b/docs/assets/logos/favicon.png
new file mode 100644
index 0000000..71efe8c
Binary files /dev/null and b/docs/assets/logos/favicon.png differ
diff --git a/docs/assets/logos/logo-dark.png b/docs/assets/logos/logo-dark.png
index 4f201cc..cc6f1ad 100644
Binary files a/docs/assets/logos/logo-dark.png and b/docs/assets/logos/logo-dark.png differ
diff --git a/docs/assets/logos/logo-large-dark.png b/docs/assets/logos/logo-large-dark.png
new file mode 100644
index 0000000..4f201cc
Binary files /dev/null and b/docs/assets/logos/logo-large-dark.png differ
diff --git a/docs/assets/logos/logo-large-light.png b/docs/assets/logos/logo-large-light.png
new file mode 100644
index 0000000..a6bbf5c
Binary files /dev/null and b/docs/assets/logos/logo-large-light.png differ
diff --git a/docs/assets/logos/logo-light.png b/docs/assets/logos/logo-light.png
index a6bbf5c..ec575bf 100644
Binary files a/docs/assets/logos/logo-light.png and b/docs/assets/logos/logo-light.png differ
diff --git a/docs/build/building-a-module.mdx b/docs/build/building-a-module.mdx
new file mode 100644
index 0000000..e3c098f
--- /dev/null
+++ b/docs/build/building-a-module.mdx
@@ -0,0 +1,146 @@
+# Building a Module
+Building a SherpaJS module is straightforward and can be accomplished in just a
+few steps. Modules allow you to encapsulate and share functionality across
+multiple SherpaJS applications. Here's how to get started:
+
+
+
+
+
+## Quick Installation
+We recommend starting with the
+[SherpaJS Module Template](https://github.com/sellersindustry/SherpaJS-template-module),
+which provides a pre-configured structure and example endpoints. After
+downloading the template, install all dependencies by running:
+
+```sh
+npm install
+```
+
+You can start the development server with `npm run dev`.
+
+Now your project is all setup, explore around the project files and get
+acquainted with the [SherpaJS Project Structure](/structure) and
+[SherpaJS CLI](/api/cli).
+
+
+
+
+
+## Manual Installation
+Creating a new module is extremely easy and can be done within a couple of
+minutes. To manually create a new module start by create a new NodeJS project
+with `npm init`. Then install the SherpaJS Core package:
+
+```sh
+npm install sherpa-core
+```
+
+
+
+
+
+
+### Updating `package.json`
+Open the `package.json` file in the root directory of your project, and
+update the following properties.
+
+```json title="package.json"
+{
+ "type": "module",
+ "exports": "./sherpa.module.ts",
+ "scripts": {
+ "build": "sherpa build -b Vercel",
+ "build-local": "sherpa build -b local",
+ "start": "sherpa start",
+ "dev": "npm run build-local && npm run start"
+ }
+}
+```
+
+
+
+
+### Creating Module Config
+Create a [module config](/build/module-config) file named `sherpa.module.ts` in
+the root directory of your module. This file will default export a module
+configuration.
+
+```typescript title="sherpa.module.ts"
+import { SherpaJS, CreateModuleInterface } from "sherpa-core";
+
+export type Schema = { foo: boolean, bar: string };
+
+export default SherpaJS.New.module({
+ name: "example-module",
+ interface: CreateModuleInterface()
+});
+```
+
+[Learn more about module configs](/build/module-config).
+
+
+
+
+
+### Creating Server Config
+Create a new Typescript file for your [server configuration](/build/server-config)
+in the root directory of your project named `sherpa.server.ts`. *Technically a
+server config is not required to create a module, but it is to test the module*.
+
+```typescript title="sherpa.server.ts"
+import { SherpaJS } from "sherpa-core";
+import { Schema } from "../sherpa.module.ts";
+
+export default SherpaJS.New.server({
+ context: {
+ example: "foo"
+ }
+});
+```
+
+The context you provide the server should match the context schema for your module.
+
+
+### Creating Endpoints
+SherpaJS uses a directory-based structure for routing, similar to NextJS. Start
+by creating a `/routes` directory and place a new enpoint `index.ts` file in the
+directory. This will be processed at the root `/` of your application.
+
+```typescript title="routes/index.ts"
+import { Request, Response } from "sherpa-core";
+import { Schema } from "../sherpa.module.ts"
+
+export function GET(request:Request, context:Schema) {
+ return Response.text("Hello World!");
+}
+```
+
+Learn more about [routing](/build/rounting) and [endpoints](/build/endpoints).
+
+
+
+
+
+### Details
+While the routes of your module are available on a server when the module is
+loaded, other assets like the `public` directory are not available. Keep this
+in mind when designing your module.
+
+
+
+
+
+### Share Your Module
+Share your module with the world by deploying it as an NPM package and
+submitting a
+[new issue](https://github.com/sellersindustry/SherpaJS/issues/new/choose)
+to get it listed as a SherpaJS Community module.
+
+**Important Notes**
+ * Ensure your module is deployed as an NPM package.
+ * Include documentation on how to set it up, including required properties.
+ * Link to the SherpaJS documentation for users to understand how to set it up.
+
+Thank you for supporting SherpaJS! 🎉🥳
+
diff --git a/docs/build/endpoints.mdx b/docs/build/endpoints.mdx
index 6e5e504..993c515 100644
--- a/docs/build/endpoints.mdx
+++ b/docs/build/endpoints.mdx
@@ -1,7 +1,223 @@
# Endpoints
+Endpoints represent the individual points of access within your microservice
+architecture, allowing clients to interact with specific functionalities or
+resources. Endpoints are defined within route files (`index.ts`, `module.ts`,
+and `view.html`).
-## Functions Endpoint
-## View Endpoint
+
+
+
+## Function Endpoints
+Function endpoints are defined using a `index.ts` file. Each endpoint is
+defined within a route file using the corresponding HTTP
+method (`GET`, `POST`, `PATCH`, `PUT`, `DELETE`) function. These functions provide
+access to the incoming request and the environment, allowing developers
+to customize the endpoint's behavior based on the request data and the
+server environment.
+
+
+
+
+
+### Defining Function Endpoints
+Endpoint functions receive two parameters:
+1. [`request`](/api/components/request) - Contains the HTTP request information.
+2. `context` - Additional properties provided to configure the endpoint. The
+ context is either provided by the server configuration
+ (if it's the root route) or the module loader (if it's a module route).
+
+A response should be returned by the function, using the
+[SherpaJS Response utility](/api/components/response).
+
+
+#### Supported HTTP methods
+ * [GET](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET)
+ * [POST](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST)
+ * [PATCH](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH)
+ * [PUT](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT)
+ * [DELETE](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/DELETE)
+
+
+
+
+
+### Example Function Endpoint
+```typescript title="/routes/index.ts"
+import { Request, Context, Response } from "sherpa-core";
+
+// Example GET endpoint
+export function GET(request: Request, context: Context) {
+ return Response.text("Hello World");
+}
+
+// Example POST endpoint
+export function POST(request: Request, context: Context) {
+ return Response.text("Example POST", { status: 201 });
+}
+
+// Example DELETE endpoint
+export function DELETE(request: Request, context: Context) {
+ return Response.JSON({ message: "DELETE request received" }, { status: 204 });
+}
+```
+
+
+
+
+
+## View Endpoints
+Endpoints can also render views, including HTML files. To render a view,
+simply place the view file (named `view.html`) in the endpoint directory.
+
+
+
+
+
+### Defining Function Endpoints
+Simply create a view endpoint by creating a `view.html` in an endpoint
+directory. You can use view endpoints along with function endpoints, but there
+are a couple of additional rules:
+
+1. When rendering a view, you cannot also have a GET method in your function endpoint.
+2. Function endpoints are not required when a view is provided.
+3. View endpoints do not support module endpoints.
+
+
+
+
+
+### Example View Endpoint
+```html title="/routes/about/view.html"
+
+
+
+
+
+ Welcome to SherpaJS
+
+
+
Welcome to SherpaJS
+
This is an example HTML view rendered by SherpaJS.
+
Use this template to create your own custom views and endpoints.
+
+
+```
+
+
+
+
+
+## Module Endpoints
+SherpaJS allows endpoint modules to be loaded, which are sets of endpoints built
+by the [community](/#community-modules) or [yourself](/build/building-a-module).
+By integrating these prebuilt modules, which can range from authentication to
+analytics, you can easily extend your server's functionality without
+duplicating code. These modules are loaded with a `module.ts` endpoint file.
+
+
+
+
+
+### Defining Module Endpoints
+Modules are loaded in the same endpoint file (`module.ts`) as a regular
+endpoint. Instead of exporting HTTP methods, you export a loaded module.
+Simply import the module and use the load method, while providing the context.
+
+
+ Additional segment routes or endpoints are not allowed where module
+ endpoints are defined.
+
+
+
+
+
+
+### Example Module Loading
+The module entry point can either be a relative directory
+(in which case you must specify the `sherpa.module.ts` file)...
+
+```typescript title="/routes/example/module.ts"
+import ExampleModule from "../../modules/sherpa.module";
+
+export default ExampleModule.load({
+ test: "Hello World"
+});
+```
+
+or an NPM package name...
+
+```typescript title="/routes/flags/module.ts"
+// module.ts
+import StaticFlags from "sherpajs-static-flags";
+
+export default StaticFlags.load({
+ test: "Hello World"
+});
+```
+
+
+ Module interfaces or context can be access from other places within your
+ code, using [interface calling](/build/module-config#module-interface-call-example).
+
+
+
+
+
+
+## Example Routing
+
+### Basic Route Structure
+```plaintext
+/routes
+│
+├── /users
+│ └── index.ts // Function endpoint for "/users"
+│
+├── /posts
+│ └── index.ts // Function endpoint for "/posts"
+│
+├── /auth
+│ └── index.ts // Function endpoint for "/auth"
+```
+
+
+
+
+
+### Nested and Dynamic Routes
+```plaintext
+/routes
+│
+├── /example
+│ ├── index.ts // Function endpoint for "/example"
+│ ├── /subroute
+│ │ └── index.ts // Function endpoint for "/example/subroute"
+│
+├── /[id]
+│ └── index.ts // Function endpoint for "/[id]" access "[id]" with request.params.path.get("id")
+│
+├── /products
+│ ├── index.ts // Function endpoint for "/products"
+│ ├── /[productID]
+│ │ └── index.ts // Function endpoint for "/products/[productID]" access "[productID]" with request.params.path.get("productID")
+│ └── /category
+│ └── index.ts // Function endpoint for "/products/category"
+```
+
+
+
+
+
+### View and Module Endpoints
+```plaintext
+/routes
+│
+├── /home
+│ └── view.html // View endpoint for "/home"
+│
+├── /dashboard
+│ └── module.ts // Module endpoint for "/dashboard"
+```
-## Module Endpoint
\ No newline at end of file
diff --git a/docs/build/miscellaneous.mdx b/docs/build/miscellaneous.mdx
new file mode 100644
index 0000000..b5a8f77
--- /dev/null
+++ b/docs/build/miscellaneous.mdx
@@ -0,0 +1,60 @@
+# Miscellaneous
+
+
+## Environment Variables
+Environment variables are a key part of configuring your SherpaJS application.
+They allow you to set various configuration options and secrets without
+hardcoding them into your application's codebase.
+
+
+
+
+
+### Loading Environment Variables
+SherpaJS uses the `.env` file to load environment variables. This file should
+be placed at the root of your project. When the system is compiled, the
+variables defined in this file are automatically loaded into your server's
+environment.
+
+Any environment variables provided by hosting services (such as Vercel or AWS)
+are automatically included in your build.
+
+Environment varibles can also be added during build with the
+[build command](/api/cli#build-command).
+
+
+
+
+
+### Automatic Parsing
+SherpaJS automatically parses environment variables to their appropriate types:
+- Strings remain as strings
+- Booleans are converted to `true` or `false`
+- Numbers are converted to numeric values
+
+
+
+
+
+### Example .env File
+Here is an example of a `.env` file:
+
+```shell title=".env"
+PORT=3000 # number
+DATABASE_URL=mongodb://localhost:27017/mydatabase # string
+JWT_SECRET=myverysecretkey # string
+ENABLE_FEATURE_X=true # boolean
+MAX_CONNECTIONS=100 # number
+```
+
+
+
+
+### Best Practices
+- **Security**: Never commit your `.env` file to version control. Add it
+ to your `.gitignore` file.
+- **Defaults**: Provide sensible default values for environment variables
+ in your code.
+- **Validation**: Validate the presence and format of critical environment
+ variables at the start of your application to avoid runtime errors.
+
diff --git a/docs/build/module-config.mdx b/docs/build/module-config.mdx
index a171803..9e3d862 100644
--- a/docs/build/module-config.mdx
+++ b/docs/build/module-config.mdx
@@ -1 +1,187 @@
-# Module Config
\ No newline at end of file
+# Module Configuration
+Sherpa modules are configured using a `sherpa.module.ts` file, where you define
+the structure and behavior of your module. This configuration file is located
+at the root of your project and serves as the entry point for your Sherpa module.
+
+
+## Config File
+The configuration file must be located at `sherpa.module.ts` and have a
+default export of the config using the `SherpaJS.New.module` function as
+follows. You can export a class using `CreateModuleInterface` that acts as a
+wrapper for validating the context when the module is loaded.
+
+
+
+
+
+### Basic Configuration
+This basic configuration sets up a module with a simple interface
+definition. The context schema is defined inline using the
+`CreateModuleInterface` function.
+
+```typescript title="sherpa.module.ts"
+import { SherpaJS, CreateModuleInterface } from "sherpa-core";
+
+export default SherpaJS.New.module({
+ name: "example-module",
+ interface: CreateModuleInterface<{ foo: boolean, bar: string }>()
+});
+```
+
+
+
+
+
+### Class-Based Configuration
+Alternatively, you can export any interface class with a constructor that
+takes the context as a parameter and sets `this.context` within your class.
+You can attach additional methods to interact with your module.
+
+These interfaces can be called by other functions and endpoints inside your
+codebase, see the
+[calling module interfaces example](/build/module-config#module-interface-call-example).
+
+```typescript title="sherpa.module.ts"
+import { SherpaJS, ModuleInterface } from "sherpa-core";
+
+export default SherpaJS.New.module({
+ name: "example-module",
+ interface: class Example implements ModuleInterface {
+ context: { foo: number, bar: string };
+ constructor(context: { foo: number, bar: string }) {
+ this.context = context;
+ }
+ }
+});
+```
+
+
+ You can also export any additional attributes from this file as needed. The
+ module config file, `sherpa.module.ts` should be the main script defined
+ in your `package.json`.
+
+
+
+
+
+
+## Config Structure
+
+### name
+The name of the module.
+
+
+
+
+
+### interface
+A class that has a constructor with `context:[TYPE]` parameter and a
+property `context: [TYPE]`. You can also use `CreateModuleInterface` to
+generate this class.
+
+
+
+
+
+## Module Config Type
+The module configuration type is structured as:
+
+```typescript
+{
+ name:string;
+ interface:T;
+}
+```
+
+where `T` is a class that implements implements `ModuleInterface`. Thus, it
+has a `context` and a `constructor` that takes `context` as a parameter.
+
+```typescript
+{
+ context:Schema;
+ constructor(context:Schema) { this.context = context; }
+}
+```
+
+
+
+
+
+## Example Config
+
+### Basic Example
+A basic configuration using the `CreateModuleInterface` function.
+
+```typescript title="example-module/sherpa.module.ts"
+import { SherpaJS, CreateModuleInterface } from "sherpa-core";
+
+export default SherpaJS.New.module({
+ name: "example-module",
+ interface: CreateModuleInterface<{ foo: boolean, bar: string }>()
+});
+```
+
+Loading the module from a server endpoints, [learn more](/build/endpoints).
+```typescript title="route/module.ts"
+import ExampleModule from "../example-module/sherpa.module.ts";
+
+export default ExampleModule.load({
+ foo: true,
+ bar: "hello"
+})
+```
+
+
+
+
+
+
+### Module Interface Call Example
+
+A basic configuration using the `CreateModuleInterface` function.
+
+```typescript title="example-module/sherpa.module.ts"
+import { SherpaJS, CreateModuleInterface } from "sherpa-core";
+
+export type Schema = { foo: number, bar: string };
+
+export default SherpaJS.New.module({
+ name: "example-module",
+ interface: class Example implements ModuleInterface {
+
+ context:Schema;
+
+ constructor(context:Schema) {
+ this.context = context;
+ }
+
+ getFoo():number {
+ return this.context.foo;
+ }
+
+ }
+});
+```
+
+Loading the a module from a server endpoints,
+[learn more](/build/endpoints).
+```typescript title="route/example/module.ts"
+import ExampleModule from "../../example-module/sherpa.module.ts";
+
+export default ExampleModule.load({
+ foo: 3,
+ bar: "hello"
+})
+```
+
+Calling the loaded module instance from another endpoint...
+```typescript title="route/index.ts"
+import { Request, Response } from "sherpa-core";
+import example from "./example/module.ts";
+
+export function GET() {
+ return Response.text(example.getFoo()); // returns 3
+}
+
+```
+
diff --git a/docs/build/routes.mdx b/docs/build/routes.mdx
deleted file mode 100644
index bc51cc3..0000000
--- a/docs/build/routes.mdx
+++ /dev/null
@@ -1,5 +0,0 @@
-# Routes
-
-## Regular Route
-
-## Dynamic Route
\ No newline at end of file
diff --git a/docs/build/routing.mdx b/docs/build/routing.mdx
new file mode 100644
index 0000000..b15a6de
--- /dev/null
+++ b/docs/build/routing.mdx
@@ -0,0 +1,167 @@
+# Routing
+SherpaJS provides a flexible and intuitive way to define endpoints and handle
+incoming requests within your microservice architecture. Drawing inspiration
+by Next.js, SherpaJS routes follow a directory-based structure located in
+the `/routes` directory of your module.
+
+
+
+
+
+## Terminology
+
+### Route Component Tree
+ * **Routes**: A hierarchical structure for all the segments and endpoints
+ of the server.
+ * **Subroutes**: A subsection of the route structure.
+ * **Root**: The first level of segments and endpoints in a route or subroute.
+
+
+
+
+
+### URL Anatomy
+ * **Segment**: The directory name part of the URL path delimited by slashes.
+ * **URL Path**: The part of the URL that comes after the domain, composed of segments.
+ * **Endpoint**: The final destination in the route structure where the request
+ is handled, typically defined in `index.ts` files.
+
+
+
+
+
+## Structure of Routes
+In the `/routes` directory, you can create directories to organize your
+routes. Each endpoint within a route is represented by a file typically named
+`index.ts`, [learn more about other types of endpoints](/build/endpoints).
+
+
+
+
+
+### Example Route Structure
+```plaintext
+/routes
+│
+├── /users
+│ └── index.ts // Endpoint logic for "/users"
+│
+│
+├── /example
+│ ├── index.ts // Endpoint logic for "/example"
+│ ├── /subroute
+│ │ └── index.ts // Endpoint logic for "/example/subroute"
+│
+├── /[id]
+│ └── index.ts // Endpoint logic for "/[id]" access "[id]" with request.params.path.get("id")
+│
+├── /products
+│ ├── index.ts // Endpoint logic for "/products"
+│ ├── /[productID]
+│ │ └── index.ts // Endpoint logic for "/products/[productID]" access "[productID]" with request.params.path.get("productID")
+│ └── /category
+│ └── index.ts // Endpoint logic for "/products/category"
+```
+
+
+
+
+
+## Defining Segment routes
+Routes in SherpaJS are created using a file-system based router where folders
+define segment routes, and files inside these folders define the endpoint logic.
+
+
+
+
+
+### Basic Segment Route
+In SherpaJS, the basic segment routes are straightforward. Each folder
+represents a route segment, and the `index.ts` file within the folder
+contains the endpoint logic, [or other types of endpoints](/build/endpoints).
+
+```typescript title="routes/index.ts"
+import { Request, Response } from "sherpa-core";
+
+export function GET(request:Request) {
+ return Response.text("Hello World!");
+}
+```
+
+
+
+
+
+### Nested Segment Route
+To create a nested segment route, nest folders inside each other. For example, to
+create a `/dashboard/settings` route, you would nest two folders like so:
+
+```plaintext
+/routes
+│
+├── /dashboard
+│ ├── index.ts // Endpoint logic for "/dashboard"
+│ └── /settings
+│ └── index.ts // Endpoint logic for "/dashboard/settings"
+```
+
+```typescript title="routes/dashboard/settings/index.ts"
+import { Request, Response } from "sherpa-core";
+
+export function GET(request:Request) {
+ return Response.text("Hello World!");
+}
+```
+
+
+
+
+
+### Dynamic Segment Route
+To define a dynamic segment route, name a directory using square brackets, such
+as `[id]`. Within a dynamic segment route directory, you can access the parameter
+value from the request object in your endpoint logic. For example, if you have
+a dynamic segement route named `[id]`, you can access the parameter
+using `request.params.path.get("id")`.
+
+```plaintext
+/routes
+│
+├── /products
+│ └── /[id]
+│ └── index.ts // Endpoint logic for "/products/[id]"
+```
+
+```typescript title="routes/products/[id]/index.ts"
+import { Request, Response } from "sherpa-core";
+
+export function GET(request:Request) {
+ return Response.new(request.params.path.get("id"));
+}
+```
+
+
+
+
+
+## Restrictions
+The SherpaJS routing system has some restrictions when it comes to defining
+routes, these restrictions help to keep routing simple, consistent, and ensure
+best practices. The SherpaJS compiler will prevent you from compiling if you
+violate any of these restrictions.
+ * Multiple [dynamic segement routes](/build/routing#dynamic-segment-route)
+ are not allowed in a single segement route.
+ * Additional segment routes or endpoints are not allowed as the segment where
+ a [Module Endpoint](/build/endpoints#module-endpoints) is loaded.
+ * [Function Endpoints](/build/endpoints#function-endpoints) cannot have a
+ GET method when paired with a [View Endpoint](/build/endpoints#view-endpoints).
+
+
+
+
+
+## Next Steps
+Now that you understand the fundamentals of routing in SherpaJS, you can start
+creating endpoints for your application. \
+
+[Learn more about Endpoints](/build/endpoints)
diff --git a/docs/build/server-config.mdx b/docs/build/server-config.mdx
index dbfed2e..b63da57 100644
--- a/docs/build/server-config.mdx
+++ b/docs/build/server-config.mdx
@@ -1 +1,121 @@
-# Server Config
\ No newline at end of file
+# Server Configuration
+Sherpa servers are configured using a `sherpa.server.ts` file, where you define
+the structure and behavior of your server. This configuration file is located
+at the root of your project and serves as the entry point for your Sherpa server.
+
+
+
+
+
+## Config File
+The configuration file must be located at `sherpa.server.ts` and have a
+default export of the config using the `SherpaJS.New.server` function as follows:
+
+```typescript title="sherpa.server.ts"
+import SherpaJS from "sherpa-core";
+
+export default SherpaJS.New.server({
+ content: {
+ serverSecret: process.env.SERVER_SECRET,
+ allowThingy: true
+ }
+});
+```
+
+
+ When you load modules they have there own context, that is provided
+ by the module loader, and do not have access to your server context.
+
+
+
+
+
+
+
+## Config Structure
+
+### Context
+A property that allows you to define a context object. Contexts are
+provided to endpoints and can contain any additional data or settings needed
+for request processing.
+
+
+
+
+
+## Server Config Type
+The server configuration type is structured as:
+
+```typescript
+{
+ context: T;
+}
+```
+
+where `T` can be any type, allowing for flexible and customizable
+server configurations.
+
+
+
+
+
+## Examples
+
+### Basic Example
+A basic configuration where the context contains simple settings:
+
+```typescript title="sherpa.server.ts"
+import { SherpaJS } from "sherpa-core";
+
+export default SherpaJS.New.server({
+ context: {
+ serverSecret: "foo",
+ allowThingy: true
+ }
+});
+```
+
+The context object is then available within endpoints.
+```typescript title="routes/index.ts"
+import { Request, Response } from "sherpa-core";
+
+
+export function GET(request:Request, context:unknown) {
+ consoe.log(context.serverSecret); // returns "foo"
+ consoe.log(context.allowThingy); // returns true
+ return Response.new();
+}
+```
+
+
+
+
+
+### Typed Example
+A more detailed configuration using a typed context for additional type
+safety and clarity:
+
+```typescript title="sherpa.server.ts"
+import { SherpaJS } from "sherpa-core";
+
+type ConfigExample = { serverSecret: string; allowThingy: boolean };
+
+export default SherpaJS.New.server({
+ context: {
+ serverSecret: "foo",
+ allowThingy: true
+ }
+});
+```
+
+The context object is then available within endpoints.
+```typescript title="routes/index.ts"
+import { Request, Response } from "sherpa-core";
+
+
+export function GET(request:Request, context:ConfigExample) {
+ consoe.log(context.serverSecret); // returns "foo"
+ consoe.log(context.allowThingy); // returns true
+ return Response.new();
+}
+```
diff --git a/docs/build/static-assets.mdx b/docs/build/static-assets.mdx
index cb41e9e..ce69756 100644
--- a/docs/build/static-assets.mdx
+++ b/docs/build/static-assets.mdx
@@ -1 +1,96 @@
-# Static Assets
\ No newline at end of file
+# Static Assets
+SherpaJS servers can serve static assets such as images, CSS, JavaScript
+files, and other resources that do not change frequently. These assets are
+placed in a dedicated folder within your project and are served directly to
+clients when requested.
+
+This static asset directory is optional. Static assets are not transferred from
+modules.
+
+
+
+
+
+## Defining Static Assets Directory
+The default directory for static assets in a SherpaJS project is the `public`
+folder. Any files placed in this folder are accessible via a URL path that
+mirrors the directory structure within `public`.
+
+
+
+
+
+## Serving Static Assets
+To serve static assets, simply place the files within the `public`
+directory of your project. For example:
+
+```plaintext
+/your-project
+│
+├── /public
+│ ├── /images
+│ │ └── logo.png
+│ ├── /css
+│ │ └── styles.css
+│ └── /js
+│ └── script.js
+│
+├── /routes
+│ └── view.html
+└── sherpa.server.ts
+```
+
+In this structure:
+ * `logo.png` will be accessible at `/images/logo.png`
+ * `styles.css` will be accessible at `/css/styles.css`
+ * `script.js` will be accessible at `/js/script.js`
+ * `view.html` will be accessible at `/`
+
+
+
+
+
+## Examples
+
+
+### View Endpoints Example
+If you want to reference these static assets in your view endpoint or other
+files, use the appropriate URL path. For example, in an HTML file:
+
+```html title="/routes/view.html"
+
+
+
+
+
+ My SherpaJS App
+
+
+
+
+
+
+
+
Welcome to My SherpaJS App
+
This is a simple example of serving static assets.