Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add TypeScript support for hooks and filters #519

Merged
merged 15 commits into from
Mar 5, 2021
9 changes: 9 additions & 0 deletions docs/authoring.md
Original file line number Diff line number Diff line change
Expand Up @@ -391,3 +391,12 @@ async function asyncCamelCase(str, callback) {
```

In case you have more than one template and want to reuse filters, you can put them in a single library. You can configure such a library in the template configuration under `filters` property. You can also use the official AsyncAPI [filters library](https://github.com/asyncapi/generator-filters). To learn how to add such filters to configuration [read more about the configuration file](#configuration-file).

## TypeScript support

The AsyncAPI generator has TypeScript support for [hooks](#hooks) and Nunjucks's [filters](#filters). Assumptions:

- Installing the `typescript` package and creating the` tsconfig.json` file isn't necessary.
- Source code of the hook/filter must have `.ts` extension.
- Each package related to the typings for TypeScript like `@types/node` must be installed in the template under `dependencies` array. This is because the Generator transpiles the TypeScript code on-the-fly while rendering the template, and cannot use packages under `devDependencies`.
- Each template should have `@types/node` package installed to enable support for typings for Node.
12 changes: 8 additions & 4 deletions lib/generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,12 @@ const {
getInvalidOptions,
isReactTemplate,
isJsFile,
registerSourceMap,
registerTypeScript,
} = require('./utils');
const { registerFilters } = require('./filtersRegistry');
const { registerHooks } = require('./hooksRegistry');

parser.registerSchemaParser(openapiSchemaParser);
parser.registerSchemaParser(ramlDtParser);
parser.registerSchemaParser(avroSchemaParser);

const FILTERS_DIRNAME = 'filters';
const HOOKS_DIRNAME = 'hooks';
const CONFIG_FILENAME = 'package.json';
Expand All @@ -56,6 +54,12 @@ const shouldIgnoreDir = dirPath =>
dirPath === '.git'
|| dirPath.startsWith(`.git${path.sep}`);

parser.registerSchemaParser(openapiSchemaParser);
parser.registerSchemaParser(ramlDtParser);
parser.registerSchemaParser(avroSchemaParser);
registerSourceMap();
registerTypeScript();

class Generator {
/**
* Instantiates a new Generator object.
Expand Down
9 changes: 9 additions & 0 deletions lib/hooksRegistry.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,15 @@ async function registerConfigHooks(hooks, templateDir, templateConfig) {
* @param {Array} config List of hooks configured in template configuration
*/
function addHook(hooks, mod, config) {
/**
* ESM `export default { ... }` is transpiled to:
* module.exports = { default: { ... } };
* First check the `default` object, and if it exists the override mod to `default`.
*/
if (typeof mod.default === 'object') {
mod = mod.default;
}

Object.keys(mod).forEach(hookType => {
const moduleHooksArray = [].concat(mod[hookType]);

Expand Down
19 changes: 19 additions & 0 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,22 @@ utils.getInvalidOptions = (generatorOptions, options) => {
utils.isAsyncFunction = (fn) => {
return fn && fn.constructor && fn.constructor.name === 'AsyncFunction';
};

/**
* Register `source-map-support` package.
derberg marked this conversation as resolved.
Show resolved Hide resolved
* This package provides source map support for stack traces in Node - also for transpiled code from TS.
*
* @private
*/
utils.registerSourceMap = () => {
require('source-map-support').install();
};

/**
* Register TypeScript transpiler. It enables transpilation of TS filters and hooks on the fly.
*
* @private
*/
utils.registerTypeScript = () => {
require('ts-node').register();
};
43 changes: 43 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,10 @@
"nunjucks": "^3.2.0",
"resolve-pkg": "^2.0.0",
"semver": "^7.3.2",
"simple-git": "^1.131.0"
"simple-git": "^1.131.0",
"source-map-support": "^0.5.19",
"ts-node": "^9.1.1",
"typescript": "^4.2.2"
},
"devDependencies": {
"@semantic-release/commit-analyzer": "^8.0.1",
Expand Down