- Make generateDocs work with Vanilla vs TypeScript and Development vs Production
- Add support for body
- Get and display responses
- Clean up login button state
- Add entities
- Add minimize all button for modules
- Describe syntax and structure requirements/limitations in README
- Expand login to more than just IDIR
- Check for protectedRoute on router routes
- Check for describe in zod schema to add to params
- Install package by following the steps at Installing the Package.
- Set up the package by following the steps at Basic Setup Guide.
- Use with @bcgov/citz-imb-kc-express.
- Allows automatic generation of api documentation and integration with Keycloak SSO protected endpoints.
- General Information
- Installing the Package - Start Here!
- Basic Setup Guide - Setting up after installing.
- Environment Variables - Required variables for initialization.
- Directory Structure - How the repo is designed.
- Scripts - Scripts for running and working on the package.
- Module Exports - Functions available from the module.
- TypeScript Types - Available TypeScript types.
- Applications using this Solution - See an example of how to use.
- For running on a NodeJS:20 Express API.
- Works with Vanilla JavaScript or Typescript 5.
- Use with @bcgov/citz-imb-kc-express.
- Allows automatic generation of api documentation and integration with Keycloak SSO protected endpoints.
Example:
- Add the following line to your
package.json:
{
"dependencies": {
"@bcgov/citz-imb-kc-express-api-docs": "https://github.com/bcgov/citz-imb-kc-express-api-docs/releases/download/v<VERSION>/bcgov-citz-imb-kc-express-api-docs-<VERSION>.tgz",
// The rest of your dependencies...
},
}- Replace
<VERSION>with the version you wish to use. Reference releases for version numbers.
- Run
npm installto add the package.
Requirements:
- Endpoints must be organized by module (by default this means a
src/modulesdirectory). - Modules must be defined as a base route in express file such as
healthmodule asapp.use('/health', router); - Each module must have a single
router.tsfile (controllers can be in separate files). - Use of module type
importsinstead of commonjs typerequire. - Schemas used in getParams, getQuery, and getBody must be imported to controller files from another file.
- Controller functions must have a description in the form of a single or multi-line comment above them. For multi-line comments, the first line of text will be taken as the description.
- Add import
const { apiDocs } = require('@bcgov/citz-imb-kc-express-api-docs');orimport { apiDocs } from '@bcgov/citz-imb-kc-express-api-docs';to the top of the file that defines the express app. AddapiDocs(app, API_DOCS_CONFIG);below the definition of the express app, whereappis defined byexpress().
Note the default config options:
// Automatically set, unless changed
const DefaultAPIDocsConfig = {
title: "API Documentation",
expressFilePath: "src/express.ts",
modulesBasePath: "src/modules",
modules: {},
};Example:
import express from 'express';
import { apiDocs } from '@bcgov/citz-imb-kc-express-api-docs';
const API_DOCS_CONFIG = {
modules: {
health: {
description: 'Check application health.',
},
},
customSchemas: { // This is an optional property.
'zodProperty.nonEmptyString': { // Example of custom zod schema object.
required: true,
type: 'string',
},
},
customControllers: { // This is an optional property.
'dataController.getAllItems': {
description: 'Returns all items.',
// optional add query property (see TypeScript types).
},
},
customResponseStatuses: { // This is an optional property.
'statusCode.OK': 200,
'statusCode.CREATED': 201,
'statusCode.ACCEPTED': 202,
'statusCode.NO_CONTENT': 204,
'statusCode.NOT_MODIFIED': 304,
'statusCode.BAD_REQUEST': 400,
'statusCode.UNAUTHORIZED': 401,
'statusCode.FORBIDDEN': 403,
'statusCode.NOT_FOUND': 404,
'statusCode.IM_A_TEAPOT': 418,
'statusCode.INTERNAL_SERVER_ERROR': 500,
'statusCode.NOT_IMPLEMENTED': 501,
'statusCode.SERVICE_UNAVAIBLABLE': 503,
},
defaultResponses: [500], // This is an optional property.
};
// Define Express App
const app = express();
// Initialize api docs
apiDocs(app, API_DOCS_CONFIG);- Add the required environment variables from the Environment Variables section below.
# Ensure the following environment variables are defined on the container.
BACKEND_URL= # URL of the backend application.
SSO_CLIENT_ID= # Keycloak client_id
SSO_CLIENT_SECRET= # Keycloak client_secret
SSO_AUTH_SERVER_URL= # Keycloak auth URL, see example below.
# https://dev.loginproxy.gov.bc.ca/auth/realms/standard/protocol/openid-connect
DEBUG= # (optional) Set to 'true' to get useful debug statements in api console.
VERBOSE_DEBUG= # (optional) Set to 'true' to get extra details from DEBUG..
├── .github/
| ├── config/
| | └── dep-report.json5 # Configure options for NPM Dep Report.
| ├── helpers/
| | ├── github-api/ # Functions to access the GitHub API.
| | ├── create-npm-dep-report-issues.js # Creates GitHub Issues for Npm Dep Reports.
| | ├── create-npm-dep-report.js # Creates text bodies for Npm Dep Reports.
| | ├── parse-json5-config.js # Parses json5 files for GitHub actions output.
| | └── parse-npm-deps.js # Parses package.json files for changes to package versions.
| ├── workflows/
| | ├── npm-dep-report.yaml # Reports on new package versions.
| | └── releases.yaml # Creates a new GitHub Release.
├── .husky/
| └── post-commit # Script that runs after a git commit.
├── scripts/
| ├── bump-version.mjs # Bumps version in package.json file.
| ├── post-commit-version-change.mjs # Bumps version when post-commit is run.
| ├── remove-dts-files.mjs # Removes TypeScript declaration files from the build.
| └── remove-empty-dirs.mjs # Removes empty directories from the build.
├── src/ # Source code for package.
| ├── static/ # Static files served as the api documentation.
| ├── utils/ # Utility functions.
| ├── config.ts # Config variables.
| ├── index.ts # Export functions for the package.
| └── types.ts # TypeScript types.
├── package.json # Package config and dependencies.
├── .npmrc # NPM config.
├── rollup.config.mjs # Builds and compiles TypeScript files into JavaScript.
├── rollupdts.config.mjs # Builds and compiles TypeScript declartion files.
# Compile all src code into a bundle in build/ directory.
$ npm run build# Part of 'build' and it bundles the typescipt declarations into a single bundle.d.ts file.
$ npm run build:dts# Part of build and it removes directories and files before the build.
$ npm run clean:prebuild# Part of build and it removes directories and files after the build.
$ npm run clean:postbuild# Used to package the code before a release.
$ npm run packThese are the functions and types exported by the @bcgov/citz-imb-kc-express-api-docs module.
import {
apiDocs, // Initialization function to generate api docs.
} from '@bcgov/citz-imb-kc-express-api-docs';
// TypeScript Types:
import {
Config, // Type for configuration options.
} from '@bcgov/citz-imb-kc-express';These are the TypeScript types of the @bcgov/citz-imb-kc-express-api-docs module.
const apiDocs: (app: Application, config: Config) => void;
type CustomSchemaConfig = {
[pattern: string]: ParamProperties;
};
type CustomControllerConfig = {
[controller: string]: {
description: string;
query?: {
[param: string]: ParamProperties;
};
};
};
type CustomResponseStatuses = {
[variable: string]: number;
};
type Config = {
title: string;
expressFilePath: string;
modulesBasePath: string;
modules: {
[module: string]: {
description: string;
};
};
customSchemas?: CustomSchemaConfig;
customControllers?: CustomControllerConfig;
customResponseStatuses?: CustomResponseStatuses;
defaultResponses?: number[];
};
type Method = "GET" | "POST" | "PATCH" | "PUT" | "DELETE";
type ParamProperties = {
required: boolean;
type: string; // "string" | "number" | "boolean"
description?: string;
};
type Endpoint = {
route: string;
method: Method;
description?: string;
controller: {
name: string;
path: string;
query?: {
[param: string]: ParamProperties;
};
pathParams?: {
[param: string]: ParamProperties;
};
};
responseStatusCodes?: number[];
};
type Modules = {
[key: string]: {
description: string;
protected: boolean;
protectedBy: string[];
protectedByAll: boolean;
endpoints: Endpoint[];
};
};The following applications are currently using this keycloak implementation solution:
PLAY - CITZ IMB Package Testing App