Skip to content
This repository has been archived by the owner on Sep 8, 2021. It is now read-only.
/ tsgen Public archive

Generates Typescript APIs and JSON-Schemas from d.ts files. [deprecated]

Notifications You must be signed in to change notification settings

atek-cloud/tsgen

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tsgen Typescript generator for Atek

Deprecated

This repo was used during an early version of Atek in which schemas were written as d.ts files and then generated using this tool. This was more complexity than we needed, so this approach has been deprecated.


Atek defines RPC and database schemas using URL IDs, various options, (in some cases) JSON Schemas. These can be somewhat tedious to define manually.

To make life easier, we use .d.ts files to declare the schemas and API interfaces and then we generate the API code using this tsgen tool.

A .d.ts file should include a couple of conventions:

  • It should start with a "frontmatter" which is a multi-line comment formatted in YAML. This must include an id and type value.
  • The id should be a URL without any protocol or extension.
  • The type should be "api" or "adb-record"
  • The metadata can (and should) also include title and description.
  • If type is "api" then you can also indicate transport but tsgen doesnt make anything interesting for proxy transports.
  • It should export a default interface.

Usage

atek tsgen gen-file --in {dts_file_path} --out {output_folder} --env {env}
atek tsgen gen-folder --in {dts_folder_path} --out {output_folder} --env {env}

Use gen-file to generate TS for a single dts, and gen-folder for a folder of dts files.

Choose an --env value based on your application:

  • node A nodejs atek application
  • host The "atek" project (you only need this if working on atek)

If using node, you will need to install @atek-cloud/node-rpc as the generated code depends on it.

Example

Suppose we have a file ping-api.d.ts.

/*
id: atek.cloud/ping-api
type: api
title: Ping API
description: Utility API used for debugging and testing liveness.
*/

export default interface PingApi {
  // Ask for a pong back with the given parameter
  ping (param: number): Promise<number>
}

If we run:

atek tsgen gen-file --in ping-api.d.ts --out ./gen --env host

We will get the following output:

./gen/atek.cloud/ping-api.ts

/**
 * File generated by Atek tsgen
 * env=host
 * DO NOT MODIFY
 */
import { URL } from 'url';
import { ApiBrokerClient } from '@atek-cloud/api-broker';

export const ID = "atek.cloud/ping-api";
export const REVISION = undefined;

export default class PingApiClient extends ApiBrokerClient {
  constructor() {
    super("atek.cloud/ping-api")
  }

  ping(param: number): Promise<number> {
    return this.$rpc("ping", [param])
  }
}

./gen/atek.cloud/ping-api.server.ts

/**
 * File generated by Atek tsgen
 * env=host
 * DO NOT MODIFY
 */
import { URL } from 'url';
import { ApiBrokerServer, ApiBrokerServerHandlers } from '@atek-cloud/api-broker';

export const ID = "atek.cloud/ping-api";
export const REVISION = undefined;
export const SCHEMAS = {"$schema":"http://json-schema.org/draft-07/schema#","definitions":{"PingApi":{"type":"object"},"api_PingApi_Ping":{"type":"object","properties":{"params":{"type":"array","items":{"type":"number"},"minItems":1,"maxItems":1},"returns":{"type":"number"}},"required":["params","returns"]}}};
export const EXPORT_MAP = {"methods":{"ping":"#/definitions/api_PingApi_Ping"},"events":{}};

export default class PingApiServer extends ApiBrokerServer {
  ID = "atek.cloud/ping-api";
  REVISION = undefined;

  constructor(handlers: ApiBrokerServerHandlers) {
    super(handlers, SCHEMAS, EXPORT_MAP)
  }
}

You can now use these APIs to call and serve the ping API:

import PingApiClient from './gen/atek.cloud/ping-api.ts'

const api = new PingApiClient()
await api.ping(42) // => 42
import createExpressApp, * as express from 'express'
import PingApiServer from './gen/atek.cloud/ping-api.server.ts'

const apiServer = new PingApiServer({
  ping (param: number): Promise<number> {
    return Promise.resolve<number>(param)
  }
})

const PORT = Number(process.env.ATEK_ASSIGNED_PORT)
const app = createExpressApp()
app.use(bodyParser.json())
app.post('/_api/ping', (req, res) => apiServer.handle(req, res, req.body))
app.listen(PORT, () => {
  console.log(`Ping server running at: http://localhost:${PORT}/`)
})

About

Generates Typescript APIs and JSON-Schemas from d.ts files. [deprecated]

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published