npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

interpret-dubbo2js

v3.0.0

Published

apache dubbo & dubbo-js interpret java-jar file to typescript files

Downloads

42

Readme

Translator

Dubbo-js uses RPC to get through node and java. If we can automatically generate Dubbo service interface definition, parameter conversion, and have automatic completion ability in ide, our development experience will be better.

"Translator" came into being for this purpose!

We will like it.

Duty

  1. Generate typescript code corresponding to Dubbo service interface;
  2. Parametric conversion, converting JavaScript object to a format that hession. JS recognizes;

TODO

  • [ ] Synchronization of interface annotation information;
  • [ ] MVN packaged plug-in;

How to Usage?

We divide the whole process into three steps.

  1. Generate jar packages and install dependencies in Java API projects;

  2. Extract ast information from generated jar bytecode, and then generate typescript based on it.

  3. Calling services;

step1:

mvn package
mvn install dependency:copy-dependencies

step2:

npm install interpret-dubbo2js -g
interpret -c dubbo.json

dubbo.json:

{
  "output": "./src",
  "entry": "com.qianmi",
  "entryJarPath": "${jarPath}",
  "libDirPath": "${denpendJarDir}"
}

note: Reference examples;

| parameter | affect | | ------------ | ------------------------------------------------------------------------------------ | | output | the dir to save output eg: config example | | entry | package path filter eg: config example | | entryJarPath | jar package for dubbo api eg: config example | | libDirPath | the dubbo api dependencies eg: config example |

step2:Use the provider

import {ShowCaseProvider} from '@qianmi/***-api/lib/com/qianmi/ShowCaseProvider';
const dubbo = new Dubbo({
  application: {name: 'd2p-visitor-bff'},
  dubboInvokeTimeout: 10,
  //zookeeper address
  register: app.config.zookeeper,
  dubboVersion: '2.4.13',
  logger: app.logger as ILogger,
  interfaces: [
    'com.qianmi.cloudshop.api.marketing.d2p.D2pMarketingQueryProvider',
  ],
});
let showCaseProvider = ShowCaseProvider(dubbo);
showCaseProvider.show();

Tip npm install interpret-util dubbo-js;

interpret-example;

vocabulary explanation

Note: The code snippet in the following explanation comes from hello-egg-node

Provider

There are two meanings.

First, Dubbo provides services interfaces, such as

package com.alibaba.dubbo.demo;

public interface DemoProvider {

    String sayHello(String name);

    String echo() ;

    void test();

    UserResponse getUserInfo(UserRequest request);
}

Second, the client for node.js, corresponding to the Dubbo service, such as

import {UserRequest} from './UserRequest';
import {UserResponse} from './UserResponse';
import {argumentMap, JavaString} from 'interpret-util';
import {TDubboCallResult, Dubbo} from 'dubbo2.js';

export interface IDemoProvider {
  sayHello(name: JavaString): TDubboCallResult<string>;
  test(): TDubboCallResult<void>;
  echo(): TDubboCallResult<string>;
  getUserInfo(request: UserRequest): TDubboCallResult<UserResponse>;
}

export const DemoProviderWrapper = {
  sayHello: argumentMap,
  test: argumentMap,
  echo: argumentMap,
  getUserInfo: argumentMap,
};

export function DemoProvider(dubbo: Dubbo): IDemoProvider {
  return dubbo.proxyService<IDemoProvider>({
    dubboInterface: 'com.alibaba.dubbo.demo.DemoProvider',
    methods: DemoProviderWrapper,
  });
}

//generate by interpret-cli dubbo-js

converter

The main responsibility of a translator is to seamlessly connect with nodejs dubbo.

The main responsibility of the converter is to convert JavaScript code into JS objects in hession.JS format and then communicate with Dubbo service.

Let's see how it works:

UserRequest.java

//dubbo-demo/dubbo-demo-api/src/main/java/com/alibaba/dubbo/demo/DemoProvider.java
public interface DemoProvider {
    UserResponse getUserInfo(UserRequest request);
}

//dubbo-demo/dubbo-demo-api/src/main/java/com/alibaba/dubbo/demo/UserRequest.java
public class UserRequest implements Serializable {
    private Integer id;
    private String name;
    private String email;
}

Corresponding TS code

UserRequest.ts

//
import java from 'js-to-java';

//
export interface IUserRequest {
  name?: string;
  id?: number;
  email?: string;
}

export class UserRequest {
  constructor(params: IUserRequest) {
    this.name = params.name;
    this.id = params.id;
    this.email = params.email;
  }

  name?: string;
  id?: number;
  email?: string;

