Skip to Content
Codegen Templates Reference

Client Templates

Introduction

Vovk.ts renders the client libraries from EJS  templates. The template logic works like this:

  1. One template definition renders several files: a template is a folder with one or more files. A file with the .ejs extension is rendered as an EJS template, and other files are copied as they are. index.ts.ejs is rendered as index.ts; an index.ts without the .ejs extension is copied as it is.
  2. A template can build on another one with the extends option: it takes the options of the other template and overrides some of them.
  3. A template can include other templates with the requires option: it renders them into the output folder.

Template definitions live in the clientTemplateDefs option of the config, together with the built-in definitions. To see them all, set exposeConfigKeys to true, or add clientTemplateDefs to it if it’s an array. Then .vovk-schema/_meta.json lists them under config.

Example

Take the built-in template definition of the Rust client as an example of the options in the next section. Its main definition is under the rs key: the template name you use in the segmented client or composed client config.

The rs template has no files of its own, so it has no templatePath. It requires:

  • rsSrc, which renders the Rust source files to ./src (relative to outDir),
  • rsPkg, which renders the Cargo files to the root of outDir,
  • and rsReadme, which renders the README to the root of outDir.

The rs definition also sets composedClient.outDir to dist_rust, so it doesn’t write into the src/client folder of the composed TypeScript client.

rsSrc points templatePath to its template folder (lib.rs.ejs, http_request.rs and so on). It requires the schemaJson template, which renders schema.json: the full schema from the .vovk-schema/ folder.

The same setup in your own vovk.config.mjs file:

vovk.config.mjs
/** @type {import('vovk').VovkConfig} */ const config = { clientTemplateDefs: { schemaJson: { templatePath: `vovk-cli/client-templates/schema-json/`, }, rsSrc: { templatePath: `vovk-rust/client-templates/rs-src/`, requires: { schemaJson: './', }, }, rsPkg: { templatePath: `vovk-rust/client-templates/rs-pkg/`, }, rsReadme: { templatePath: `vovk-rust/client-templates/rs-readme/`, }, rs: { composedClient: { outDir: 'dist_rust', }, requires: { rsSrc: './src/', rsPkg: './', rsReadme: './', }, }, } }; export default config;

(the paths end with / for clarity; it isn’t required)

With this setup, generate the full Cargo package:

npx vovk generate --from rs --out ./dist_rust

Or only the source code:

npx vovk generate --from rsSrc --out ./my_rust_project/src

Or only the README.md file:

npx vovk generate --from rsReadme --out ./my_rust_project

Template Definitions

A definition has these options:

extends?: string

The name of the built-in template this definition extends. The definition takes the options of that template and can override them, such as segmentedClient.outDir.

templatePath?: string

The path of the template folder: relative to the project root, or a package path such as vovk-cli/client-templates/ts-base/. Without it, the template can still include other templates with requires.

requires?: Record<string, string>

The template definitions this template includes. The keys are template names; the values are the paths they render to, relative to the output folder.

composedClient?: object

Composed client options for this template, on top of the root composedClient options of the config, such as outDir or excludeSegments.

segmentedClient?: object

Segmented client options for this template, on top of the root segmentedClient options of the config, such as outDir or excludeSegments.

outputConfig?: object

Overrides the root outputConfig of the config for this template, such as origin or openAPIObject.

Built-in Templates

ts

The default template of the composed client and the segmented client. Renders TypeScript code.

tsBase

The default template of the bundle, since it has no openapi object. Renders TypeScript code.

schemaTs

Renders schema.ts, which imports the segment schemas from the .vovk-schema/ folder and exports them as a TypeScript object.

  • templatePath is vovk-cli/client-templates/schema-ts/.

schemaJson

Renders schema.json: all segment schemas from the .vovk-schema/ folder for the composed client, or one segment schema for the segmented client.

  • templatePath is vovk-cli/client-templates/schema-json/.

openapiTs

Renders openapi.ts, which exports the OpenAPI schema from the openapi.json file next to it (rendered by the openapiJson template).

  • templatePath is vovk-cli/client-templates/openapi-ts/.
  • requires openapiJson, for the OpenAPI schema it imports.

openapiJson

Renders openapi.json, the OpenAPI schema. Use it alone to add the OpenAPI schema to your project.

  • templatePath is vovk-cli/client-templates/openapi-json/.

To write only the openapi.json file, without a client:

npx vovk generate --from openapiJson --out ./public

readme

Renders README.md, the documentation of the generated TypeScript client. It takes its data from package.json. The bundle, composedClient or segmentedClient options of the config can override that data, at the root or in a template definition. Each RPC method gets a code sample that you can copy into your code.

  • templatePath is vovk-cli/client-templates/readme/.

packageJson

Renders package.json, so the generated client can be published to NPM. It takes name, version, description, license, author, contributors, repository, homepage, bugs and keywords from the root package.json, and sets version to 0.0.0 when there is none. The bundle, composedClient or segmentedClient options of the config can override these and other package fields, at the root or in a template definition.

  • templatePath is vovk-cli/client-templates/package-json/.

mixins

Renders the types and the schema of OpenAPI mixins, when the project has them.

  • templatePath is vovk-cli/client-templates/mixins/.

rs

Renders the Rust client package: the source code and the Cargo files.

  • requires rsSrc (rendered to ./src/), rsPkg and rsReadme.
  • Sets composedClient.outDir to dist_rust.

rsSrc

Renders the source files of the Rust client, such as lib.rs and http_request.rs.

  • templatePath is vovk-rust/client-templates/rs-src/.
  • requires schemaJson, for the full schema in the generated code.

rsPkg

Renders Cargo.toml for the Rust client.

  • templatePath is vovk-rust/client-templates/rs-pkg/.

rsReadme

Renders README.md for the Rust client, like the readme template.

  • templatePath is vovk-rust/client-templates/rs-readme/.

py

Renders the Python client package: the source code and the setup files.

  • requires pySrc (rendered to ./src/[package_name]/), pyPkg and pyReadme. [package_name] is the package name without @, with /, - and other characters a Python name can’t hold turned into _: @acme/web-app becomes acme_web_app. A name that starts with a digit gets a pkg_ prefix, and a Python or Rust keyword gets a _pkg suffix: 3d-viewer becomes pkg_3d_viewer, class becomes class_pkg. The Cargo.toml of the Rust client uses the same name.
  • Sets composedClient.outDir to dist_python.

pySrc

Renders the source files of the Python client: __init__.py, api_client.py and py.typed.

  • templatePath is vovk-python/client-templates/py-src/.
  • requires schemaJson, for the full schema in the generated code.

pyPkg

Renders pyproject.toml and setup.cfg for the Python client.

  • templatePath is vovk-python/client-templates/py-pkg/.

pyReadme

Renders README.md for the Python client, like the readme template.

  • templatePath is vovk-python/client-templates/py-readme/.

Roadmap

  • 📝 Document how to create custom templates.
Last updated on