No description
  • TypeScript 90%
  • JavaScript 5.4%
  • Dockerfile 4.6%
Find a file
TR 5fd6526608
All checks were successful
Build and Publish / publish (push) Successful in 9s
Merge pull request 'chore: updated vode-app packages' (#18) from temir/vode-app-create-hono-server:dev into main
Reviewed-on: #18
2026-07-05 16:45:51 +02:00
.forgejo/workflows chore: udpated template and template files from template@0.6.0 and ts-lib@0.15.0 templates 2026-07-05 14:01:32 +02:00
scripts chore: updated from ts-lib@0.14.0 template 2026-07-03 12:52:02 +02:00
src chore: updated from ts-lib@0.13.1 template 2026-06-01 15:16:07 +02:00
template chore: updated vode-app packages 2026-07-05 16:45:28 +02:00
tests chore: updated from template@0.4.4 template 2026-06-01 13:32:56 +02:00
.gitignore version 0.4.4 2026-05-19 22:08:47 +02:00
.npmrc feat: build and publish workflow 2026-07-03 12:55:11 +02:00
CHANGELOG.md resetted package under "@vode-app" scope 2026-05-21 14:14:06 +02:00
LICENSE updated generated package for use as a package template 2026-03-06 14:22:38 +01:00
package-lock.json chore: updated vode-app packages 2026-07-05 16:45:28 +02:00
package.json chore: updated vode-app packages 2026-07-05 16:45:28 +02:00
README.md chore: udpated template and template files from template@0.6.0 and ts-lib@0.15.0 templates 2026-07-05 14:01:32 +02:00
tsconfig.json chore: updated from template@0.4.1 template 2026-05-30 14:47:47 +02:00

Introduction

This template scaffolds a ...

Table of Contents

  1. Quick Start
  2. Documentation
    1. createAppHost()
    2. createSpaHost()
  3. DevOps
    1. Change Management
    2. Registry
    3. CI/CD Workflows

Quick Start

# print the latest version
npm info "@vode-app/create-hono-server" version

# create/update a package from the template in the current directory
npm create --no-install --no-git "@vode-app/hono-server@latest" .

# set metadata in package.json

npm update

Documentation

The following sections explain the configurations and conventions baked into the generated package. Useful when adapting it to fit specific needs.

<DOCUMENTATION>

In the src/main.ts file, an App Host (appHost) is first created, then an App Host Server (appHostServer) is started with the created App Host.

An App Host is just a Hono<E> instance. Do with it what you will.

Generated example in src/main.ts:

import {
    // ... ,
    buildinfoUrl as serverBuildinfoUrl,
    buildinfoTemplateUrl as serverTemplateBuildinfoUrl,
} from './package-urls.js';
// ...
import {
    // ... ,
    createBuildinfoEndpoint,
    createHealthEndpoint,
    createOpenapiEndpoints,
    // ...
} from '@vode-app/common-server-side/hono';

// ...

let appHost: Hono<AppHostEnv>;
console.log('[main] Creating app host...');
try {

    appHost = basePathTrimmed
        ? new Hono<AppHostEnv>().basePath(`/${basePathTrimmed}/`)
        : new Hono<AppHostEnv>()
        ;

    appHost.route('/', createHealthEndpoint({
        path: '/health',
        description: 'Server health check endpoint.',
    }));

    appHost.route('/', createBuildinfoEndpoint({
        path: '/buildinfo',
        description: 'Server buildinfo endpoint.',
        buildinfoUrl: serverBuildinfoUrl,
    }));

    appHost.route('/', createBuildinfoEndpoint({
        path: '/buildinfo-template',
        description: 'Server template buildinfo endpoint.',
        buildinfoUrl: serverTemplateBuildinfoUrl,
    }));

    const version = readFileSync(serverBuildinfoUrl, 'utf-8');
    appHost.route('/', createOpenapiEndpoints(appHost, {
        title: 'Example Vode App Server',
        version: version,
        description: 'OpenAPI documentation for the Example Vode App Server.',
        path: 'openapi',
        uiPath: 'scalar',
    }));

} catch (error) {
    console.error('[main] Failed to create app host:', error);
    process.exit(1);
}
console.log('[main] App host created.');

// ...

createAppHost()

A convenience function for creating an App Host is provided by the @vode-app/common-server-side/hono package. It abstracts away some of the common setup and configuration, while still allowing for flexibility and customization.

Example usage in src/main.ts:

import {
    // ... ,
    createAppHost,
    type CreateAppHostOptions,
    createBuildinfoEndpoint,
    createHealthEndpoint,
    createLoggingMiddleware,
    createRequestLoggerMiddleware,
    // ...
} from '@vode-app/common-server-side/hono';
// ...
import { requestId } from 'hono/request-id';
import { compress } from 'hono/compress';
import { secureHeaders } from 'hono/secure-headers';

// ...

let appHost: Hono<AppHostEnv>;
console.log('[main] Creating app host...');
try {

    const createAppHostOptions: CreateAppHostOptions<AppHostEnv> = {
        middleware: [

            createLoggingMiddleware({
                logLevel: env.LOG_LEVEL,
                logLevelPerScope: logLevelPerScope
                    ? logLevelPerScope
                    : undefined
                ,
            }),

            // DEVEL: Add dependency injection middleware here

            requestId(),
            createRequestLoggerMiddleware<AppHostEnv>(),
            compress(),
            secureHeaders(),

            // DEVEL: Add middleware here

        ],
        endpointGroups: [

            createHealthEndpoint({
                path: '/health',
                description: 'Server health check endpoint.',
            }),
            createBuildinfoEndpoint({
                path: '/buildinfo',
                description: 'Server buildinfo endpoint.',
                buildinfoUrl: serverBuildinfoUrl,
            }),
            createBuildinfoEndpoint({
                path: '/buildinfo-template',
                description: 'Server template buildinfo endpoint.',
                buildinfoUrl: serverTemplateBuildinfoUrl,
            }),

            // DEVEL: Add endpoint groups here

        ],
        exposeOpenApi: env.EXPOSE_OPENAPI,
    };
    if (basePathTrimmed) createAppHostOptions.basePath = basePathTrimmed;
    if (createAppHostOptions.exposeOpenApi) {
        const version = readFileSync(serverBuildinfoUrl, 'utf-8');
        createAppHostOptions.openApi = {
            title: 'Example Vode App Server',
            version: version,
            description: 'OpenAPI documentation for the Example Vode App Server.',
            path: 'openapi',
            uiPath: 'scalar',
        };
    }

    appHost = createAppHost<AppHostEnv>(createAppHostOptions);

} catch (error) {
    console.error('[main] Failed to create app host:', error);
    process.exit(1);
}
console.log('[main] App host created.');

// ... 

createSpaHost()

A convenience function for creating an SPA Host is provided by the @vode-app/common-server-side/hono package. It abstracts away some of the common setup and configuration for hosting a Single Page Application (SPA), while still allowing for flexibility and customization. Under the hood, it creates an App Host and configures it to serve the SPA.

Example usage in src/main.ts:

import {
    // ... ,
    createSpaHost,
    type CreateSpaHostOptions,
    type CreateSpaOptions,
    // ...
} from '@vode-app/common-server-side/hono';
// ...
import { fileURLToPath } from 'node:url';
// ...
import {
    buildinfoUrl as clientBuildinfoUrl,
    buildinfoTemplateUrl as clientTemplateBuildinfoUrl,
    indexHtmlUrl as clientIndexHtmlUrl,
    distUrl as clientDistUrl,
} from '@vode-app/example-client/package-urls';

// ...

let appHost: Hono<AppHostEnv>;
console.log('[main] Creating app host...');
try {

    const createSpaOptions: CreateSpaOptions = {
        path: 'example/',
        buildinfoUrl: clientBuildinfoUrl,
        buildinfoTemplateUrl: clientTemplateBuildinfoUrl,
        indexHtmlUrl: clientIndexHtmlUrl,
        assetsRoot: fileURLToPath(clientDistUrl),
    };
    if (basePathTrimmed) createSpaOptions.basePath = `/${basePathTrimmed}/`;

    const createSpaHostOptions: CreateSpaHostOptions<AppHostEnv> = {
        logLevel: {
            default: env.LOG_LEVEL,
            perScope: logLevelPerScope,
        },
        dependencyInjectionMiddleware: [

            // DEVEL: add dependency injection middleware here

        ],
        middleware: [

            // DEVEL: add middleware here

        ],
        serverBuildinfoUrl: serverBuildinfoUrl,
        serverTemplateBuildinfoUrl: serverTemplateBuildinfoUrl,
        spa: createSpaOptions,
        endpointGroups: [

            // DEVEL: add endpoint groups here

        ],
        exposeOpenApi: env.EXPOSE_OPENAPI,
    };
    if (basePathTrimmed) createSpaHostOptions.basePath = basePathTrimmed;
    if (createSpaHostOptions.exposeOpenApi) {
        createSpaHostOptions.openApi = {
            title: 'Web API',
            version: '1.0.0',
            description: 'API documentation for the server.',
            path: 'openapi',
            uiPath: 'scalar',
        };
    }

    appHost = createSpaHost<AppHostEnv>(createSpaHostOptions);

} catch (error) {
    console.error('[main] Failed to create app host:', error);
    process.exit(1);
}
console.log('[main] App host created.');

// ...

DevOps

npm install
npm update

npm run clean
npm run build
npm run tests

npx tsx dist/cli.bundle.js -- example/
git fetch upstream
git fetch origin
git fetch . upstream/main:origin/main
git fetch . origin/main:main
git push origin main
git merge --ff-only main
git push

Change Management

  1. Create a new branch for the change.
  2. Make the changes and commit.
  3. Bump the version in package.json.
  4. Add an entry for the new version in CHANGELOG.md.
  5. Pull-request the branch.
  6. Ensure package artifacts are current.
  7. Publish.

Registry

.npmrc:

@vode-app:registry=https://git.chimps.quest/api/packages/vode-app/npm/
//git.chimps.quest/api/packages/vode-app/npm/:_authToken=${VODE_APP_REGISTRY_AUTH_TOKEN}

or bunfig.toml:

[install.scopes]
"vode-app" = { url = "https://git.chimps.quest/api/packages/vode-app/npm/", token = "$VODE_APP_REGISTRY_AUTH_TOKEN" }
# git.chimps.quest/api/packages/vode-app/npm/
export VODE_APP_REGISTRY_AUTH_TOKEN=<AUTH_TOKEN>
# or
$env:VODE_APP_REGISTRY_AUTH_TOKEN = "<AUTH_TOKEN>"
npm publish

CI/CD Workflows

Build and Publish

⚠️ .npmrc configuring the package registry and its authentication token is required for the workflow to work.

Parameter Type Description
RUNNER_LABEL Variable The label of the runner to use for the workflow.
ACCESS_TOKEN Secret The authentication token for the package registry.

.github/workflows/build-publish.yml:

name: Build and Publish

on:
  push:
    branches:
      - main

jobs:
  publish:
    runs-on: ${{ vars.RUNNER_LABEL }}
    steps:
      - uses: actions/checkout@v4

      - name: Install
        env:
          VODE_APP_REGISTRY_AUTH_TOKEN: ${{ secrets.ACCESS_TOKEN }}
        run: npm ci

      - name: Build
        run: npm run build

      - name: Test
        run: npm run tests

      - name: Publish
        env:
          VODE_APP_REGISTRY_AUTH_TOKEN: ${{ secrets.ACCESS_TOKEN }}
        run: |
          PKG_NAME=$(node -p "require('./package.json').name")
          PKG_VERSION=$(node -p "require('./package.json').version")
          NPM_TAG="latest"
          if echo "$PKG_VERSION" | grep -q -- '-'; then
            NPM_TAG="next"
          fi
          if npm view "$PKG_NAME@$PKG_VERSION" version >/dev/null 2>&1; then
            echo "$PKG_NAME@$PKG_VERSION already published, skipping."
          else
            npm publish --tag "$NPM_TAG"
          fi