  __fields2java() {
    return {
      $class: 'com.alibaba.dubbo.demo.UserRequest',
      $: {
        name: java.String(this.name),
        id: java.Integer(this.id),
        email: java.String(this.email),
      },
    };
  }
}

//generate by interpret-cli dubbo-js

java Ast

Extract ast from Java source code and use it to convert to typescritp code

Let's look at the ast information for DemoProvider and UserRequest in the example above.

{
  "classes": {
    "com.alibaba.dubbo.demo.DemoProvider": {
      "fields": {},
      "isAbstract": true,
      "isEnum": false,
      "isInterface": true,
      "methods": {
        "sayHello": {
          "formalParams": ["name"],
          "isOverride": false,
          "params": [
            {
              "name": "java.lang.String",
              "typeArgs": []
            }
          ],
          "ret": {
            "name": "java.lang.String",
            "typeArgs": []
          },
          "typeParams": []
        },
        "test": {
          "formalParams": [],
          "isOverride": false,
          "params": [],
          "ret": {
            "name": "java.lang.Void"
          },
          "typeParams": []
        },
        "echo": {
          "formalParams": [],
          "isOverride": false,
          "params": [],
          "ret": {
            "name": "java.lang.String",
            "typeArgs": []
          },
          "typeParams": []
        },
        "getUserInfo": {
          "formalParams": ["request"],
          "isOverride": false,
          "params": [
            {
              "name": "com.alibaba.dubbo.demo.UserRequest",
              "typeArgs": []
            }
          ],
          "ret": {
            "name": "com.alibaba.dubbo.demo.UserResponse",
            "typeArgs": []
          },
          "typeParams": []
        }
      },
      "name": "com.alibaba.dubbo.demo.DemoProvider",
      "privateFields": [],
      "typeParams": [],
      "values": []
    },
    "com.alibaba.dubbo.demo.UserRequest": {
      "fields": {
        "name": {
          "name": "java.lang.String",
          "typeArgs": []
        },
        "id": {
          "name": "java.lang.Integer",
          "typeArgs": []
        },
        "email": {
          "name": "java.lang.String",
          "typeArgs": []
        }
      },
      "isAbstract": false,
      "isEnum": false,
      "isInterface": false,
      "methods": {
        "setName": {
          "formalParams": ["name"],
          "isOverride": false,
          "params": [
            {
              "name": "java.lang.String",
              "typeArgs": []
            }
          ],
          "ret": {
            "name": "java.lang.Void"
          },
          "typeParams": []
        },
        "getName": {
          "formalParams": [],
          "isOverride": false,
          "params": [],
          "ret": {
            "name": "java.lang.String",
            "typeArgs": []
          },
          "typeParams": []
        },
        "setEmail": {
          "formalParams": ["email"],
          "isOverride": false,
          "params": [
            {
              "name": "java.lang.String",
              "typeArgs": []
            }
          ],
          "ret": {
            "name": "java.lang.Void"
          },
          "typeParams": []
        },
        "setId": {
          "formalParams": ["id"],
          "isOverride": false,
          "params": [
            {
              "name": "java.lang.Integer",
              "typeArgs": []
            }
          ],
          "ret": {
            "name": "java.lang.Void"
          },
          "typeParams": []
        },
        "getEmail": {
          "formalParams": [],
          "isOverride": false,
          "params": [],
          "ret": {
            "name": "java.lang.String",
            "typeArgs": []
          },
          "typeParams": []
        },
        "getId": {
          "formalParams": [],
          "isOverride": false,
          "params": [],
          "ret": {
            "name": "java.lang.Integer",
            "typeArgs": []
          },
          "typeParams": []
        },
        "toString": {
          "formalParams": [],
          "isOverride": false,
          "params": [],
          "ret": {
            "name": "java.lang.String",
            "typeArgs": []
          },
          "typeParams": []
        }
      },
      "name": "com.alibaba.dubbo.demo.UserRequest",
      "privateFields": ["id", "name", "email"],
      "typeParams": [],
      "values": []
    },
    "com.alibaba.dubbo.demo.UserResponse": {
      "fields": {
        "status": {
          "name": "java.lang.String",
          "typeArgs": []
        },
        "info": {
          "name": "java.util.Map",
          "typeArgs": [
            {
              "isWildcard": false,
              "type": {
                "name": "java.lang.String",
                "typeArgs": []
              }
            },
            {
              "isWildcard": false,
              "type": {
                "name": "java.lang.String",
                "typeArgs": []
              }
            }
          ]
        }
      },
      "isAbstract": false,
      "isEnum": false,
      "isInterface": false,
      "methods": {
        "getInfo": {
          "formalParams": [],
          "isOverride": false,
          "params": [],
          "ret": {
            "name": "java.util.Map",
            "typeArgs": [
              {
                "isWildcard": false,
                "type": {
                  "name": "java.lang.String",
                  "typeArgs": []
                }
              },
              {
                "isWildcard": false,
                "type": {
                  "name": "java.lang.String",
                  "typeArgs": []
                }
              }
            ]
          },
          "typeParams": []
        },
        "toString": {
          "formalParams": [],
          "isOverride": false,
          "params": [],
          "ret": {
            "name": "java.lang.String",
            "typeArgs": []
          },
          "typeParams": []
        },
        "setInfo": {
          "formalParams": ["info"],
          "isOverride": false,
          "params": [
            {
              "name": "java.util.Map",
              "typeArgs": [
                {
                  "isWildcard": false,
                  "type": {
                    "name": "java.lang.String",
                    "typeArgs": []
                  }
                },
                {
                  "isWildcard": false,
                  "type": {
                    "name": "java.lang.String",
                    "typeArgs": []
                  }
                }
              ]
            }
          ],
          "ret": {
            "name": "java.lang.Void"
          },
          "typeParams": []
        },
        "getStatus": {
          "formalParams": [],
          "isOverride": false,
          "params": [],
          "ret": {
            "name": "java.lang.String",
            "typeArgs": []
          },
          "typeParams": []
        },
        "setStatus": {
          "formalParams": ["status"],
          "isOverride": false,
          "params": [
            {
              "name": "java.lang.String",
              "typeArgs": []
            }
          ],
          "ret": {
            "name": "java.lang.Void"
          },
          "typeParams": []
        }
      },
      "name": "com.alibaba.dubbo.demo.UserResponse",
      "privateFields": ["status", "info"],
      "typeParams": [],
      "values": []
    }
  },
  "providers": ["com.alibaba.dubbo.demo.DemoProvider"]
}

argumentMap

ArgumentMap is a runtime assistant method whose main responsibility is to trigger data structure transformation.

Main steps:

  1. Traversal parameters are called if _fields 2java is included.

  2. Delete null and undefined values;

//Examples of argumentMap usage

import {UserRequest} from './UserRequest';
import {UserResponse} from './UserResponse';
import {argumentMap, JavaString} from 'interpret-util';
import {TDubboCallResult, Dubbo} from 'dubbo-js';

export interface IDemoProvider {
  sayHello(name: JavaString): TDubboCallResult<string>;
  test(): TDubboCallResult<void>;
  echo(): TDubboCallResult<string>;
  getUserInfo(request: UserRequest): TDubboCallResult<UserResponse>;
}

export const DemoProviderWrapper = {
  sayHello: argumentMap,
  test: argumentMap,
  echo: argumentMap,
  getUserInfo: argumentMap,
};

export function DemoProvider(dubbo: Dubbo): IDemoProvider {
  return dubbo.proxyService<IDemoProvider>({
    dubboInterface: 'com.alibaba.dubbo.demo.DemoProvider',
    methods: DemoProviderWrapper,
  });
}

//generate by interpret-cli dubbo-js

//Content of argumentMap method
export function argumentMap() {
  let _arguments = Array.from(arguments);

  return _arguments.map(
    argumentItem =>
      argumentItem.__fields2java
        ? paramEnhance(argumentItem.__fields2java())
        : argumentItem,
  );
}

function paramEnhance(javaParams: Array<object> | object) {
  if (javaParams instanceof Array) {
    for (let i = 0, ilen = javaParams.length; i < ilen; i++) {
      let itemParam = javaParams[i];
      minusRedundancy(itemParam);
    }
  } else {
    minusRedundancy(javaParams);
  }
  return javaParams;
}

function minusRedundancy(itemParam: any) {
  if (!itemParam) {
    return;
  }
  for (var _key in itemParam.$) {
    if (itemParam.$[_key] === null || itemParam.$[_key] === undefined) {
      delete itemParam.$[_key];
      log('删除 key %s from %j ', itemParam, _key);
    }
  }
}

FAQ:

q1:How to integrate with the project?

There are two ways to use it.

  1. Embedding projects directly;

  2. Publish NPM packages;

The first approach is very suitable for a small number of Dubbo interfaces, single projects; see hello-egg

The second approach is suitable for large-scale projects, especially multi-project shared interfaces; see Automatic Translation Service

Tip 生成的代码可以发 npm 包供其他业务线使用或直接在项目中引用

Resources

dubbo-js-Translator.pdf

interpret-example;