diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 8011724bb..000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,85 +0,0 @@ -version: 2 -updates: -- package-ecosystem: maven - directory: "/" - schedule: - interval: daily - time: "07:00" - open-pull-requests-limit: 10 - ignore: - - dependency-name: io.netty:netty-transport-native-kqueue - versions: - - 4.1.58.Final - - 4.1.59.Final - - 4.1.62.Final - - dependency-name: io.netty:netty-transport-native-epoll - versions: - - 4.1.58.Final - - 4.1.59.Final - - 4.1.62.Final - - dependency-name: io.netty:netty-codec-haproxy - versions: - - 4.1.58.Final - - 4.1.59.Final - - 4.1.62.Final - - dependency-name: io.micrometer:micrometer-registry-graphite - versions: - - 1.6.3 - - 1.6.4 - - 1.6.5 - - dependency-name: io.micrometer:micrometer-registry-jmx - versions: - - 1.6.3 - - 1.6.4 - - 1.6.5 - - dependency-name: io.micrometer:micrometer-registry-influx - versions: - - 1.6.3 - - 1.6.4 - - 1.6.5 - - dependency-name: io.micrometer:micrometer-registry-prometheus - versions: - - 1.6.3 - - 1.6.4 - - 1.6.5 - - dependency-name: org.graalvm.sdk:graal-sdk - versions: - - 21.0.0 - - 21.0.0.2 - - dependency-name: org.graalvm.tools:chromeinspector - versions: - - 21.0.0 - - 21.0.0.2 - - dependency-name: org.graalvm.tools:profiler - versions: - - 21.0.0 - - 21.0.0.2 - - dependency-name: org.graalvm.js:js - versions: - - 21.0.0 - - 21.0.0.2 - - dependency-name: org.graalvm.truffle:truffle-api - versions: - - 21.0.0 - - 21.0.0.2 - - dependency-name: org.apache.logging.log4j:log4j-core - versions: - - 2.14.0 - - dependency-name: org.apache.logging.log4j:log4j-api - versions: - - 2.14.0 - - dependency-name: io.vertx:vertx-circuit-breaker:sources - versions: - - 4.0.1 - - dependency-name: io.vertx:vertx-config:sources - versions: - - 4.0.1 - - dependency-name: io.vertx:vertx-config - versions: - - 4.0.1 - - dependency-name: com.datastax.oss:java-driver-query-builder - versions: - - 4.10.0 - - dependency-name: com.datastax.oss:java-driver-mapper-runtime - versions: - - 4.10.0 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 000000000..a743177eb --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,71 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ develop, master ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ develop ] + schedule: + - cron: '23 10 * * 2' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'java', 'javascript' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] + # Learn more: + # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏ī¸ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml index e3b789b75..1b50da117 100644 --- a/.github/workflows/develop.yml +++ b/.github/workflows/develop.yml @@ -15,9 +15,7 @@ jobs: os: - ubuntu-latest jdk: - - 'https://api.adoptopenjdk.net/v3/binary/latest/8/ga/linux/x64/jdk/hotspot/normal/adoptopenjdk' - - 'https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-21.1.0/graalvm-ce-java8-linux-amd64-21.1.0.tar.gz' - - 'https://api.adoptopenjdk.net/v3/binary/latest/8/ga/linux/x64/jdk/openj9/normal/adoptopenjdk' + - 'https://api.adoptium.net/v3/binary/latest/8/ga/linux/x64/jdk/hotspot/normal/eclipse?project=jdk' runs-on: ${{ matrix.os }} steps: - name: Checkout @@ -53,9 +51,8 @@ jobs: os: - ubuntu-latest jdk: - - 'https://api.adoptopenjdk.net/v3/binary/latest/11/ga/linux/x64/jdk/hotspot/normal/adoptopenjdk' - - 'https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-21.1.0/graalvm-ce-java11-linux-amd64-21.1.0.tar.gz' - - 'https://api.adoptopenjdk.net/v3/binary/latest/11/ga/linux/x64/jdk/openj9/normal/adoptopenjdk' + - 'https://api.adoptium.net/v3/binary/latest/11/ga/linux/x64/jdk/hotspot/normal/eclipse?project=jdk' + - 'https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-21.3.0/graalvm-ce-java11-linux-amd64-21.3.0.tar.gz' runs-on: ${{ matrix.os }} steps: - name: Checkout @@ -83,16 +80,16 @@ jobs: - name: Run tests run: mvn clean verify - java16: - name: Run Java 16 tests + java17: + name: Run Java 17 tests strategy: fail-fast: true matrix: os: - ubuntu-latest jdk: - - 'https://api.adoptopenjdk.net/v3/binary/latest/16/ga/linux/x64/jdk/hotspot/normal/adoptopenjdk' - - 'https://api.adoptopenjdk.net/v3/binary/latest/16/ga/linux/x64/jdk/openj9/normal/adoptopenjdk' + - 'https://api.adoptium.net/v3/binary/latest/17/ga/linux/x64/jdk/hotspot/normal/eclipse?project=jdk' + - 'https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-21.3.0/graalvm-ce-java17-linux-amd64-21.3.0.tar.gz' runs-on: ${{ matrix.os }} steps: - name: Checkout @@ -115,7 +112,7 @@ jobs: with: distribution: 'jdkfile' jdkFile: ${{ runner.temp }}/java_package.tar.gz - java-version: '16' + java-version: '17' architecture: x64 - name: Run tests run: mvn clean verify diff --git a/CHANGELOG.md b/CHANGELOG.md index 086e1d458..e713dce07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [0.16.0] - 2021-10-28 +* Bump graaljs to 20.3.0 +* Bump vert.x to 4.2.0 +* Added new vert.x modules +* Bumped dependencies (dependabot) +* Removed nag about no compiler, as graal does it for us +* PM can now run without NPM +* ES fixes for generated code +* Re-enabling manual generation +* Added a CoC + ## [0.15.0] - 2021-06-02 * FileSystemResolver will use import maps when available * Started implementing support for import-map diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..41dd9ebee --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,127 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/codegen/pom.xml b/codegen/pom.xml index 8cba6d031..0eb987e39 100644 --- a/codegen/pom.xml +++ b/codegen/pom.xml @@ -4,14 +4,14 @@ io.reactiverse es4x-parent - 0.15.0 + 0.16.0 .. 4.0.0 es4x-codegen - 0.15.0 + 0.16.0 ${java.home}/../lib/tools.jar @@ -49,6 +49,16 @@ vertx-codegen ${stack.version} + + io.vertx + vertx-docgen + 0.9.4 + + + io.vertx + vertx-codetrans + 4.1.0.Beta1 + junit junit diff --git a/codegen/src/main/java/io/reactiverse/es4x/codegen/generator/IndexDTS.java b/codegen/src/main/java/io/reactiverse/es4x/codegen/generator/IndexDTS.java index 94ed7237b..5fceac7a3 100644 --- a/codegen/src/main/java/io/reactiverse/es4x/codegen/generator/IndexDTS.java +++ b/codegen/src/main/java/io/reactiverse/es4x/codegen/generator/IndexDTS.java @@ -305,10 +305,16 @@ private void generateMethod(PrintWriter writer, ClassTypeInfo type, MethodInfo m generateDoc(writer, method.getDoc(), " "); + if (method.isMethodOverride()) { + writer.print(" override "); + } else { + writer.print(" "); + } + if (getOverrideArgs(type.getSimpleName(), method.getName()) != null) { - writer.printf(" %s%s%s(%s", method.isStaticMethod() ? "static " : "", method.getName(), genGeneric(method.getTypeParams()), getOverrideArgs(type.getSimpleName(), method.getName())); + writer.printf("%s%s%s(%s", method.isStaticMethod() ? "static " : "", method.getName(), genGeneric(method.getTypeParams()), getOverrideArgs(type.getSimpleName(), method.getName())); } else { - writer.printf(" %s%s%s(", method.isStaticMethod() ? "static " : "", method.getName(), genGeneric(method.getTypeParams())); + writer.printf("%s%s%s(", method.isStaticMethod() ? "static " : "", method.getName(), genGeneric(method.getTypeParams())); boolean more = false; for (ParamInfo param : params) { if (more) { diff --git a/codegen/src/main/java/io/reactiverse/es4x/codegen/generator/JVMClass.java b/codegen/src/main/java/io/reactiverse/es4x/codegen/generator/JVMClass.java index bad0f445c..70042065e 100644 --- a/codegen/src/main/java/io/reactiverse/es4x/codegen/generator/JVMClass.java +++ b/codegen/src/main/java/io/reactiverse/es4x/codegen/generator/JVMClass.java @@ -1,11 +1,12 @@ package io.reactiverse.es4x.codegen.generator; +import io.vertx.core.json.JsonObject; + import java.io.PrintWriter; import java.lang.reflect.*; import java.util.Arrays; -import static io.reactiverse.es4x.codegen.generator.Util.genType; -import static io.reactiverse.es4x.codegen.generator.Util.isExcluded; +import static io.reactiverse.es4x.codegen.generator.Util.*; public class JVMClass { @@ -54,6 +55,12 @@ public static void generateDTS(PrintWriter writer, String fqcn) { return; } + JsonObject includes = getIncludes(getSimpleName(clazz)); + + if (includes.containsKey("import")) { + writer.printf("%s\n", includes.getString("import")); + } + boolean isInterface = clazz.isInterface(); boolean isAbstract = !clazz.isInterface() && Modifier.isAbstract(clazz.getModifiers()); diff --git a/codegen/src/main/java/io/reactiverse/es4x/codegen/generator/OptionsDTS.java b/codegen/src/main/java/io/reactiverse/es4x/codegen/generator/OptionsDTS.java index 8cfd687de..1f86af1a9 100644 --- a/codegen/src/main/java/io/reactiverse/es4x/codegen/generator/OptionsDTS.java +++ b/codegen/src/main/java/io/reactiverse/es4x/codegen/generator/OptionsDTS.java @@ -119,12 +119,11 @@ public String render(DataObjectModel model, int index, int size, Map") ? " implements " + includes.getString("dataObjectImplements") : ""); if (model.hasEmptyConstructor()) { writer.print(" constructor();\n\n"); @@ -167,6 +166,10 @@ public String render(DataObjectModel model, int index, int size, Map session) { if (model instanceof EnumModel) { - session.putIfAbsent("enum", "seen"); + session.putIfAbsent("enums", "seen"); } if (model instanceof ClassModel) { @@ -71,28 +71,34 @@ public String render(Model model, int index, int size, Map sessi if (session.containsKey("index")) { /* always overwritten */ json.put("main", "index.js"); - json.put("module", "index.mjs"); json.put("types", "index.d.ts"); } + boolean isModule = false; + // generate exports for bundlers/cdn's - if (session.containsKey("index") || session.containsKey("enum") || session.containsKey("options")) { + if (session.containsKey("index") || session.containsKey("enums") || session.containsKey("options")) { + isModule = true; JsonObject exports = new JsonObject(); if (session.containsKey("index")) { exports.put(".", "./index.mjs"); exports.put("./index", "./index.mjs"); } - if (session.containsKey("enum")) { - exports.put("./enum", "./enum.mjs"); + if (session.containsKey("enums")) { + exports.put("./enums", "./enums.mjs"); } - if (session.containsKey("index")) { + if (session.containsKey("options")) { exports.put("./options", "./options.mjs"); } json.put("exports", exports); } + if (isModule) { + json.put("type", "module"); + } + // extras json.put("sideEffects", false); diff --git a/codegen/src/main/java/io/reactiverse/es4x/codetrans/EcmaScript.java b/codegen/src/main/java/io/reactiverse/es4x/codetrans/EcmaScript.java new file mode 100644 index 000000000..87eda4361 --- /dev/null +++ b/codegen/src/main/java/io/reactiverse/es4x/codetrans/EcmaScript.java @@ -0,0 +1,27 @@ +package io.reactiverse.es4x.codetrans; + +import io.vertx.codetrans.CodeBuilder; +import io.vertx.codetrans.Lang; +import io.vertx.codetrans.Script; + +public class EcmaScript implements Lang { + @Override + public String id() { + return "es4x"; + } + + @Override + public Script loadScript(ClassLoader classLoader, String s, String s1) throws Exception { + throw new UnsupportedOperationException(); + } + + @Override + public String getExtension() { + return "js"; + } + + @Override + public CodeBuilder codeBuilder() { + return new EcmaScriptCodeBuilder(); + } +} diff --git a/codegen/src/main/java/io/reactiverse/es4x/codetrans/EcmaScriptCodeBuilder.java b/codegen/src/main/java/io/reactiverse/es4x/codetrans/EcmaScriptCodeBuilder.java new file mode 100644 index 000000000..0163185c2 --- /dev/null +++ b/codegen/src/main/java/io/reactiverse/es4x/codetrans/EcmaScriptCodeBuilder.java @@ -0,0 +1,124 @@ +package io.reactiverse.es4x.codetrans; + +import com.sun.source.tree.LambdaExpressionTree; +import io.vertx.codegen.type.*; +import io.vertx.codetrans.*; +import io.vertx.codetrans.expression.*; +import io.vertx.codetrans.statement.StatementModel; + +import java.util.Collections; +import java.util.LinkedHashSet; + +import static io.reactiverse.es4x.codegen.generator.Util.getNPMScope; + +class EcmaScriptCodeBuilder implements CodeBuilder { + + LinkedHashSet modules = new LinkedHashSet<>(); + + @Override + public CodeWriter newWriter() { + return new EcmaScriptWriter(this); + } + + @Override + public String render(RunnableCompilationUnit unit, RenderMode renderMode) { + CodeWriter writer = newWriter(); + for (ClassTypeInfo module : modules) { + writer + .append("import { ") + .append(module.getSimpleName()) + .append(" } from \"") + .append( getNPMScope(module.getModule())); + + switch (module.getKind()) { + case API: + writer.append("/index"); + break; + case OTHER: + if (module.isVariable()) { + writer.append("/options"); + break; + } + case ENUM: + writer.append("/enums"); + break; + } + + writer + .append("\"\n"); + } + unit.getMain().render(writer); + return writer.getBuffer().toString(); + } + + @Override + public ApiTypeModel apiType(ApiTypeInfo type) { + modules.add(type); + return CodeBuilder.super.apiType(type); + } + + @Override + public ExpressionModel toDataObjectValue(EnumFieldExpressionModel enumField) { + return new StringLiteralModel(this, enumField.identifier); + } + + @Override + public ExpressionModel asyncResultHandler(LambdaExpressionTree.BodyKind bodyKind, ParameterizedTypeInfo resultType, String resultName, CodeModel body, CodeModel succeededBody, CodeModel failedBody) { + return new LambdaExpressionModel(this, bodyKind, Collections.singletonList(resultType), Collections.singletonList(resultName), body); + } + + @Override + public StatementModel variableDecl(VariableScope scope, TypeInfo type, String name, ExpressionModel initializer) { + return StatementModel.render(renderer -> { + renderer.append("let ").append(name); + if (initializer != null) { + renderer.append(" = "); + initializer.render(renderer); + } + }); + } + + @Override + public StatementModel enhancedForLoop(String variableName, ExpressionModel expression, StatementModel body) { + return StatementModel.render((renderer) -> { + expression.render(renderer); + renderer.append(".forEach(").append(variableName).append(" => {\n"); + renderer.indent(); + body.render(renderer); + renderer.unindent(); + renderer.append("})"); + }); + } + + @Override + public StatementModel forLoop(StatementModel initializer, ExpressionModel condition, ExpressionModel update, StatementModel body) { + return StatementModel.conditional((renderer) -> { + renderer.append("for ("); + initializer.render(renderer); + renderer.append("; "); + condition.render(renderer); + renderer.append("; "); + update.render(renderer); + renderer.append(") {\n"); + renderer.indent(); + body.render(renderer); + renderer.unindent(); + renderer.append("}"); + }); + } + + @Override + public StatementModel sequenceForLoop(String variableName, ExpressionModel fromValue, ExpressionModel toValue, StatementModel body) { + return StatementModel.conditional((renderer) -> { + renderer.append("for (let ").append(variableName).append(" = "); + fromValue.render(renderer); + renderer.append(";").append(variableName).append(" < "); + toValue.render(renderer); + renderer.append(";").append(variableName).append("++) {\n"); + renderer.indent(); + body.render(renderer); + renderer.unindent(); + renderer.append("}"); + }); + } +} diff --git a/codegen/src/main/java/io/reactiverse/es4x/codetrans/EcmaScriptWriter.java b/codegen/src/main/java/io/reactiverse/es4x/codetrans/EcmaScriptWriter.java new file mode 100644 index 000000000..2225b03f6 --- /dev/null +++ b/codegen/src/main/java/io/reactiverse/es4x/codetrans/EcmaScriptWriter.java @@ -0,0 +1,466 @@ +package io.reactiverse.es4x.codetrans; + +import com.sun.source.tree.LambdaExpressionTree; +import io.vertx.codegen.type.ApiTypeInfo; +import io.vertx.codegen.type.ClassTypeInfo; +import io.vertx.codegen.type.EnumTypeInfo; +import io.vertx.codegen.type.TypeInfo; +import io.vertx.codetrans.CodeModel; +import io.vertx.codetrans.CodeWriter; +import io.vertx.codetrans.MethodSignature; +import io.vertx.codetrans.TypeArg; +import io.vertx.codetrans.expression.*; +import io.vertx.codetrans.statement.StatementModel; + +import javax.lang.model.element.TypeElement; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.IntStream; + +class EcmaScriptWriter extends CodeWriter { + + final EcmaScriptCodeBuilder builder; + + EcmaScriptWriter(EcmaScriptCodeBuilder builder) { + super(builder); + this.builder = builder; + } + + private String capitalize(String string) { + return string.substring(0, 1).toUpperCase() + string.substring(1); + } + + @Override + public void renderBinary(BinaryExpressionModel expression) { + ExpressionModel left = expression.getLeft(); + ExpressionModel right = expression.getRight(); + String op = expression.getOp(); + switch (op) { + case "==": + op = "==="; + if (right instanceof NullLiteralModel) { + ExpressionModel tmp = right; + right = left; + left = tmp; + } + if (left instanceof NullLiteralModel) { + // Todo find a way to suppress these when not needed i.e (( xxx )) + append("("); + right.render(this); + append(" === null || "); + right.render(this); + append(" === undefined)"); + return; + } + break; + case "!=": + if (right instanceof NullLiteralModel) { + ExpressionModel tmp = right; + right = left; + left = tmp; + } + if (left instanceof NullLiteralModel) { + // Todo find a way to suppress these when not needed i.e (( xxx )) + append("("); + right.render(this); + append(" !== null && "); + right.render(this); + append(" !== undefined)"); + return; + } + op = "!=="; + break; + } + super.renderBinary(new BinaryExpressionModel(builder, expression.getLeft(), op, expression.getRight())); + } + + @Override + public void renderStatement(StatementModel statement) { + statement.render(this); + // In javascript, conditional structure should not have an ending ;. This generates an empty instruction. + if (statement instanceof StatementModel.Expression) { + append(";"); + } + append("\n"); + } + + @Override + public void renderTryCatch(StatementModel tryBlock, StatementModel catchBlock) { + append("try {\n"); + indent(); + tryBlock.render(this); + unindent(); + append("} catch(err) {\n"); + indent(); + catchBlock.render(this); + unindent(); + append("}\n"); + } + + @Override + public void renderThis() { + append("this"); + } + + @Override + public void renderNewMap() { + append("{}"); + } + + @Override + public void renderNewList() { + append("[]"); + } + + public void renderDataObject(DataObjectLiteralModel model) { + append("new ").append(model.getType().getSimpleName()).append("()"); + boolean dataModelHasMembers = model.getMembers().iterator().hasNext(); + if (dataModelHasMembers) { + append("\n"); + indent(); + } + final AtomicBoolean needsNL = new AtomicBoolean(); + model.getMembers().forEach(member -> { + if (needsNL.get()) { + append("\n"); + } + append(".set").append(capitalize(member.getName())).append("("); + if (member instanceof Member.Single) { + ((Member.Single) member).getValue().render(this); + } else if (member instanceof Member.Sequence) { + append("["); + IntStream.range(0, ((Member.Sequence) member).getValues().size()).forEach(i -> { + if (i > 0) + append(", "); + ((Member.Sequence) member).getValues().get(i).render(this); + }); + append("]"); + } else if (member instanceof Member.Entries) { + append("todo-renderDataObject-entries"); + } + append(")"); + needsNL.set(true); + }); + if (dataModelHasMembers) { + unindent(); + } + } + + @Override + public void renderDataObjectToJson(IdentifierModel model) { + model.render(this); + } + + @Override + public void renderToDataObject(JsonObjectModel model, ClassTypeInfo type) { + model.render(this); + } + + public void renderJsonObject(JsonObjectLiteralModel jsonObject) { + renderJsonObject(jsonObject.getMembers()); + } + + public void renderJsonArray(JsonArrayLiteralModel jsonArray) { + renderJsonArray(jsonArray.getValues()); + } + + private void renderJsonObject(Iterable members) { + append("{\n"); + indent(); + for (Iterator iterator = members.iterator(); iterator.hasNext(); ) { + Member member = iterator.next(); + String name = member.getName(); + append("\""); + renderChars(name); + append("\" : "); + if (member instanceof Member.Single) { + ((Member.Single) member).getValue().render(this); + } else if (member instanceof Member.Sequence) { + renderJsonArray(((Member.Sequence) member).getValues()); + } else if (member instanceof Member.Entries) { + renderJsonObject(((Member.Entries) member).entries()); + } + if (iterator.hasNext()) { + append(','); + } + append('\n'); + } + unindent().append("}"); + } + + private void renderJsonArray(List values) { + append("[\n").indent(); + for (int i = 0; i < values.size(); i++) { + values.get(i).render(this); + if (i < values.size() - 1) { + append(','); + } + append('\n'); + } + unindent().append(']'); + } + + @Override + public void renderJsonObjectAssign(ExpressionModel expression, String name, ExpressionModel value) { + expression.render(this); + append('.'); + append(name); + append(" = "); + value.render(this); + } + + @Override + public void renderJsonArrayAdd(ExpressionModel expression, ExpressionModel value) { + expression.render(this); + append(".push("); + value.render(this); + append(")"); + } + + @Override + public void renderDataObjectAssign(ExpressionModel expression, String name, ExpressionModel value) { + renderJsonObjectAssign(expression, name, value); + } + + @Override + public void renderJsonObjectMemberSelect(ExpressionModel expression, Class type, String name) { + expression.render(this); + append('.'); + append(name); + } + + @Override + public void renderJsonObjectToString(ExpressionModel expression) { + append("JSON.stringify("); + expression.render(this); + append(")"); + } + + @Override + public void renderJsonArrayToString(ExpressionModel expression) { + append("JSON.stringify("); + expression.render(this); + append(")"); + } + + @Override + public void renderDataObjectMemberSelect(ExpressionModel expression, String name) { + renderJsonObjectMemberSelect(expression, Object.class, name); + } + + @Override + public void renderJsonObjectSize(ExpressionModel expression) { + append("Object.keys("); + expression.render(this); + append(").length"); + } + + @Override + public void renderJsonArraySize(ExpressionModel expression) { + expression.render(this); + append(".length"); + } + + @Override + public void renderLambda(LambdaExpressionTree.BodyKind bodyKind, List parameterTypes, List parameterNames, CodeModel body) { + append("("); + for (int i = 0; i < parameterNames.size(); i++) { + if (i > 0) { + append(", "); + } + append(parameterNames.get(i)); + } + append(") => {\n"); + indent(); + body.render(this); + if (bodyKind == LambdaExpressionTree.BodyKind.EXPRESSION) { + append(";\n"); + } + unindent(); + append("}"); + } + + @Override + public void renderEnumConstant(EnumTypeInfo type, String constant) { + append(type.getSimpleName()).append('.').append(constant); + } + + @Override + public void renderThrow(String throwableType, ExpressionModel reason) { + if (reason == null) { + append("throw ").append("\"an error occurred\""); + } else { + append("throw "); + reason.render(this); + } + } + + @Override + public void renderSystemOutPrintln(ExpressionModel expression) { + append("console.log("); + expression.render(this); + append(")"); + } + + @Override + public void renderSystemErrPrintln(ExpressionModel expression) { + append("console.error("); + expression.render(this); + append(")"); + } + + @Override + public void renderListAdd(ExpressionModel list, ExpressionModel value) { + list.render(this); + append(".push("); + value.render(this); + append(")"); + } + + @Override + public void renderListSize(ExpressionModel list) { + list.render(this); + append(".length"); + } + + @Override + public void renderListGet(ExpressionModel list, ExpressionModel index) { + list.render(this); + append("["); + index.render(this); + append("]"); + } + + @Override + public void renderListLiteral(List arguments) { + append("["); + for (Iterator it = arguments.iterator(); it.hasNext(); ) { + it.next().render(this); + if (it.hasNext()) { + append(", "); + } + } + append("]"); + } + + @Override + public void renderNewArray(String s, List list) { + renderListLiteral(list); + } + + @Override + public void renderMapGet(ExpressionModel map, ExpressionModel key) { + map.render(this); + append('['); + key.render(this); + append(']'); + } + + @Override + public void renderMapPut(ExpressionModel map, ExpressionModel key, ExpressionModel value) { + map.render(this); + append('['); + key.render(this); + append("] = "); + value.render(this); + } + + @Override + public void renderMapForEach(ExpressionModel map, String keyName, TypeInfo keyType, String valueName, TypeInfo valueType, LambdaExpressionTree.BodyKind bodyKind, CodeModel block) { + map.render(this); + append(".forEach("); + renderLambda(bodyKind, Arrays.asList(valueType, keyType), Arrays.asList(valueName, keyName), block); + append(")"); + } + + @Override + public void renderMethodReference(ExpressionModel expression, MethodSignature signature) { + if (!(expression instanceof ThisModel)) { + expression.render(this); + append('.'); + } + append(signature.getName()); + } + + @Override + public void renderApiType(ApiTypeInfo apiType) { + append(apiType.getSimpleName()); + } + + @Override + public void renderJavaType(ClassTypeInfo javaType) { + append("Java.type(\"").append(javaType.getName()).append("\")"); + } + + @Override + public void renderAsyncResultSucceeded(TypeInfo resultType, String name) { + append(name).append(".succeeded()"); + } + + @Override + public void renderAsyncResultFailed(TypeInfo resultType, String name) { + append(name).append(".failed()"); + } + + @Override + public void renderAsyncResultCause(TypeInfo resultType, String name) { + append(name).append(".cause()"); + } + + @Override + public void renderAsyncResultValue(TypeInfo resultType, String name) { + append(name).append(".result()"); + } + + @Override + public void renderMethodInvocation(ExpressionModel expression, TypeInfo receiverType, MethodSignature method, TypeInfo returnType, List typeArguments, List argumentModels, List argumentTypes) { + List parameterTypes = method.getParameterTypes(); + for (int i = 0; i < parameterTypes.size(); i++) { + TypeInfo parameterType = parameterTypes.get(i); + TypeInfo argumentType = argumentTypes.get(i); + if (io.vertx.codetrans.Helper.isHandler(parameterType) && io.vertx.codetrans.Helper.isInstanceOfHandler(argumentType)) { + ExpressionModel expressionModel = argumentModels.get(i); + argumentModels.set(i, builder.render(expressionModel::render)); + } + } + + // + if (!(expression instanceof ThisModel)) { + expression.render(this); + append('.'); + } + append(method.getName()); + append('('); + for (int i = 0; i < argumentModels.size(); i++) { + if (i > 0) { + append(", "); + } + argumentModels.get(i).render(this); + } + append(')'); + } + + @Override + public void renderNew(ExpressionModel expression, TypeInfo type, List argumentModels) { + append("new ("); + expression.render(this); + append(")"); + append('('); + for (int i = 0; i < argumentModels.size(); i++) { + if (i > 0) { + append(", "); + } + argumentModels.get(i).render(this); + } + append(')'); + } + + @Override + public void renderInstanceOf(ExpressionModel expression, TypeElement type) { + expression.render(this); + append(" instanceof "); + append(type.getSimpleName()); + } +} diff --git a/codegen/src/main/java/io/reactiverse/es4x/docgen/generator/ES4XDocGenerator.java b/codegen/src/main/java/io/reactiverse/es4x/docgen/generator/ES4XDocGenerator.java new file mode 100644 index 000000000..e184e7cc9 --- /dev/null +++ b/codegen/src/main/java/io/reactiverse/es4x/docgen/generator/ES4XDocGenerator.java @@ -0,0 +1,121 @@ +package io.reactiverse.es4x.docgen.generator; + +import io.reactiverse.es4x.codetrans.EcmaScript; +import io.vertx.codegen.annotations.VertxGen; +import io.vertx.codegen.type.*; +import io.vertx.codetrans.CodeTranslator; +import io.vertx.docgen.DocGenerator; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.*; +import javax.lang.model.util.Elements; +import javax.lang.model.util.Types; + +import static io.reactiverse.es4x.codegen.generator.Util.getNPMScope; + +public class ES4XDocGenerator implements DocGenerator { + + private CodeTranslator translator; + private Elements elementUtils; + private Types typeUtils; + + @Override + public void init(ProcessingEnvironment processingEnv) { + translator = new CodeTranslator(processingEnv); + elementUtils = processingEnv.getElementUtils(); + typeUtils = processingEnv.getTypeUtils(); + } + + @Override + public String getName() { + return "js"; + } + + @Override + public String renderSource(ExecutableElement elt, String source) { + try { + return translator.translate(elt, new EcmaScript()); + } catch (Exception e) { + System.out.println("Cannot generate " + elt.getEnclosingElement().getSimpleName() + "#" + elt.getSimpleName() + " : " + e.getMessage()); + return "Code not translatable"; + } + } + + @Override + public String resolveTypeLink(TypeElement elt) { + try { + TypeMirrorFactory factory = new TypeMirrorFactory(elementUtils, typeUtils); + TypeInfo type = factory.create(elt.asType()); + + String baselink = getNPMScope(type.getRaw().getModule()); + String kind; + + switch (type.getKind()) { + case ENUM: + kind = "enums"; + break; + case HANDLER: + case ASYNC_RESULT: + kind = "interfaces"; + break; + case API: + boolean concrete = elt.getAnnotation(VertxGen.class) == null || elt.getAnnotation(VertxGen.class).concrete(); + if (concrete) { + kind = "classes"; + } else { + kind = "interfaces"; + } + break; + case OTHER: + if (type.isVariable()) { + kind = "classes"; + break; + } + return null; + default: + System.err.println("Could not resolve doc link for kind " + type.getKind()); + return null; + } + + return "/es4x/" + baselink + "/" + kind + "/" + elt.getSimpleName().toString().toLowerCase() + ".html"; + } catch (Exception e) { + System.out.println("Could not resolve doc link for type " + elt.getQualifiedName() + ": " + e.getMessage()); + return null; + } + } + + @Override + public String resolveMethodLink(ExecutableElement elt) { + TypeElement typeElt = (TypeElement) elt.getEnclosingElement(); + String link = resolveTypeLink(typeElt); + if (link != null) { + link += '#' + elt.getSimpleName().toString().toLowerCase(); + } + return link; + } + + @Override + public String resolveLabel(Element elt, String defaultLabel) { + return defaultLabel; + } + + @Override + public String resolveConstructorLink(ExecutableElement elt) { + TypeElement typeElt = (TypeElement) elt.getEnclosingElement(); + String link = resolveTypeLink(typeElt); + if (link != null) { + link += '#' + elt.getSimpleName().toString().toLowerCase(); + } + return link; + } + + @Override + public String resolveFieldLink(VariableElement elt) { + TypeElement typeElt = (TypeElement) elt.getEnclosingElement(); + String link = resolveTypeLink(typeElt); + if (link != null) { + link += '#' + elt.getSimpleName().toString().toLowerCase(); + } + return link; + } +} diff --git a/codegen/src/main/resources/META-INF/services/io.vertx.docgen.DocGenerator b/codegen/src/main/resources/META-INF/services/io.vertx.docgen.DocGenerator new file mode 100644 index 000000000..a2ef334d4 --- /dev/null +++ b/codegen/src/main/resources/META-INF/services/io.vertx.docgen.DocGenerator @@ -0,0 +1 @@ +io.reactiverse.es4x.docgen.generator.ES4XDocGenerator diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 409ef9fd1..5966406c4 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -132,7 +132,8 @@ module.exports = { 'worker', 'jars', 'security', - 'logging' + 'logging', + 'codegen' ] } ], diff --git a/docs/advanced/codegen.md b/docs/advanced/codegen.md new file mode 100644 index 000000000..00097def8 --- /dev/null +++ b/docs/advanced/codegen.md @@ -0,0 +1,343 @@ +# Code Generation + +`es4x` works with vert.x code generation. Vert.x code generation is an annotation processing tool that extracts metadata +from the java source code and allows other projects such as `es4x` to generate other sources. + +A typical code generation process will generate the following files: + +* `package.json` a module descriptor with references to java artifacts and/or other js dependencies +* `README.md` a simple read me +* `index.js` a commonjs style script exporting all the annotated java interfaces +* `index.mjs` a ES6 module script exporting all the annotated java interfaces +* `index.d.ts` a typescript definition file with all the annotated java interfaces +* `options.js` a commonjs style script exporting all the annotated java data objects +* `options.mjs` a ES6 module script exporting all the annotated java data objects +* `options.d.ts` a typescript definition file with all the annotated data objects +* `enums.js` a commonjs style script exporting all the annotated java enums +* `enums.mjs` a ES6 module script exporting all the annotated java enums +* `enums.d.ts` a typescript definition file with all the annotated java enums +* `mod.js` a single ES6 module re-exporting `index.mjs`, `options.mjs` and `enums.mjs` from a single source + +At the moment the current generation of code is driven by a `maven` build. The process can be seen as a sub module of +a maven build defined as usual by a `pom.xml` file. + +## Code generating a vert.x module for es4x + +For this example, let's consider the module [hot-reload](https://github.com/pmlopes/hot-reload). The module is a vertx +codegen module if the APIs follow the codegen restrictions and interfaces are annotated with `@VertxGen` like in this +interface [HotReload.java](https://github.com/pmlopes/hot-reload/blob/master/src/main/java/xyz/jetdrone/vertx/hot/reload/HotReload.java) + +::: warning +Sometimes codegen seem not to be working because a top level `package-info.java` file is missing. Don't forget that file +it is required to get the annotation processor to run. +::: + +In order to generate an `es4x` module for this component all we need is a `pom.xml` which should look like this: + +```xml + + + + 4.0.0 + + + io.reactiverse.es4x + es4x-generator + 0.15.1-SNAPSHOT + ../.. + + + hot-reload + 0.15.1-SNAPSHOT + + jar + + + xyz.jetdrone + 0.0.5 + false + + + { + "@vertx/web": "${stack.version}" + } + + + + + + + io.vertx + vertx-web + ${stack.version} + true + + + + ${maven.groupId} + ${project.artifactId} + ${npm-version} + + + ${maven.groupId} + ${project.artifactId} + ${npm-version} + provided + sources + + + + +``` + +The `artifactId` should be the same as the one we want to generate the `es4x` module. In this example the original +module has the following coordinates: + +```xml +xyz.jetdrone +hot-reload +0.0.5 +``` + +From here, there are several properties you need to declare, not all of them are required and some already have been +prefilled here's the list: + +```xml +${project.parent.version} + +io.vertx + +true +latest +true +true + + + + [ + { + "group": "io.vertx", + "prefix": "vertx-", + "scope": "vertx", + "stripPrefix": true + }, + { + "group": "io.vertx", + "module": "vertx", + "name": "core", + "scope": "vertx" + }, + { + "group": "io.vertx", + "module": "vertx-jdbc", + "name": "jdbc-client", + "scope": "vertx" + }, + { + "group": "io.vertx", + "module": "vertx-mongo", + "name": "mongo-client", + "scope": "vertx" + }, + { + "group": "io.vertx", + "module": "vertx-redis", + "name": "redis-client", + "scope": "vertx" + }, + { + "group": "io.vertx", + "module": "vertx-sql", + "name": "jdbc-client", + "scope": "vertx" + }, + { + "group": "io.reactiverse", + "scope": "reactiverse" + } + ] + + + +${project.artifactId} +${project.version} +Apache-2.0 + +https://registry.npmjs.org + + + + { + "@vertx/core": "${stack.version}" + } + + +{} + + + { + "name": "${npm-name}", + "description": "${project.description}", + "version": "${npm-version}", + "license": "${npm-license}", + "public": true, + "maven": { + "groupId": "${maven.groupId}", + "artifactId": "${project.artifactId}", + "version": "${npm-version}" + }, + "dependencies": ${npm-dependencies}, + "devDependencies": ${npm-dev-dependencies} + } + + +[] + +[] + +{} + +https://github.com/reactiverse/es4x.git +/generator/${maven.groupId}/${project.artifactId} +``` + +Finally you need to go over the dependencies section. There are 2 dependencies you always need to have: + +```xml + + ${maven.groupId} + ${project.artifactId} + ${npm-version} + + + ${maven.groupId} + ${project.artifactId} + ${npm-version} + provided + sources + +``` + +The final artifact and the artifact source jar. Using the artifact we can compute the dependencies so we can ensure that +the annotation processor can work outside the source project, but there are cases like in this example where optional +dependencies are listed. If such dependencies are used, they need to be re-declared in the pom like in the example +above. + +## Running the generation + +Running the generation is a typical maven phase (`generate-sources`) so all you need is: + +```shell +~/ $ mvn clean generate-sources + +[INFO] Scanning for projects... +[INFO] +[INFO] -------------------< io.reactiverse.es4x:hot-reload >------------------- +[INFO] Building hot-reload 0.15.1-SNAPSHOT +[INFO] --------------------------------[ jar ]--------------------------------- +[INFO] +[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ hot-reload --- +[INFO] Deleting /home/paulo/Projects/reactiverse/es4x/generator/xyz.jetdrone/hot-reload/target +[INFO] +[INFO] --- maven-enforcer-plugin:1.4.1:enforce (enforce-maven) @ hot-reload --- +[INFO] +[INFO] --- properties-maven-plugin:1.0.0:set-system-properties (default) @ hot-reload --- +[INFO] Set 8 system properties +[INFO] +[INFO] --- maven-dependency-plugin:3.2.0:unpack-dependencies (unpack-sources) @ hot-reload --- +[INFO] Unpacking /home/paulo/.m2/repository/xyz/jetdrone/hot-reload/0.0.6/hot-reload-0.0.6-sources.jar to /home/paulo/Projects/reactiverse/es4x/generator/xyz.jetdrone/hot-reload/target/sources/hot-reload with includes "**/*.java" and excludes "**/examples/**/*.*,**/*-examples/**/*.*,**/groovy/**/*.*,**/rxjava/**/*.*,**/reactivex/**/*.*" +[INFO] +[INFO] --- maven-processor-plugin:4.5-jdk8:process (generate-api) @ hot-reload --- +[WARNING] diagnostic: warning: [options] bootstrap class path not set in conjunction with -source 8 +[INFO] diagnostic: Note: Loaded es4x-generator (index.js) code generator +[INFO] diagnostic: Note: Loaded es4x-generator (options.js) code generator +[INFO] diagnostic: Note: Loaded es4x-generator (enum.js) code generator +[INFO] diagnostic: Note: Loaded es4x-generator (index.d.ts) code generator +[INFO] diagnostic: Note: Loaded es4x-generator (options.d.ts) code generator +[INFO] diagnostic: Note: Loaded es4x-generator (enum.d.ts) code generator +[INFO] diagnostic: Note: Loaded es4x-generator (index.mjs) code generator +[INFO] diagnostic: Note: Loaded es4x-generator (options.mjs) code generator +[INFO] diagnostic: Note: Loaded es4x-generator (enum.mjs) code generator +[INFO] diagnostic: Note: Loaded es4x-generator (package.json) code generator +[INFO] diagnostic: Note: Loaded es4x-generator (README.md) code generator +[INFO] diagnostic: Note: Loaded es4x-generator (mod.js) code generator +[INFO] diagnostic: Note: Loaded data_object_converters code generator +[INFO] diagnostic: Note: Generated model xyz.jetdrone.vertx.hot.reload.HotReload: npm/index.d.ts +[INFO] diagnostic: Note: Generated model xyz.jetdrone.vertx.hot.reload.HotReload: npm/package.json +[INFO] diagnostic: Note: Generated model xyz.jetdrone.vertx.hot.reload.HotReload: npm/index.js +[INFO] diagnostic: Note: Generated model xyz.jetdrone.vertx.hot.reload.HotReload: npm/mod.js +[INFO] diagnostic: Note: Generated model xyz.jetdrone.vertx.hot.reload.HotReload: npm/index.mjs +[INFO] diagnostic: Note: Generated model xyz.jetdrone.vertx.hot.reload.HotReload: npm/README.md +[WARNING] diagnostic: warning: Unclosed files for the types 'PathForCodeGenProcessor'; these types will not undergo annotation processing +[INFO] +[INFO] --- maven-resources-plugin:3.2.0:copy-resources (copy-extras) @ hot-reload --- +[INFO] Using 'UTF-8' encoding to copy filtered resources. +[INFO] Using 'UTF-8' encoding to copy filtered properties files. +[INFO] skip non existing resourceDirectory /home/paulo/Projects/reactiverse/es4x/generator/xyz.jetdrone/hot-reload/extra +[INFO] ------------------------------------------------------------------------ +[INFO] BUILD SUCCESS +[INFO] ------------------------------------------------------------------------ +[INFO] Total time: 2.371 s +[INFO] Finished at: 2021-09-10T21:32:03+02:00 +[INFO] ------------------------------------------------------------------------ +~/Projects/reactiverse/es4x/generator/xyz.jetdrone/hot-reload (develop)$ +``` + +## Working around limitations + +Codegen is a great tool but sometimes is is very hard to get it to work for all cases. For this `es4x` codegen plugin +has several workarounds to allow you to quickly hack your desired output without having to write code. + +### Adding code to a generated file + +You can either add code to the beginning or to the end of each generated file. At the same level of your `pom.xml` add +a file `{index|options|enums|...}.header.{js|mjs|.d.ts}` and it's content will be prepended to the generated file. + +The same can be done to the end of the generated files, use the following format: `{index|options|enums|...}.footer.{js|mjs|.d.ts}`. + +For example, vert.x core doesn't annotate the types `JsonObject` and `JsonArray` so in order to expose them in core we +have a file `module.header.mjs` with the following content: + +```js +export const AsyncResult = Java.type('io.vertx.core.AsyncResult'); +export const JsonObject = Java.type('io.vertx.core.json.JsonObject'); +export const JsonArray = Java.type('io.vertx.core.json.JsonArray'); +``` + +The same can be done to a specific type. For example, `HttpMethod` isn't fully annotated so we include the default +methods to right interface during the `index.d.ts` file generation by creating an includes file `HttpMethod.includes.json`. + +```json +{ + "d.ts": " /**\n * The RFC 2616 {@code OPTIONS} method, this instance is interned and uniquely us..." +} +``` + +The key identifies the kind of generation template where the inclusion should happen. + +::: warning +Exclusions can also be done using `.excludes.json` file name suffix. +::: + +## Overriding + +Just like inclusion and exclusion, we can also override method parameters or even return types using the file name +suffix `.override.json`, for example, `CompositeFuture` codegen doesn't handle some overloads correctly so we can +define an overrides file as: + +```json +{ + "cause": "index?: number", + "succeeded": "index?: number", + "failed": "index?: number", + "isComplete": "index?: number", + "setHandler": { + "return": "Future" + } +} +``` + +This allows as to define an optional argument `index` to several methods and override the return type for `setHandler` +to comply to typescript restrictions. diff --git a/docs/get-started/hello-world.md b/docs/get-started/hello-world.md index e75b381cb..d4acd09ea 100644 --- a/docs/get-started/hello-world.md +++ b/docs/get-started/hello-world.md @@ -121,14 +121,14 @@ In order to get code completion on [Visual Studio Code](https://code.visualstudi script should be: ```js -/// +/// ``` ::: The hello application `index.js` should be like: ```js{1-2} -/// +/// // @ts-check import { Router } from '@vertx/web'; diff --git a/docs/get-started/install.md b/docs/get-started/install.md index 7066cf186..a4c69bdaa 100644 --- a/docs/get-started/install.md +++ b/docs/get-started/install.md @@ -24,13 +24,13 @@ Using `jabba` you can install `openjdk 11` and/or `graalvm` (once) as: ```bash jabba install openjdk@1.11.0 -jabba install graalvm@20.2.0 +jabba install graalvm@21.3.0 ``` And later switch to the desired runtime by executing: ```bash -jabba use openjdk@1.11 # OR jabba use graalvm@20.2 +jabba use openjdk@1.11 # OR jabba use graalvm@21.2 ``` ::: @@ -63,7 +63,7 @@ When working on CI environments where the amount of packages is limited, the pac unzipping the prepackaged tar/zip file. ```bash -ES4X='0.9.0' \ +ES4X='0.16.0' \ curl -sL \ https://github.com/reactiverse/es4x/releases/download/$ES4X/es4x-pm-$ES4X-bin.tar.gz \ | tar zx --strip-components=1 -C /usr/local diff --git a/es4x/pom.xml b/es4x/pom.xml index def40a774..6f929ba4b 100644 --- a/es4x/pom.xml +++ b/es4x/pom.xml @@ -4,14 +4,14 @@ io.reactiverse es4x-parent - 0.15.0 + 0.16.0 .. 4.0.0 es4x - 0.15.0 + 0.16.0 UTF-8 diff --git a/es4x/src/main/java/io/reactiverse/es4x/ECMAEngine.java b/es4x/src/main/java/io/reactiverse/es4x/ECMAEngine.java index bb63e2070..d5b57fdd4 100644 --- a/es4x/src/main/java/io/reactiverse/es4x/ECMAEngine.java +++ b/es4x/src/main/java/io/reactiverse/es4x/ECMAEngine.java @@ -17,6 +17,7 @@ import io.netty.buffer.Unpooled; import io.reactiverse.es4x.impl.JSObjectMessageCodec; +import io.reactiverse.es4x.impl.SetContainer; import io.reactiverse.es4x.jul.ANSIFormatter; import io.vertx.core.Future; import io.vertx.core.Promise; @@ -36,15 +37,12 @@ import java.util.function.Function; import java.util.logging.ConsoleHandler; import java.util.logging.Handler; -import java.util.logging.Logger; import java.util.regex.Pattern; import static io.reactiverse.es4x.impl.AsyncError.parseStrackTraceElement; public final class ECMAEngine { - private static final Logger LOG = Logger.getLogger(ECMAEngine.class.getName()); - private static Pattern[] allowedHostClassFilters() { String hostClassFilter = System.getProperty("es4x.host.class.filter", System.getenv("ES4XHOSTCLASSFILTER")); if (hostClassFilter == null || hostClassFilter.length() == 0) { @@ -89,7 +87,6 @@ private static Pattern[] allowedHostClassFilters() { // lazy install the codec private final AtomicBoolean codecInstalled = new AtomicBoolean(false); - private static boolean nag = true; public ECMAEngine(Vertx vertx) { this.vertx = vertx; @@ -105,13 +102,6 @@ public ECMAEngine(Vertx vertx) { throw new IllegalStateException("A language with id 'js' is not installed"); } - if (nag) { - nag = false; - if ("Interpreted".equalsIgnoreCase(engine.getImplementationName())) { - LOG.warning("ES4X is using graaljs in interpreted mode! Add the JVMCI compiler module in order to run in optimal mode!"); - } - } - // enable or disable the polyglot access polyglotAccess = Boolean.getBoolean("es4x.no-polyglot-access") ? PolyglotAccess.NONE : PolyglotAccess.ALL; @@ -126,9 +116,6 @@ public ECMAEngine(Vertx vertx) { .buildLiteral(); hostAccess = HostAccess.newBuilder(HostAccess.ALL) - // temp workaround for 21.1.0 regression - .allowBufferAccess(true) - /// Highest Precedence /// accepts is null, so we can quickly assert the type @@ -182,7 +169,7 @@ public ECMAEngine(Vertx vertx) { v -> v.get("then") instanceof Function, v -> { final Promise promise = ((VertxInternal) vertx).promise(); - ((Function) v.get("then")).apply(new Object[] { + ((Function) v.get("then")).apply(new Object[]{ (Consumer) promise::complete, (Consumer) failure -> { if (failure instanceof Throwable) { @@ -190,7 +177,7 @@ public ECMAEngine(Vertx vertx) { } else { if (failure instanceof Map) { // this happens when JS error messages are bubbled up from the thenable - final Map map = (Map) failure; + final Map map = (Map) failure; if (map.containsKey("name") && map.containsKey("message")) { promise.fail( wrap( @@ -260,7 +247,7 @@ public ECMAEngine(Vertx vertx) { Value.class, Set.class, Value::hasArrayElements, - v -> new HashSet<>(v.as(List.class)), + v -> new SetContainer<>(v.as(List.class)), HostAccess.TargetMappingPrecedence.LOW) // Goal: Error -> Throwable // Errors are expected to be used sporadically too, this helper is just extracting the default error fields from @@ -287,7 +274,7 @@ public ECMAEngine(Vertx vertx) { } private static Throwable wrap(String name, String message, String stack) { - // empty message fields usually it JS prints the name field + // empty message fields usually in JS prints the name field final Throwable t = new Throwable("".equals(message) ? name : message); // the stacktrace for JS is a single string and we need to parse it back to a Java friendly way if (stack != null) { diff --git a/es4x/src/main/java/io/reactiverse/es4x/Runtime.java b/es4x/src/main/java/io/reactiverse/es4x/Runtime.java index 5e5cfc1ce..a00d6262c 100644 --- a/es4x/src/main/java/io/reactiverse/es4x/Runtime.java +++ b/es4x/src/main/java/io/reactiverse/es4x/Runtime.java @@ -79,9 +79,9 @@ public Value apply(Object value) { source = Source.newBuilder("js", (File) value).build(); } else if (value instanceof Map) { // a json document - final String script = (String) ((Map) value).get("script"); + final String script = (String) ((Map) value).get("script"); // might be optional - final String name = (String) ((Map) value).get("name"); + final String name = (String) ((Map) value).get("name"); if (name != null && name.length() > 0) { final URI uri; @@ -199,7 +199,7 @@ public Value eval(String script, boolean interactive) { /** * Parse a given script string. * - * @param script string containing code. + * @param script string containing code. * @param interactive literals are non listed on debug sessions * @return returns the parsing result. */ @@ -210,7 +210,7 @@ public Value parse(String script, boolean interactive) { /** * Parse a given script string. * - * @param script string containing code. + * @param script string containing code. * @param contentType the script content type * @param interactive literals are non listed on debug sessions * @return returns the parsing result. diff --git a/es4x/src/main/java/io/reactiverse/es4x/impl/ImportMapper.java b/es4x/src/main/java/io/reactiverse/es4x/impl/ImportMapper.java index 7098f63b3..2a01723e3 100644 --- a/es4x/src/main/java/io/reactiverse/es4x/impl/ImportMapper.java +++ b/es4x/src/main/java/io/reactiverse/es4x/impl/ImportMapper.java @@ -11,6 +11,8 @@ import java.net.URL; import java.util.*; +import static io.reactiverse.es4x.impl.Utils.toNixPath; + public class ImportMapper { private final Map imports; @@ -62,8 +64,9 @@ public URI resolve(String specifier, String referrer) throws MalformedURLExcepti } public URL resolve(String specifier, URL scriptURL) throws UnmappedBareSpecifierException { - final URL asURL = tryURLLikeSpecifierParse(specifier, scriptURL); - final String normalizedSpecifier = asURL != null ? href(asURL) : specifier; + final String posixSpecifier = toNixPath(specifier); + final URL asURL = tryURLLikeSpecifierParse(posixSpecifier, scriptURL); + final String normalizedSpecifier = asURL != null ? href(asURL) : posixSpecifier; final String scriptURLString = href(scriptURL); for (Map.Entry> kv : scopes.entrySet()) { diff --git a/es4x/src/main/java/io/reactiverse/es4x/impl/SetContainer.java b/es4x/src/main/java/io/reactiverse/es4x/impl/SetContainer.java new file mode 100644 index 000000000..e61984e06 --- /dev/null +++ b/es4x/src/main/java/io/reactiverse/es4x/impl/SetContainer.java @@ -0,0 +1,49 @@ +/* + * Copyright 2019 Red Hat, Inc. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Apache License v2.0 which accompanies this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * The Apache License v2.0 is available at + * http://www.opensource.org/licenses/apache2.0.php + * + * You may elect to redistribute this code under either of these licenses. + */ +package io.reactiverse.es4x.impl; + +import java.util.AbstractSet; +import java.util.Iterator; +import java.util.List; + +public class SetContainer extends AbstractSet { + + private final List holder; + + public SetContainer(List holder) { + this.holder = holder; + } + + @Override + public boolean add(T item) { + if (holder.contains(item)) { + return false; + } + + holder.add(item); + return true; + } + + @Override + public Iterator iterator() { + return holder.iterator(); + } + + @Override + public int size() { + return holder.size(); + } +} diff --git a/es4x/src/main/java/io/reactiverse/es4x/impl/UnmappedBareSpecifierException.java b/es4x/src/main/java/io/reactiverse/es4x/impl/UnmappedBareSpecifierException.java index 067331188..7c84da04e 100644 --- a/es4x/src/main/java/io/reactiverse/es4x/impl/UnmappedBareSpecifierException.java +++ b/es4x/src/main/java/io/reactiverse/es4x/impl/UnmappedBareSpecifierException.java @@ -5,5 +5,4 @@ public final class UnmappedBareSpecifierException extends Exception { public UnmappedBareSpecifierException(String bareSpecifier) { super("Unmapped bare specifier: " + bareSpecifier); } - } diff --git a/es4x/src/main/java/io/reactiverse/es4x/impl/Utils.java b/es4x/src/main/java/io/reactiverse/es4x/impl/Utils.java index a32167c4c..ef13001fb 100644 --- a/es4x/src/main/java/io/reactiverse/es4x/impl/Utils.java +++ b/es4x/src/main/java/io/reactiverse/es4x/impl/Utils.java @@ -2,6 +2,8 @@ import java.io.*; import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; @@ -90,4 +92,67 @@ public static String getManifestAttribute(String attribute) throws IOException { return null; } + + public static URI fileToURI(File file) { + try { + return new URI("file://" + slashify(file.getPath(), file.isDirectory())); + } catch (URISyntaxException e) { + throw new IllegalArgumentException("Cannot convert to URI: " + file, e); + } + } + + private static String slashify(String path, boolean isDirectory) { + String p = path; + if (File.separatorChar != '/') + p = p.replace(File.separatorChar, '/'); + if (!p.startsWith("/")) + p = "/" + p; + if (!p.endsWith("/") && isDirectory) + p = p + "/"; + return p; + } + + public static String toNixPath(String path) { + if (File.separatorChar != '/') { + // handle the edge-case of Window's long file names + // See: https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#short-vs-long-names + path = path.replaceAll("^\\\\\\\\\\?\\\\",""); + + // convert the separators, valid since both \ and / can't be in a windows filename + path = path.replace('\\','/'); + + // compress any // or /// to be just /, which is a safe oper under POSIX + // and prevents accidental errors caused by manually doing path1+path2 + path = path.replaceAll("//+","/"); + + // prefix with slash if drive letter is present + if (path.length() > 1) { + if (Character.isLetter(path.charAt(0)) && path.charAt(1) == ':') { + path = "/" + path; + } + } + } + return path; + } + + static String relativize(String base, String fileName) { + + if (fileName.startsWith(base)) { + int baseLen = base.length(); + if (fileName.length() == baseLen) { + return ""; + } else { + int sep; + if (base.charAt(baseLen - 1) == File.separatorChar) { + sep = baseLen - 1; + } else { + sep = baseLen; + } + if (fileName.charAt(sep) == File.separatorChar) { + return fileName.substring(sep + 1); + } + } + } + return fileName; + } } diff --git a/es4x/src/main/java/io/reactiverse/es4x/impl/VertxFileSystem.java b/es4x/src/main/java/io/reactiverse/es4x/impl/VertxFileSystem.java index eb65ce457..680a955b7 100644 --- a/es4x/src/main/java/io/reactiverse/es4x/impl/VertxFileSystem.java +++ b/es4x/src/main/java/io/reactiverse/es4x/impl/VertxFileSystem.java @@ -33,7 +33,6 @@ import java.nio.file.spi.FileSystemProvider; import java.util.*; import java.util.concurrent.ConcurrentHashMap; -import java.util.regex.Pattern; import static io.reactiverse.es4x.impl.Utils.*; @@ -41,7 +40,6 @@ public final class VertxFileSystem implements FileSystem { private static final Logger LOGGER = LoggerFactory.getLogger(VertxFileSystem.class); - private static final Pattern DOT_SLASH = Pattern.compile("^\\." + Pattern.quote(File.separator) + "|" + Pattern.quote(File.separator) + "\\." + Pattern.quote(File.separator)); private static final FileSystemProvider DELEGATE = FileSystems.getDefault().provider(); public static String getCWD() { @@ -70,7 +68,6 @@ public static String getCWD() { private final String[] extensions; // keep track of the well-known roots private final String cwd; - private final String cacheDir; private final String downloadDir; private final String baseDir; @@ -81,38 +78,35 @@ public VertxFileSystem(final Vertx vertx, String importMap, String... extensions this.extensions = extensions; // resolve the well known roots - this.cwd = getCWD(); - URL cwdUrl; try { - cwdUrl = new File(this.cwd).toURI().toURL(); - } catch (MalformedURLException e) { - throw new IllegalStateException("CWD toURL() failure", e); - } - - this.cacheDir = this.vertx.resolveFile("").getPath() + File.separator; - - if (importMap == null) { - mapper = new ImportMapper( - new JsonObject() - .put("imports", new JsonObject() - .put(cacheDir, "./")), - cwdUrl); - baseDir = new File(this.cwd, "node_modules").getPath() + File.separator; - downloadDir = new File(this.baseDir, ".download").getPath() + File.separator; - } else { - baseDir = new File(this.cwd).getPath() + File.separator; - downloadDir = new File(this.baseDir, ".download").getPath() + File.separator; - JsonObject json = new JsonObject(vertx.fileSystem().readFileBlocking(importMap)); - if (json.containsKey("imports")) { - json - .getJsonObject("imports") - .put(cacheDir, "./"); + cwd = getCWD(); + URI cwdUrl = fileToURI(new File(this.cwd).getCanonicalFile()); + + if (importMap == null) { + mapper = new ImportMapper( + new JsonObject() + .put("imports", new JsonObject() + .put(toNixPath(cwd), "./")), + cwdUrl); + baseDir = new File(this.cwd, "node_modules").getPath() + File.separator; + downloadDir = new File(this.baseDir, ".download").getPath() + File.separator; } else { - json - .put("imports", new JsonObject() - .put(cacheDir, "./")); + baseDir = new File(this.cwd).getPath() + File.separator; + downloadDir = new File(this.baseDir, ".download").getPath() + File.separator; + JsonObject json = new JsonObject(vertx.fileSystem().readFileBlocking(importMap)); + if (json.containsKey("imports")) { + json + .getJsonObject("imports") + .put(toNixPath(cwd), "./"); + } else { + json + .put("imports", new JsonObject() + .put(toNixPath(cwd), "./")); + } + mapper = new ImportMapper(json, cwdUrl); } - mapper = new ImportMapper(json, cwdUrl); + } catch (IOException | IllegalArgumentException e) { + throw new IllegalArgumentException("Cannot resolve the CWD", e); } } @@ -196,6 +190,8 @@ public Path parsePath(URI uri) { */ @Override public Path parsePath(String path) { + LOGGER.trace(String.format("parsePath(%s)", path)); + if ("".equals(path)) { return new File(cwd).toPath(); } @@ -206,7 +202,7 @@ public Path parsePath(String path) { LOGGER.trace(String.format("import-map.resolve(%s) : %s", path, resolved)); switch (resolved.getScheme()) { case "file": - file = new File(resolved.getPath()); + file = vertx.resolveFile(resolved.getPath()); break; case "http": case "https": @@ -219,55 +215,34 @@ public Path parsePath(String path) { throw new IllegalArgumentException("unsupported scheme: " + resolved.getScheme()); } } catch (UnmappedBareSpecifierException e) { - LOGGER.warn("Failed to resolve module", e); + LOGGER.debug("Failed to resolve module", e); // bare specifier file = new File(baseDir, path); } catch (URISyntaxException e) { throw new InvalidPathException(path, e.getMessage()); } - LOGGER.trace(String.format("parsePath(%s)", path)); - - // simple normalize - file = new File(DOT_SLASH.matcher(file.getPath()).replaceAll(File.separator)); - // if it's a download, get the file to the download dir // if not, continue the processing... if (!fetchIfNeeded(file, path)) { - // if a paths starts with cwd -> strip + force resolve through vertx - if (file.getPath().startsWith(cwd)) { - String stripped = file.getPath().substring(cwd.length()); - // force all resolutions to go over vertx file resolver to allow - // getting the right path objects even if on the classpath - file = vertx.resolveFile(stripped); - // aliasing from cache back to CWD - if (file.getPath().startsWith(cacheDir)) { - file = new File(cwd, file.getPath().substring(cacheDir.length())); - } - // make absolute - if (!file.isAbsolute()) { - file = new File(cwd, file.getPath()); - } - } + // force resolve through vertx, this allows fixing paths from cache back to the right location + file = vertx.resolveFile(file.getPath()); } - // assure the format is right - assert file.isAbsolute() : "path should be absolute"; + return file.toPath(); } private boolean fetchIfNeeded(File file, String path) { - if (!file.isAbsolute()) { - file = file.getAbsoluteFile(); - } + LOGGER.trace(String.format("fetchIfNeeded(%s, %s)", file, path)); - if (file.getPath().startsWith(downloadDir)) { + if (path.startsWith(downloadDir)) { // download if missing if (!file.exists()) { // build an URL from the path - String target = file.getPath().substring(downloadDir.length()); + String target = relativize(downloadDir, path); int split = target.indexOf(File.separator); String source = target.substring(0, split); - // can we map the hash to a url? + // can we map the hash to an url? if (!urlMap.containsKey(source)) { throw new InvalidPathException(path, "Cannot resolve the source of the hash: " + source); } @@ -383,20 +358,12 @@ public void setCurrentWorkingDirectory(Path currentWorkingDirectory) { public Path toRealPath(Path path, LinkOption... linkOptions) throws IOException { LOGGER.trace(String.format("toRealPath(%s)", path)); String name = path.toString(); - File file; - // normalize to CWD - if (name.startsWith(cwd)) { - // get the real path - file = vertx.resolveFile(name.substring(cwd.length())); - } else { - // use it as is - file = path.toFile(); - } + File file = vertx.resolveFile(relativize(cwd, name)); boolean isDownloaded = fetchIfNeeded(file, name); // if file doesn't exist, we try to guess it it's missing the extension or is an index - // if it still fails, it fallbacks to the original file + // if it still fails, it falls back to the original file if (!isDownloaded && !file.exists()) { file = resolveFile(file, null); } diff --git a/es4x/src/main/java/io/reactiverse/es4x/jul/ANSIFormatter.java b/es4x/src/main/java/io/reactiverse/es4x/jul/ANSIFormatter.java index 79bbd0556..f6712b297 100644 --- a/es4x/src/main/java/io/reactiverse/es4x/jul/ANSIFormatter.java +++ b/es4x/src/main/java/io/reactiverse/es4x/jul/ANSIFormatter.java @@ -44,8 +44,8 @@ public class ANSIFormatter extends Formatter { || term.endsWith("-256color"); } else { // there's no env variable (we're running either embedded (no shell) - // or on a OS that doesn't set the TERM variable (Windows maybe) - colors = false; + // or on an OS that doesn't set the TERM variable (Windows maybe) + colors = System.console() != null; } } } diff --git a/es4x/src/main/java/io/reactiverse/es4x/sourcemap/Base64VLQ.java b/es4x/src/main/java/io/reactiverse/es4x/sourcemap/Base64VLQ.java new file mode 100644 index 000000000..bf1fe998f --- /dev/null +++ b/es4x/src/main/java/io/reactiverse/es4x/sourcemap/Base64VLQ.java @@ -0,0 +1,91 @@ +package io.reactiverse.es4x.sourcemap; + +import java.util.Arrays; + +/** + * We encode our variable length numbers as base64 encoded strings with + * the least significant digit coming first. Each base64 digit encodes + * a 5-bit value (0-31) and a continuation bit. Signed values can be + * represented by using the least significant bit of the value as the + * sign bit. + * + * Code based on Google Closure Compiler https://code.google.com/p/closure-compiler + */ +class Base64VLQ { + // Utility class. + private Base64VLQ() {} + + // A map used to convert integer values in the range 0-63 to their base64 values. + private static final String BASE64_MAP = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + "abcdefghijklmnopqrstuvwxyz" + + "0123456789+/"; + + // A map used to convert base64 character into integer values. + private static final int[] BASE64_DECODE_MAP = new int[256]; + + static { + Arrays.fill(BASE64_DECODE_MAP, -1); + for (int i = 0; i < BASE64_MAP.length(); i++) + BASE64_DECODE_MAP[BASE64_MAP.charAt(i)] = i; + } + // A Base64 VLQ digit can represent 5 bits, so it is base-32. + private static final int VLQ_BASE_SHIFT = 5; + private static final int VLQ_BASE = 1 << VLQ_BASE_SHIFT; + + // A mask of bits for a VLQ digit (11111), 31 decimal. + private static final int VLQ_BASE_MASK = VLQ_BASE-1; + + // The continuation bit is the 6th bit. + private static final int VLQ_CONTINUATION_BIT = VLQ_BASE; + + /** + * Converts to a two-complement value from a value where the sign bit is + * is placed in the least significant bit. For example, as decimals: + * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1 + * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2 + */ + private static int fromVLQSigned(int value) { + boolean negate = (value & 1) == 1; + value = value >> 1; + return negate ? -value : value; + } + + /** + * A simple interface for advancing through a sequence of characters, that + * communicates that advance back to the source. + */ + interface CharIterator { + boolean hasNext(); + char next(); + } + + /** + * Decodes the next VLQValue from the provided CharIterator. + */ + public static int decode(CharIterator in) { + int result = 0; + boolean continuation; + int shift = 0; + do { + char c = in.next(); + int digit = fromBase64(c); + continuation = (digit & VLQ_CONTINUATION_BIT) != 0; + digit &= VLQ_BASE_MASK; + result = result + (digit << shift); + shift = shift + VLQ_BASE_SHIFT; + } while (continuation); + + return fromVLQSigned(result); + } + + /** + * @param c A base64 digit. + * @return A value in the range of 0-63. + */ + public static int fromBase64(char c) { + int result = BASE64_DECODE_MAP[c]; + assert (result != -1) : "invalid char"; + return BASE64_DECODE_MAP[c]; + } +} diff --git a/es4x/src/main/java/io/reactiverse/es4x/sourcemap/Mapping.java b/es4x/src/main/java/io/reactiverse/es4x/sourcemap/Mapping.java new file mode 100644 index 000000000..a7383e641 --- /dev/null +++ b/es4x/src/main/java/io/reactiverse/es4x/sourcemap/Mapping.java @@ -0,0 +1,50 @@ +package io.reactiverse.es4x.sourcemap; + +/** + * Mapping for Source Map. + */ +public class Mapping { + private final int generatedLine; + private final int generatedColumn; + private final int sourceLine; + private final int sourceColumn; + private final String sourceFileName; + private final String sourceSymbolName; + + public Mapping(int generatedLine, int generatedColumn, int sourceLine, int sourceColumn, String sourceFileName, String sourceSymbolName) { + this.generatedLine = generatedLine; + this.generatedColumn = generatedColumn; + this.sourceLine = sourceLine; + this.sourceColumn = sourceColumn; + this.sourceFileName = sourceFileName; + this.sourceSymbolName = sourceSymbolName; + } + + public String toString() { + return "Mapping " + generatedLine + ":" + generatedColumn + " -> " + sourceFileName + ":" + sourceLine + ":" + sourceColumn; + } + + public int getGeneratedLine() { + return generatedLine; + } + + public int getGeneratedColumn() { + return generatedColumn; + } + + public int getSourceLine() { + return sourceLine; + } + + public int getSourceColumn() { + return sourceColumn; + } + + public String getSourceFileName() { + return sourceFileName; + } + + public String getSourceSymbolName() { + return sourceSymbolName; + } +} diff --git a/es4x/src/main/java/io/reactiverse/es4x/sourcemap/SourceMap.java b/es4x/src/main/java/io/reactiverse/es4x/sourcemap/SourceMap.java new file mode 100644 index 000000000..1885f93c3 --- /dev/null +++ b/es4x/src/main/java/io/reactiverse/es4x/sourcemap/SourceMap.java @@ -0,0 +1,321 @@ +package io.reactiverse.es4x.sourcemap; + +import io.vertx.core.json.Json; +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +/** + * Parsing SourceMap version 3. + *

+ * Code based on Google Closure Compiler https://code.google.com/p/closure-compiler + */ +public class SourceMap { + static final int UNMAPPED = -1; + private JsonArray sourceFileNames; + private JsonArray sourceSymbolNames; + private ArrayList> lines = null; + private String sourceRoot; + + public SourceMap(String sourceMapData) { + parse(sourceMapData); + } + + /** + * Parses the given contents containing a source map. + */ + private void parse(String sourceMapData) { + JsonObject sourceMapRoot = new JsonObject(sourceMapData); + + // Check basic assertions about the format. + int version = sourceMapRoot.getInteger("version"); + if (version != 3) throw new RuntimeException("Unknown version: " + version); + + sourceFileNames = sourceMapRoot.getJsonArray("sources"); + sourceSymbolNames = sourceMapRoot.getJsonArray("names"); + + lines = new ArrayList<>(); + + new MappingBuilder(sourceMapRoot.getString("mappings")).build(); + } + + public Mapping getMapping(int lineNumber, int column) { + if (lineNumber < 0 || lineNumber >= lines.size()) return null; + + if (lineNumber < 0) throw new RuntimeException("invalid line number!"); + if (column < 0) throw new RuntimeException("invalid column number!"); + + + // If the line is empty return the previous mapping. + if (lines.get(lineNumber) == null) return getPreviousMapping(lineNumber); + + ArrayList entries = lines.get(lineNumber); + // No empty lists. + if (entries.isEmpty()) throw new RuntimeException("empty list of entries!"); + if (entries.get(0).getGeneratedColumn() > column) return getPreviousMapping(lineNumber); + + int index = search(entries, column, 0, entries.size() - 1); + if (index < 0) throw new RuntimeException("can't find entry!"); + return getMappingForEntry(entries.get(index)); + } + + public void eachMapping(java.util.function.Consumer cb) { + for (List line : lines) { + if (line != null) { + for (Mapping mapping : line) cb.accept(mapping); + } + } + } + + public Collection getSourceFileNames() { + return sourceFileNames.getList(); + } + + public Collection getSourceSymbolNames() { + return sourceSymbolNames.getList(); + } + + public String getSourceRoot() { + return this.sourceRoot; + } + + private class MappingBuilder { + private static final int MAX_ENTRY_VALUES = 5; + private final StringCharIterator content; + private int line = 0; + private int previousCol = 0; + private int previousSrcId = 0; + private int previousSrcLine = 0; + private int previousSrcColumn = 0; + private int previousNameId = 0; + + MappingBuilder(String lineMap) { + this.content = new StringCharIterator(lineMap); + } + + void build() { + int[] temp = new int[MAX_ENTRY_VALUES]; + ArrayList entries = new ArrayList(); + while (content.hasNext()) { + // ';' denotes a new line. + if (tryConsumeToken(';')) { + // The line is complete, store the result + completeLine(entries); + // A new array list for the next line. + if (!entries.isEmpty()) entries = new ArrayList(); + } else { + // grab the next entry for the current line. + int entryValues = 0; + while (!entryComplete()) { + temp[entryValues] = nextValue(); + entryValues++; + } + Mapping entry = decodeEntry(line, temp, entryValues); + + entries.add(entry); + + // Consume the separating token, if there is one. + tryConsumeToken(','); + } + } + + // Some source map generator (e.g.UglifyJS) generates lines without + // a trailing line separator. So add the rest of the content. + if (!entries.isEmpty()) completeLine(entries); + } + + private void completeLine(ArrayList entries) { + // The line is complete, store the result for the line, + // null if the line is empty. + if (!entries.isEmpty()) lines.add(entries); + else lines.add(null); + line++; + previousCol = 0; + } + + /** + * Decodes the next entry, using the previous encountered values to + * decode the relative values. + * + * @param vals An array of integers that represent values in the entry. + * @param entryValues The number of entries in the array. + * @return The entry object. + */ + private Mapping decodeEntry(int generatedLine, int[] vals, int entryValues) { + Mapping entry; + int sourceFileNameIndex; + String sourceFileName; + int sourceSymbolNameIndex; + String sourceSymbolName; + switch (entryValues) { + // The first values, if present are in the following order: + // 0: the starting column in the current line of the generated file + // 1: the id of the original source file + // 2: the starting line in the original source + // 3: the starting column in the original source + // 4: the id of the original symbol name + // The values are relative to the last encountered value for that field. + // Note: the previously column value for the generated file is reset + // to '0' when a new line is encountered. This is done in the 'build' + // method. + case 1: + // An unmapped section of the generated file. + entry = new Mapping( + generatedLine, + vals[0] + previousCol, + UNMAPPED, + UNMAPPED, + null, + null + ); + // Set the values see for the next entry. + previousCol = entry.getGeneratedColumn(); + return entry; + + case 4: + // A mapped section of the generated file. + sourceFileNameIndex = vals[1] + previousSrcId; + sourceFileName = sourceFileNames.getString(sourceFileNameIndex); + + entry = new Mapping( + generatedLine, + vals[0] + previousCol, + vals[2] + previousSrcLine, + vals[3] + previousSrcColumn, + sourceFileName, + null); + // Set the values see for the next entry. + previousCol = entry.getGeneratedColumn(); + previousSrcLine = entry.getSourceLine(); + previousSrcColumn = entry.getSourceColumn(); + previousSrcId = sourceFileNameIndex; + return entry; + + case 5: + // A mapped section of the generated file, that has an associated + // name. + sourceFileNameIndex = vals[1] + previousSrcId; + sourceFileName = sourceFileNames.getString(sourceFileNameIndex); + sourceSymbolNameIndex = vals[4] + previousNameId; + sourceSymbolName = sourceSymbolNames.getString(sourceFileNameIndex); + + entry = new Mapping( + generatedLine, + vals[0] + previousCol, + vals[2] + previousSrcLine, + vals[3] + previousSrcColumn, + sourceFileName, + sourceSymbolName + ); + // Set the values see for the next entry. + previousCol = entry.getGeneratedColumn(); + previousSrcLine = entry.getSourceLine(); + previousSrcColumn = entry.getSourceColumn(); + previousSrcId = sourceFileNameIndex; + previousNameId = sourceSymbolNameIndex; + return entry; + + default: + throw new IllegalStateException("Unexpected number of values for entry:" + entryValues); + } + } + + private boolean tryConsumeToken(char token) { + if (content.hasNext() && content.peek() == token) { + // consume the comma + content.next(); + return true; + } + return false; + } + + private boolean entryComplete() { + if (!content.hasNext()) return true; + char c = content.peek(); + return (c == ';' || c == ','); + } + + private int nextValue() { + return Base64VLQ.decode(content); + } + } + + /** + * Perform a binary search on the array to find a section that covers + * the target column. + */ + private int search(ArrayList entries, int target, int start, int end) { + while (true) { + int mid = ((end - start) / 2) + start; + int compare = compareEntry(entries, mid, target); + if (compare == 0) return mid; + else if (compare < 0) { + // it is in the upper half + start = mid + 1; + if (start > end) return end; + } else { + // it is in the lower half + end = mid - 1; + if (end < start) return end; + } + } + } + + /** + * Compare an array entry's column value to the target column value. + */ + private int compareEntry(ArrayList entries, int entry, int target) { + return entries.get(entry).getGeneratedColumn() - target; + } + + /** + * Returns the mapping entry that proceeds the supplied line or null if no + * such entry exists. + */ + private Mapping getPreviousMapping(int lineNumber) { + do { + if (lineNumber == 0) return null; + lineNumber--; + } while (lines.get(lineNumber) == null); + ArrayList entries = lines.get(lineNumber); + return getMappingForEntry(entries.get(entries.size() - 1)); + } + + /** + * Creates an "Mapping" object for the given entry object. + */ + private Mapping getMappingForEntry(Mapping entry) { + return (entry.getSourceFileName() == null) ? null : entry; + } + + /** + * A implementation of the Base64VLQ CharIterator used for decoding the + * mappings encoded in the JSON string. + */ + private static class StringCharIterator implements Base64VLQ.CharIterator { + final String content; + final int length; + int current = 0; + + StringCharIterator(String content) { + this.content = content; + this.length = content.length(); + } + + public char next() { + return content.charAt(current++); + } + + char peek() { + return content.charAt(current); + } + + public boolean hasNext() { + return current < length; + } + } +} diff --git a/es4x/src/main/resources/io/reactiverse/es4x/jvm-npm.js b/es4x/src/main/resources/io/reactiverse/es4x/jvm-npm.js index b6f05e6fe..bdcfd21a3 100644 --- a/es4x/src/main/resources/io/reactiverse/es4x/jvm-npm.js +++ b/es4x/src/main/resources/io/reactiverse/es4x/jvm-npm.js @@ -160,7 +160,9 @@ if (p) { // all paths need to be absolute if (p.indexOf('./') === 0) { - let cwd = System.getProperty("user.dir"); + let cwd = System.getProperty("user.dir") + // transform \ into / + .replace(/\\/g, '/'); if (cwd.length > 0) { if (cwd[cwd.length - 1] !== '/') { cwd += '/'; @@ -241,6 +243,10 @@ return (resolveAsFile(package_.main, base) || resolveAsDirectory(package_.main, base)); } + // if there is type validate that we don't load this module + if (package_.type && package_.type !== 'commonjs') { + throw new ModuleError('Module "' + id + '" type not of type commonjs', 'MODULE_NOT_COMMONJS'); + } // if no package.main exists, look for index.js return resolveAsFile('index.js', base); } diff --git a/es4x/src/main/resources/io/reactiverse/es4x/polyfill/global.js b/es4x/src/main/resources/io/reactiverse/es4x/polyfill/global.js index 11eec6a97..e12195e81 100644 --- a/es4x/src/main/resources/io/reactiverse/es4x/polyfill/global.js +++ b/es4x/src/main/resources/io/reactiverse/es4x/polyfill/global.js @@ -106,7 +106,19 @@ } global.process = { - env: System.getenv(), + env: new Proxy({}, { + get: function (obj, prop) { + return System.getenv(prop); + }, + getOwnPropertyDescriptor: function(obj, prop) { + return { + configurable: true, + enumerable: true, + writable: false, + value: System.getenv(prop) + }; + } + }), pid: pid, platform: System.getProperty('os.name').toLowerCase(), @@ -151,7 +163,7 @@ return { configurable: true, enumerable: true, - value: System.getenv(prop) + value: System.getProperty(prop) }; } }), diff --git a/es4x/src/test/java/io/reactiverse/es4x/MappingTest.java b/es4x/src/test/java/io/reactiverse/es4x/MappingTest.java new file mode 100644 index 000000000..a5d61084c --- /dev/null +++ b/es4x/src/test/java/io/reactiverse/es4x/MappingTest.java @@ -0,0 +1,55 @@ +package io.reactiverse.es4x; + +import io.reactiverse.es4x.impl.VertxFileSystem; +import io.reactiverse.es4x.sourcemap.SourceMap; +import io.vertx.core.Vertx; +import org.graalvm.polyglot.io.FileSystem; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; + +public class MappingTest { + + @Test + public void testMapping() throws IOException { + /* + Failed in deploying verticle caused by ReferenceError: URL is not defined + at :=>(dist/bundle.js:44:1695-1697) + at :=>(dist/bundle.js:43-60:1647-2222) + at :module(dist/bundle.js:1-80:9-2934) + at org.graalvm.sdk/org.graalvm.polyglot.Context.eval(Context.java:347) + at io.reactiverse.es4x.Runtime.eval(Runtime.java:148) + at io.reactiverse.es4x.impl.MJSVerticleFactory$1.start(MJSVerticleFactory.java:76) + at io.vertx.core.impl.DeploymentManager.lambda$doDeploy$5(DeploymentManager.java:196) + at io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:96) + at io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:59) + at io.vertx.core.impl.EventLoopContext.lambda$runOnContext$0(EventLoopContext.java:37) + at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164) + at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472) + at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500) + at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) + at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) + at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) + at java.base/java.lang.Thread.run(Thread.java:829) + */ + + + + SourceMap source = new SourceMap(new String( + Files.readAllBytes(new File("src/test/resources/bundle.js.map").toPath()) + )); + + source.eachMapping(System.out::println); + + System.out.println( + source.getMapping(44, 0)); + + System.out.println( + source.getMapping(60, 0)); + + System.out.println( + source.getMapping(80, 0)); + } +} diff --git a/es4x/src/test/java/io/reactiverse/es4x/impl/ImportMapperTest.java b/es4x/src/test/java/io/reactiverse/es4x/impl/ImportMapperTest.java index 20e5b0a03..2826a0628 100644 --- a/es4x/src/test/java/io/reactiverse/es4x/impl/ImportMapperTest.java +++ b/es4x/src/test/java/io/reactiverse/es4x/impl/ImportMapperTest.java @@ -1,6 +1,5 @@ package io.reactiverse.es4x.impl; -import io.vertx.core.impl.VertxInternal; import io.vertx.core.json.JsonObject; import io.vertx.ext.unit.junit.RunTestOnContext; import io.vertx.ext.unit.junit.VertxUnitRunner; @@ -16,6 +15,7 @@ import java.util.Arrays; import java.util.List; +import static io.reactiverse.es4x.impl.Utils.toNixPath; import static org.junit.Assert.assertEquals; @RunWith(VertxUnitRunner.class) @@ -92,7 +92,7 @@ public void testFromDeno2() throws MalformedURLException, URISyntaxException, Un .put("imports", new JsonObject() .put("/", "./"))); - assertEquals(new URI("file://" + VertxFileSystem.getCWD() + "util.ts"), mapper.resolve("/util.ts")); + assertEquals(new File(VertxFileSystem.getCWD(), "util.ts").toURI(), mapper.resolve("/util.ts")); } @Test @@ -102,22 +102,22 @@ public void testFromDeno3() throws MalformedURLException, URISyntaxException, Un .put("imports", new JsonObject() .put("/", "./src/"))); - assertEquals(new URI("file://" + VertxFileSystem.getCWD() + "src/util.ts"), mapper.resolve("/util.ts")); + assertEquals(new File(VertxFileSystem.getCWD(), "src/util.ts").toURI(), mapper.resolve("/util.ts")); } @Test - public void testCacheResolve() throws MalformedURLException, URISyntaxException, UnmappedBareSpecifierException { + public void testRelativeResolve() throws MalformedURLException, URISyntaxException, UnmappedBareSpecifierException { - VertxInternal vertx = (VertxInternal) rule.vertx(); - String cacheDir = vertx.resolveFile("").getPath() + File.separator; - String baseDir = new File(VertxFileSystem.getCWD()).getPath() + File.separator; + String tmpDir = new File(System.getProperty("java.io.tmpdir")).getPath() + File.separator; + String baseDir = VertxFileSystem.getCWD(); ImportMapper mapper = new ImportMapper( new JsonObject() .put("imports", new JsonObject() - .put(cacheDir, "./"))); + .put(toNixPath(tmpDir), "./")) + ); - assertEquals(new URI("file://" + baseDir + "test.js"), mapper.resolve(cacheDir + "test.js")); + assertEquals(new File(baseDir, "test.js").toURI(), mapper.resolve(tmpDir + "test.js")); } @Test diff --git a/es4x/src/test/java/io/reactiverse/es4x/test/FSResolverTest.java b/es4x/src/test/java/io/reactiverse/es4x/test/FSResolverTest.java index 016a770ed..96bfefeaf 100644 --- a/es4x/src/test/java/io/reactiverse/es4x/test/FSResolverTest.java +++ b/es4x/src/test/java/io/reactiverse/es4x/test/FSResolverTest.java @@ -36,17 +36,23 @@ public void testResolver() throws URISyntaxException { cwd = cwd.substring(0, cwd.length() - 1); String cache = ((VertxInternal) vertx).resolveFile("").getPath(); + String drive = ""; + + if (File.separatorChar != '/') { + drive = cwd.substring(0, 2); + } + // resolve to node modules assertEquals(cwd + $ + "node_modules" + $ + "index.js", fs.parsePath("index.js").toString()); // resolve to cwd assertEquals(cwd + $ + "index.js", fs.parsePath("./index.js").toString()); // resolve to cwd parent - int s = cwd.lastIndexOf('/'); + int s = cwd.lastIndexOf(File.separatorChar); assertEquals(cwd.substring(0, s) + $ + "index.js", fs.parsePath("../index.js").toString()); // resolve to root - assertEquals($ + "index.js", fs.parsePath("/index.js").toString()); - // rewrite to cwd - assertEquals(cwd + $ + "index.js", fs.parsePath(cache + $ + "index.js").toString()); + assertEquals(drive + $ + "index.js", fs.parsePath(drive + "/index.js").toString()); + // rewrite to relative + assertEquals("index.js", fs.parsePath(cache + $ + "index.js").toString()); // attempt download assertEquals(cwd + $ + "node_modules" + $ + ".download" + $ + "eedc890765ef80e2b57c447a50f911cd" + $ + "@vertx" + $ + "core@3.9.1" + $ + "options.mjs", fs.parsePath(new URI("https://unpkg.io/@vertx/core@3.9.1/options.mjs")).toString()); // attempt from download cache diff --git a/es4x/src/test/java/io/reactiverse/es4x/test/FactoryMJSTest.java b/es4x/src/test/java/io/reactiverse/es4x/test/FactoryMJSTest.java index 93c16a485..255651e18 100644 --- a/es4x/src/test/java/io/reactiverse/es4x/test/FactoryMJSTest.java +++ b/es4x/src/test/java/io/reactiverse/es4x/test/FactoryMJSTest.java @@ -38,10 +38,13 @@ public void shouldDeployVerticleWithOnStop(TestContext ctx) { } @Test(timeout = 30000) - @Ignore("This test requires the npm modules for 4.1 to be released first") public void shouldDeployVerticleWithMod(TestContext ctx) { final Async async = ctx.async(); rule.vertx().deployVerticle("mjs:./online.mjs", deploy -> { + if (deploy.failed()) { + deploy.cause().printStackTrace(); + } + ctx.assertTrue(deploy.succeeded()); rule.vertx().setTimer(1000L, t -> rule.vertx().undeploy(deploy.result(), undeploy -> { ctx.assertTrue(undeploy.succeeded()); diff --git a/es4x/src/test/java/io/reactiverse/es4x/test/FutureTest.java b/es4x/src/test/java/io/reactiverse/es4x/test/FutureTest.java index 0e75c10af..f9bc28aa4 100644 --- a/es4x/src/test/java/io/reactiverse/es4x/test/FutureTest.java +++ b/es4x/src/test/java/io/reactiverse/es4x/test/FutureTest.java @@ -82,7 +82,7 @@ public static class FutureTest2 { final Async test; final AtomicInteger ok = new AtomicInteger(3); - final AtomicInteger fail = new AtomicInteger(3); + final AtomicInteger fail = new AtomicInteger(4); FutureTest2(Vertx vertx, TestContext should, Async test) { this.should = should; diff --git a/es4x/src/test/java/io/reactiverse/es4x/test/ProcessTest.java b/es4x/src/test/java/io/reactiverse/es4x/test/ProcessTest.java index 410a91dbd..31d4c2da1 100644 --- a/es4x/src/test/java/io/reactiverse/es4x/test/ProcessTest.java +++ b/es4x/src/test/java/io/reactiverse/es4x/test/ProcessTest.java @@ -32,6 +32,9 @@ public void testProcessEnv() { Map env = runtime.eval("process.env").as(Map.class); // PATH is usually available on all OSes assertNotNull(env.get("PATH")); + + String ref = runtime.eval("process.env['PATH']").as(String.class); + assertNotNull(ref); } @Test(timeout = 10000) @@ -46,7 +49,9 @@ public void testProcessCWD() { @Test(timeout = 10000) public void testProcessProperties() { Map env = runtime.eval("process.properties").as(Map.class); - // PATH is usually available on all OSes assertNotNull(env.get("user.dir")); + + String ref = runtime.eval("process.properties['user.dir']").as(String.class); + assertNotNull(ref); } } diff --git a/es4x/src/test/resources/bundle.js.map b/es4x/src/test/resources/bundle.js.map new file mode 100644 index 000000000..1b06b83ce --- /dev/null +++ b/es4x/src/test/resources/bundle.js.map @@ -0,0 +1 @@ +{"version":3,"file":"bundle.js","mappings":";;;;UAAA;UACA;;UAEA;UACA;;;;;WCJA;WACA;WACA;WACA;WACA;;;;;WCJA;;;;;WCAA;WACA;WACA;WACA,uDAAuD,iBAAiB;WACxE;WACA,gDAAgD,aAAa;WAC7D;;;;;WCNA;;;;;WCAA;;WAEA;WACA;WACA;WACA;WACA;WACA;;WAEA;;WAEA;;WAEA;;WAEA;;;;;;;;;ACfA,qCAAqC;AACrC,YAAY;AACZ,OAAO,CAAC,GAAG,CAAC,gDAAe,CAAC;AAC5B,MAAM,MAAM,GAAW,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC,4GAA+B,CAAC,CAAC,CAAC;AAE5E,MAAM,CAAC,WAAW,CAAC;IACjB,QAAQ,EACN,4EAA4E;CAC/E,CAAC,CAAC;AACH,MAAM,CAAC,SAAS,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE;IAC1C,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC,CAAC","sources":["webpack://phala_chain_bridge/webpack/bootstrap","webpack://phala_chain_bridge/webpack/runtime/get javascript chunk filename","webpack://phala_chain_bridge/webpack/runtime/hasOwnProperty shorthand","webpack://phala_chain_bridge/webpack/runtime/make namespace object","webpack://phala_chain_bridge/webpack/runtime/publicPath","webpack://phala_chain_bridge/webpack/runtime/import chunk loading","webpack://phala_chain_bridge/./src/index.ts"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","// This function allow to reference async chunks\n__webpack_require__.u = (chunkId) => {\n\t// return url for filenames based on template\n\treturn \"\" + chunkId + \".bundle.js\";\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.p = \"\";","__webpack_require__.b = new URL(\"./\", import.meta.url);\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t\"main\": 0\n};\n\n// no install chunk\n\n// no chunk on demand loading\n\n// no external install chunk\n\n// no on chunks loaded","/// \n// @ts-check\nconsole.log(import.meta.url)\nconst worker: Worker = new Worker(new URL(\"my.worker.js\", import.meta.url));\n\nworker.postMessage({\n question:\n 'The Answer to the Ultimate Question of Life, The Universe, and Everything.',\n});\nworker.onmessage = ({ data: { answer } }) => {\n console.log(answer);\n};"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/es4x/src/test/resources/future/future2.js b/es4x/src/test/resources/future/future2.js index 56d1238b0..f07740742 100644 --- a/es4x/src/test/resources/future/future2.js +++ b/es4x/src/test/resources/future/future2.js @@ -6,14 +6,20 @@ async function futureTest2 () { }) .listen(-1) }; - should.assertEquals('io.vertx.core.http.impl.HttpServerImpl', server.getClass().getName()); + return server; } futureTest2() .then(function (result) { - should.fail('Expected to fail with negative port'); + // 4.2. behavior + if (result.actualPort() <= 0) { + should.fail('Expected to fail with negative port'); + } else { + test.complete(); + } }) .catch(function (err) { + // 4.1. behavior test.complete(); }); diff --git a/es4x/src/test/resources/online.mjs b/es4x/src/test/resources/online.mjs index bb5040de9..c2c5c0b63 100644 --- a/es4x/src/test/resources/online.mjs +++ b/es4x/src/test/resources/online.mjs @@ -1,4 +1,4 @@ -import { Router } from 'https://unpkg.io/@vertx/web@4.0.3/mod.js' +import { Router } from 'https://unpkg.io/@vertx/web@4.1.0/mod.js' Router.router(vertx); diff --git a/generator/build.sh b/generator/build.sh index 53f3cee0b..a1d640d03 100755 --- a/generator/build.sh +++ b/generator/build.sh @@ -18,7 +18,7 @@ elif [ "$1" = "publish" ]; then npm adduser --registry "$REGISTRY" mvn -fae -Pio.reactiverse -Dnpm-registry="$REGISTRY" -Dnpm-tag=${TAG} exec:exec@npm-publish | tee build-$1-reactiverse.log elif [ "$1" = "tsdocs" ]; then - mvn -fae -Pio.vertx,io.reactiverse clean generate-sources install exec:exec@typedoc | tee build-$1.log + mvn -Pio.vertx,io.reactiverse clean generate-sources install exec:exec@typedoc | tee build-$1.log else mvn -fae -Pio.vertx,io.reactiverse clean generate-sources install | tee build.log fi diff --git a/generator/io.reactiverse/elasticsearch-client/pom.xml b/generator/io.reactiverse/elasticsearch-client/pom.xml index 12b1022a8..cdf8c01f1 100644 --- a/generator/io.reactiverse/elasticsearch-client/pom.xml +++ b/generator/io.reactiverse/elasticsearch-client/pom.xml @@ -8,19 +8,19 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. elasticsearch-client - 0.15.0 + 0.16.0 jar io.reactiverse @reactiverse/elasticsearch-client - 0.8.4-ec7.10.1 + 0.9.0-ec7.10.1 false diff --git a/generator/io.reactiverse/reactiverse-contextual-logging/pom.xml b/generator/io.reactiverse/reactiverse-contextual-logging/pom.xml new file mode 100644 index 000000000..659c764ce --- /dev/null +++ b/generator/io.reactiverse/reactiverse-contextual-logging/pom.xml @@ -0,0 +1,71 @@ + + + + 4.0.0 + + + io.reactiverse.es4x + es4x-generator + 0.16.0 + ../.. + + + reactiverse-contextual-logging + 0.16.0 + + jar + + + io.reactiverse + @reactiverse/contextual-logging + 1.1.0 + false + + + { + "@vertx/core": "${stack.version}" + } + + 1.2.3 + 2.14.0 + + + + + ch.qos.logback + logback-classic + ${logback.version} + true + + + org.apache.logging.log4j + log4j-core + ${log4j2.version} + true + + + + io.vertx + vertx-codegen + provided + true + ${stack.version} + + + + ${maven.groupId} + ${project.artifactId} + ${npm-version} + + + ${maven.groupId} + ${project.artifactId} + ${npm-version} + provided + sources + + + + diff --git a/generator/io.vertx/pom.xml b/generator/io.vertx/pom.xml index 7b4bb4f0a..28fcfc7d3 100644 --- a/generator/io.vertx/pom.xml +++ b/generator/io.vertx/pom.xml @@ -8,12 +8,12 @@ io.reactiverse es4x-parent - 0.15.0 + 0.16.0 ../.. es4x-vertx-stack - 0.15.0 + 0.16.0 @@ -59,6 +59,7 @@ io.reactiverse.es4xvertx-auth-shiro${project.version} io.reactiverse.es4xvertx-auth-sql-client${project.version} io.reactiverse.es4xvertx-auth-webauthn${project.version} + io.reactiverse.es4xvertx-auth-otp${project.version} io.reactiverse.es4xvertx-bridge-common${project.version} io.reactiverse.es4xvertx-camel-bridge${project.version} io.reactiverse.es4xvertx-cassandra-client${project.version} @@ -67,6 +68,7 @@ io.reactiverse.es4xvertx-consul-client${project.version} io.reactiverse.es4xvertx-core${project.version} io.reactiverse.es4xvertx-db2-client${project.version} + io.reactiverse.es4xvertx-oracle-client${project.version} io.reactiverse.es4xvertx-dropwizard-metrics${project.version} io.reactiverse.es4xvertx-grpc${project.version} io.reactiverse.es4xvertx-health-check${project.version} @@ -113,6 +115,7 @@ io.reactiverse.es4xvertx-web-templ-rythm${project.version} io.reactiverse.es4xvertx-web-validation${project.version} io.reactiverse.es4xvertx-zipkin${project.version} + io.reactiverse.es4xvertx-http-proxy${project.version} node_modules/ node_modules/**/node_modules/ diff --git a/generator/io.vertx/vertx-amqp-client/pom.xml b/generator/io.vertx/vertx-amqp-client/pom.xml index a3ecc21f8..aeff9e646 100644 --- a/generator/io.vertx/vertx-amqp-client/pom.xml +++ b/generator/io.vertx/vertx-amqp-client/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-amqp-client - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-auth-common/Credentials.excludes.json b/generator/io.vertx/vertx-auth-common/Credentials.excludes.json new file mode 100644 index 000000000..561641646 --- /dev/null +++ b/generator/io.vertx/vertx-auth-common/Credentials.excludes.json @@ -0,0 +1,5 @@ +{ + "applyHttpChallenge": true, + "toHttpAuthorization": true, + "checkValid": true +} diff --git a/generator/io.vertx/vertx-auth-common/TokenCredentials.includes.json b/generator/io.vertx/vertx-auth-common/TokenCredentials.includes.json new file mode 100644 index 000000000..2270d45fd --- /dev/null +++ b/generator/io.vertx/vertx-auth-common/TokenCredentials.includes.json @@ -0,0 +1,4 @@ +{ + "import": "import { Credentials } from '@vertx/auth-common';\n", + "dataObjectImplements": "Credentials" +} diff --git a/generator/io.vertx/vertx-auth-common/UsernamePasswordCredentials.includes.json b/generator/io.vertx/vertx-auth-common/UsernamePasswordCredentials.includes.json new file mode 100644 index 000000000..2270d45fd --- /dev/null +++ b/generator/io.vertx/vertx-auth-common/UsernamePasswordCredentials.includes.json @@ -0,0 +1,4 @@ +{ + "import": "import { Credentials } from '@vertx/auth-common';\n", + "dataObjectImplements": "Credentials" +} diff --git a/generator/io.vertx/vertx-auth-common/pom.xml b/generator/io.vertx/vertx-auth-common/pom.xml index e1d87a993..4493bbff5 100644 --- a/generator/io.vertx/vertx-auth-common/pom.xml +++ b/generator/io.vertx/vertx-auth-common/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-auth-common - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-auth-htdigest/HtdigestCredentials.includes.json b/generator/io.vertx/vertx-auth-htdigest/HtdigestCredentials.includes.json new file mode 100644 index 000000000..2270d45fd --- /dev/null +++ b/generator/io.vertx/vertx-auth-htdigest/HtdigestCredentials.includes.json @@ -0,0 +1,4 @@ +{ + "import": "import { Credentials } from '@vertx/auth-common';\n", + "dataObjectImplements": "Credentials" +} diff --git a/generator/io.vertx/vertx-auth-htdigest/pom.xml b/generator/io.vertx/vertx-auth-htdigest/pom.xml index 7f6378121..de13110d8 100644 --- a/generator/io.vertx/vertx-auth-htdigest/pom.xml +++ b/generator/io.vertx/vertx-auth-htdigest/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-auth-htdigest - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-auth-htpasswd/pom.xml b/generator/io.vertx/vertx-auth-htpasswd/pom.xml index d0374c37a..ce58089a6 100644 --- a/generator/io.vertx/vertx-auth-htpasswd/pom.xml +++ b/generator/io.vertx/vertx-auth-htpasswd/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-auth-htpasswd - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-auth-jdbc/pom.xml b/generator/io.vertx/vertx-auth-jdbc/pom.xml index c288e07f2..a158188d3 100644 --- a/generator/io.vertx/vertx-auth-jdbc/pom.xml +++ b/generator/io.vertx/vertx-auth-jdbc/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-auth-jdbc - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-auth-jwt/pom.xml b/generator/io.vertx/vertx-auth-jwt/pom.xml index f6c8b89fa..75491a9fb 100644 --- a/generator/io.vertx/vertx-auth-jwt/pom.xml +++ b/generator/io.vertx/vertx-auth-jwt/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-auth-jwt - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-auth-ldap/pom.xml b/generator/io.vertx/vertx-auth-ldap/pom.xml index 6742b17ab..3b48f437c 100644 --- a/generator/io.vertx/vertx-auth-ldap/pom.xml +++ b/generator/io.vertx/vertx-auth-ldap/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-auth-ldap - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-auth-mongo/pom.xml b/generator/io.vertx/vertx-auth-mongo/pom.xml index b2078b9ca..8cf96d71e 100644 --- a/generator/io.vertx/vertx-auth-mongo/pom.xml +++ b/generator/io.vertx/vertx-auth-mongo/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-auth-mongo - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-auth-oauth2/Oauth2Credentials.includes.json b/generator/io.vertx/vertx-auth-oauth2/Oauth2Credentials.includes.json new file mode 100644 index 000000000..2270d45fd --- /dev/null +++ b/generator/io.vertx/vertx-auth-oauth2/Oauth2Credentials.includes.json @@ -0,0 +1,4 @@ +{ + "import": "import { Credentials } from '@vertx/auth-common';\n", + "dataObjectImplements": "Credentials" +} diff --git a/generator/io.vertx/vertx-auth-oauth2/pom.xml b/generator/io.vertx/vertx-auth-oauth2/pom.xml index 10c7a9769..ccdac932d 100644 --- a/generator/io.vertx/vertx-auth-oauth2/pom.xml +++ b/generator/io.vertx/vertx-auth-oauth2/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-auth-oauth2 - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-auth-otp/OtpCredentials.includes.json b/generator/io.vertx/vertx-auth-otp/OtpCredentials.includes.json new file mode 100644 index 000000000..2270d45fd --- /dev/null +++ b/generator/io.vertx/vertx-auth-otp/OtpCredentials.includes.json @@ -0,0 +1,4 @@ +{ + "import": "import { Credentials } from '@vertx/auth-common';\n", + "dataObjectImplements": "Credentials" +} diff --git a/generator/io.vertx/vertx-auth-otp/pom.xml b/generator/io.vertx/vertx-auth-otp/pom.xml new file mode 100644 index 000000000..26e43dccf --- /dev/null +++ b/generator/io.vertx/vertx-auth-otp/pom.xml @@ -0,0 +1,49 @@ + + + + + io.reactiverse.es4x + es4x-generator + 0.16.0 + ../.. + + + 4.0.0 + + vertx-auth-otp + 0.16.0 + + + io.vertx + @vertx/auth-otp + ${stack.version} + false + + + + { + "@vertx/core": "${stack.version}", + "@vertx/auth-common": "${stack.version}" + } + + + + + + + ${maven.groupId} + ${project.artifactId} + ${npm-version} + + + ${maven.groupId} + ${project.artifactId} + ${npm-version} + provided + sources + + + + diff --git a/generator/io.vertx/vertx-auth-properties/pom.xml b/generator/io.vertx/vertx-auth-properties/pom.xml index dcc27a8be..3a958a35d 100644 --- a/generator/io.vertx/vertx-auth-properties/pom.xml +++ b/generator/io.vertx/vertx-auth-properties/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-auth-properties - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-auth-shiro/pom.xml b/generator/io.vertx/vertx-auth-shiro/pom.xml index 03f9e1da0..30f5f0051 100644 --- a/generator/io.vertx/vertx-auth-shiro/pom.xml +++ b/generator/io.vertx/vertx-auth-shiro/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-auth-shiro - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-auth-sql-client/pom.xml b/generator/io.vertx/vertx-auth-sql-client/pom.xml index e72fb7160..a88c64e3d 100644 --- a/generator/io.vertx/vertx-auth-sql-client/pom.xml +++ b/generator/io.vertx/vertx-auth-sql-client/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-auth-sql-client - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-auth-webauthn/WebauthnCredentials.includes.json b/generator/io.vertx/vertx-auth-webauthn/WebauthnCredentials.includes.json new file mode 100644 index 000000000..2270d45fd --- /dev/null +++ b/generator/io.vertx/vertx-auth-webauthn/WebauthnCredentials.includes.json @@ -0,0 +1,4 @@ +{ + "import": "import { Credentials } from '@vertx/auth-common';\n", + "dataObjectImplements": "Credentials" +} diff --git a/generator/io.vertx/vertx-auth-webauthn/pom.xml b/generator/io.vertx/vertx-auth-webauthn/pom.xml index b91c50f8c..8c43b01ef 100644 --- a/generator/io.vertx/vertx-auth-webauthn/pom.xml +++ b/generator/io.vertx/vertx-auth-webauthn/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-auth-webauthn - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-bridge-common/pom.xml b/generator/io.vertx/vertx-bridge-common/pom.xml index 3e4682e0c..9759ade91 100644 --- a/generator/io.vertx/vertx-bridge-common/pom.xml +++ b/generator/io.vertx/vertx-bridge-common/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-bridge-common - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-camel-bridge/pom.xml b/generator/io.vertx/vertx-camel-bridge/pom.xml index 87605a689..304800c9c 100644 --- a/generator/io.vertx/vertx-camel-bridge/pom.xml +++ b/generator/io.vertx/vertx-camel-bridge/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-camel-bridge - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-cassandra-client/pom.xml b/generator/io.vertx/vertx-cassandra-client/pom.xml index 4c7ce007d..c861f4c17 100644 --- a/generator/io.vertx/vertx-cassandra-client/pom.xml +++ b/generator/io.vertx/vertx-cassandra-client/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-cassandra-client - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-circuit-breaker/pom.xml b/generator/io.vertx/vertx-circuit-breaker/pom.xml index c9c6e4a7f..2ed3477c2 100644 --- a/generator/io.vertx/vertx-circuit-breaker/pom.xml +++ b/generator/io.vertx/vertx-circuit-breaker/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-circuit-breaker - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-config/pom.xml b/generator/io.vertx/vertx-config/pom.xml index 99ce9bc3a..5c49dee3c 100644 --- a/generator/io.vertx/vertx-config/pom.xml +++ b/generator/io.vertx/vertx-config/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-config - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-consul-client/pom.xml b/generator/io.vertx/vertx-consul-client/pom.xml index 12ced9a9f..6d21f0fa2 100644 --- a/generator/io.vertx/vertx-consul-client/pom.xml +++ b/generator/io.vertx/vertx-consul-client/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-consul-client - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-core/pom.xml b/generator/io.vertx/vertx-core/pom.xml index 4e8b6cb59..de2f04817 100644 --- a/generator/io.vertx/vertx-core/pom.xml +++ b/generator/io.vertx/vertx-core/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-core - 0.15.0 + 0.16.0 1.7.30 diff --git a/generator/io.vertx/vertx-db2-client/pom.xml b/generator/io.vertx/vertx-db2-client/pom.xml index 395fb4a40..c0538775f 100644 --- a/generator/io.vertx/vertx-db2-client/pom.xml +++ b/generator/io.vertx/vertx-db2-client/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-db2-client - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-dropwizard-metrics/pom.xml b/generator/io.vertx/vertx-dropwizard-metrics/pom.xml index 4cbf3d327..a6829009f 100644 --- a/generator/io.vertx/vertx-dropwizard-metrics/pom.xml +++ b/generator/io.vertx/vertx-dropwizard-metrics/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-dropwizard-metrics - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-grpc/pom.xml b/generator/io.vertx/vertx-grpc/pom.xml index 2cb6eff8a..00972d980 100644 --- a/generator/io.vertx/vertx-grpc/pom.xml +++ b/generator/io.vertx/vertx-grpc/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-grpc - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-health-check/pom.xml b/generator/io.vertx/vertx-health-check/pom.xml index eda59f393..6c51e830b 100644 --- a/generator/io.vertx/vertx-health-check/pom.xml +++ b/generator/io.vertx/vertx-health-check/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-health-check - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-http-proxy/pom.xml b/generator/io.vertx/vertx-http-proxy/pom.xml new file mode 100644 index 000000000..c2759d581 --- /dev/null +++ b/generator/io.vertx/vertx-http-proxy/pom.xml @@ -0,0 +1,48 @@ + + + + + io.reactiverse.es4x + es4x-generator + 0.16.0 + ../.. + + + 4.0.0 + + vertx-http-proxy + 0.16.0 + + + io.vertx + @vertx/http-proxy + ${stack.version} + false + + + + { + "@vertx/core": "${stack.version}" + } + + + + + + + ${maven.groupId} + ${project.artifactId} + ${npm-version} + + + ${maven.groupId} + ${project.artifactId} + ${npm-version} + provided + sources + + + + diff --git a/generator/io.vertx/vertx-jdbc-client/pom.xml b/generator/io.vertx/vertx-jdbc-client/pom.xml index 92887cb73..d38604e54 100644 --- a/generator/io.vertx/vertx-jdbc-client/pom.xml +++ b/generator/io.vertx/vertx-jdbc-client/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-jdbc-client - 0.15.0 + 0.16.0 io.vertx @@ -59,7 +59,7 @@ io.agroal agroal-pool - 1.11 + 1.12 true diff --git a/generator/io.vertx/vertx-json-schema/pom.xml b/generator/io.vertx/vertx-json-schema/pom.xml index ac6fc50c2..f23232ec6 100644 --- a/generator/io.vertx/vertx-json-schema/pom.xml +++ b/generator/io.vertx/vertx-json-schema/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-json-schema - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-kafka-client/pom.xml b/generator/io.vertx/vertx-kafka-client/pom.xml index d6342bb5a..ccbaefda4 100644 --- a/generator/io.vertx/vertx-kafka-client/pom.xml +++ b/generator/io.vertx/vertx-kafka-client/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-kafka-client - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-mail-client/pom.xml b/generator/io.vertx/vertx-mail-client/pom.xml index 23e2b5d69..d6c88a732 100644 --- a/generator/io.vertx/vertx-mail-client/pom.xml +++ b/generator/io.vertx/vertx-mail-client/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-mail-client - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-micrometer-metrics/pom.xml b/generator/io.vertx/vertx-micrometer-metrics/pom.xml index a36091c9f..bd9adc7eb 100644 --- a/generator/io.vertx/vertx-micrometer-metrics/pom.xml +++ b/generator/io.vertx/vertx-micrometer-metrics/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-micrometer-metrics - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-mongo-client/pom.xml b/generator/io.vertx/vertx-mongo-client/pom.xml index f6d50d1b9..ee0fc2ae4 100644 --- a/generator/io.vertx/vertx-mongo-client/pom.xml +++ b/generator/io.vertx/vertx-mongo-client/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-mongo-client - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-mqtt/pom.xml b/generator/io.vertx/vertx-mqtt/pom.xml index 33e2642d1..e3c394175 100644 --- a/generator/io.vertx/vertx-mqtt/pom.xml +++ b/generator/io.vertx/vertx-mqtt/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-mqtt - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-mssql-client/pom.xml b/generator/io.vertx/vertx-mssql-client/pom.xml index db51beb15..8dc2852db 100644 --- a/generator/io.vertx/vertx-mssql-client/pom.xml +++ b/generator/io.vertx/vertx-mssql-client/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-mssql-client - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-mysql-client/pom.xml b/generator/io.vertx/vertx-mysql-client/pom.xml index 003b8aaa3..6fcaf0f01 100644 --- a/generator/io.vertx/vertx-mysql-client/pom.xml +++ b/generator/io.vertx/vertx-mysql-client/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-mysql-client - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-opentracing/pom.xml b/generator/io.vertx/vertx-opentracing/pom.xml index a86b97119..70f0aaa6f 100644 --- a/generator/io.vertx/vertx-opentracing/pom.xml +++ b/generator/io.vertx/vertx-opentracing/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-opentracing - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-oracle-client/pom.xml b/generator/io.vertx/vertx-oracle-client/pom.xml new file mode 100644 index 000000000..09adc87b2 --- /dev/null +++ b/generator/io.vertx/vertx-oracle-client/pom.xml @@ -0,0 +1,49 @@ + + + + + io.reactiverse.es4x + es4x-generator + 0.16.0 + ../.. + + + 4.0.0 + + vertx-oracle-client + 0.16.0 + + + io.vertx + @vertx/oracle-client + ${stack.version} + false + + + + { + "@vertx/core": "${stack.version}", + "@vertx/sql-client": "${stack.version}" + } + + + + + + + ${maven.groupId} + ${project.artifactId} + ${npm-version} + + + ${maven.groupId} + ${project.artifactId} + ${npm-version} + provided + sources + + + + diff --git a/generator/io.vertx/vertx-pg-client/pom.xml b/generator/io.vertx/vertx-pg-client/pom.xml index 6da17f1e5..a905ffcaa 100644 --- a/generator/io.vertx/vertx-pg-client/pom.xml +++ b/generator/io.vertx/vertx-pg-client/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-pg-client - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-proton/pom.xml b/generator/io.vertx/vertx-proton/pom.xml index dc5fc34c9..651500dc3 100644 --- a/generator/io.vertx/vertx-proton/pom.xml +++ b/generator/io.vertx/vertx-proton/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-proton - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-rabbitmq-client/pom.xml b/generator/io.vertx/vertx-rabbitmq-client/pom.xml index ecbb255f4..1d9b0a8ac 100644 --- a/generator/io.vertx/vertx-rabbitmq-client/pom.xml +++ b/generator/io.vertx/vertx-rabbitmq-client/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-rabbitmq-client - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-redis-client/pom.xml b/generator/io.vertx/vertx-redis-client/pom.xml index 58819289b..984070cec 100644 --- a/generator/io.vertx/vertx-redis-client/pom.xml +++ b/generator/io.vertx/vertx-redis-client/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-redis-client - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-service-discovery/pom.xml b/generator/io.vertx/vertx-service-discovery/pom.xml index a49d461b9..4a6a57f90 100644 --- a/generator/io.vertx/vertx-service-discovery/pom.xml +++ b/generator/io.vertx/vertx-service-discovery/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-service-discovery - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-service-proxy/pom.xml b/generator/io.vertx/vertx-service-proxy/pom.xml index 943a51f3a..78a7fdc99 100644 --- a/generator/io.vertx/vertx-service-proxy/pom.xml +++ b/generator/io.vertx/vertx-service-proxy/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-service-proxy - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-shell/pom.xml b/generator/io.vertx/vertx-shell/pom.xml index 0a3ece339..36f935848 100644 --- a/generator/io.vertx/vertx-shell/pom.xml +++ b/generator/io.vertx/vertx-shell/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-shell - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-sql-client-templates/pom.xml b/generator/io.vertx/vertx-sql-client-templates/pom.xml index 6b19d9471..c4735fd2f 100644 --- a/generator/io.vertx/vertx-sql-client-templates/pom.xml +++ b/generator/io.vertx/vertx-sql-client-templates/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-sql-client-templates - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-sql-client/pom.xml b/generator/io.vertx/vertx-sql-client/pom.xml index f809aca9a..126f10409 100644 --- a/generator/io.vertx/vertx-sql-client/pom.xml +++ b/generator/io.vertx/vertx-sql-client/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-sql-client - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-stomp/pom.xml b/generator/io.vertx/vertx-stomp/pom.xml index 02db97e83..08c4f9e79 100644 --- a/generator/io.vertx/vertx-stomp/pom.xml +++ b/generator/io.vertx/vertx-stomp/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-stomp - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-tcp-eventbus-bridge/pom.xml b/generator/io.vertx/vertx-tcp-eventbus-bridge/pom.xml index db85da368..c7de74a5b 100644 --- a/generator/io.vertx/vertx-tcp-eventbus-bridge/pom.xml +++ b/generator/io.vertx/vertx-tcp-eventbus-bridge/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-tcp-eventbus-bridge - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-unit/pom.xml b/generator/io.vertx/vertx-unit/pom.xml index 0815450a5..2c3c491c4 100644 --- a/generator/io.vertx/vertx-unit/pom.xml +++ b/generator/io.vertx/vertx-unit/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-unit - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-web-api-contract/pom.xml b/generator/io.vertx/vertx-web-api-contract/pom.xml index 4f3a6ac3f..c0b3c81ff 100644 --- a/generator/io.vertx/vertx-web-api-contract/pom.xml +++ b/generator/io.vertx/vertx-web-api-contract/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-web-api-contract - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-web-api-service/pom.xml b/generator/io.vertx/vertx-web-api-service/pom.xml index 489904c25..3c48bc275 100644 --- a/generator/io.vertx/vertx-web-api-service/pom.xml +++ b/generator/io.vertx/vertx-web-api-service/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-web-api-service - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-web-client/pom.xml b/generator/io.vertx/vertx-web-client/pom.xml index cf24c1c76..adef4962c 100644 --- a/generator/io.vertx/vertx-web-client/pom.xml +++ b/generator/io.vertx/vertx-web-client/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-web-client - 0.15.0 + 0.16.0 io.vertx @@ -27,9 +27,23 @@ "@vertx/web-common": "${stack.version}" } + + + { + "@vertx/auth-oauth2": "${stack.version}" + } + + + ["@vertx/auth-oauth2"] + + io.vertx + vertx-auth-oauth2 + ${stack.version} + true + ${maven.groupId} diff --git a/generator/io.vertx/vertx-web-common/pom.xml b/generator/io.vertx/vertx-web-common/pom.xml index 2ce8936e7..957a6b636 100644 --- a/generator/io.vertx/vertx-web-common/pom.xml +++ b/generator/io.vertx/vertx-web-common/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-web-common - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-web-graphql/pom.xml b/generator/io.vertx/vertx-web-graphql/pom.xml index 64bde8844..1df38f35e 100644 --- a/generator/io.vertx/vertx-web-graphql/pom.xml +++ b/generator/io.vertx/vertx-web-graphql/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-web-graphql - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-web-openapi/pom.xml b/generator/io.vertx/vertx-web-openapi/pom.xml index eca2347db..241112db2 100644 --- a/generator/io.vertx/vertx-web-openapi/pom.xml +++ b/generator/io.vertx/vertx-web-openapi/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-web-openapi - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-web-sstore-cookie/pom.xml b/generator/io.vertx/vertx-web-sstore-cookie/pom.xml index 13388f761..b30f6c763 100644 --- a/generator/io.vertx/vertx-web-sstore-cookie/pom.xml +++ b/generator/io.vertx/vertx-web-sstore-cookie/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-web-sstore-cookie - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-web-sstore-redis/pom.xml b/generator/io.vertx/vertx-web-sstore-redis/pom.xml index f5770563f..489840ecc 100644 --- a/generator/io.vertx/vertx-web-sstore-redis/pom.xml +++ b/generator/io.vertx/vertx-web-sstore-redis/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-web-sstore-redis - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-web-templ-freemarker/pom.xml b/generator/io.vertx/vertx-web-templ-freemarker/pom.xml index f5e3691df..1456cb1f2 100644 --- a/generator/io.vertx/vertx-web-templ-freemarker/pom.xml +++ b/generator/io.vertx/vertx-web-templ-freemarker/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-web-templ-freemarker - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-web-templ-handlebars/pom.xml b/generator/io.vertx/vertx-web-templ-handlebars/pom.xml index d82e41b42..57b5b4367 100644 --- a/generator/io.vertx/vertx-web-templ-handlebars/pom.xml +++ b/generator/io.vertx/vertx-web-templ-handlebars/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-web-templ-handlebars - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-web-templ-httl/pom.xml b/generator/io.vertx/vertx-web-templ-httl/pom.xml index 3391870c1..a9eccae0c 100644 --- a/generator/io.vertx/vertx-web-templ-httl/pom.xml +++ b/generator/io.vertx/vertx-web-templ-httl/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-web-templ-httl - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-web-templ-jade/pom.xml b/generator/io.vertx/vertx-web-templ-jade/pom.xml index 61d3e23fd..93f937736 100644 --- a/generator/io.vertx/vertx-web-templ-jade/pom.xml +++ b/generator/io.vertx/vertx-web-templ-jade/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-web-templ-jade - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-web-templ-jte/pom.xml b/generator/io.vertx/vertx-web-templ-jte/pom.xml index b528eecb6..34c6124cf 100644 --- a/generator/io.vertx/vertx-web-templ-jte/pom.xml +++ b/generator/io.vertx/vertx-web-templ-jte/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-web-templ-jte - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-web-templ-mvel/pom.xml b/generator/io.vertx/vertx-web-templ-mvel/pom.xml index 8ab86bf60..cb39faa40 100644 --- a/generator/io.vertx/vertx-web-templ-mvel/pom.xml +++ b/generator/io.vertx/vertx-web-templ-mvel/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-web-templ-mvel - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-web-templ-pebble/pom.xml b/generator/io.vertx/vertx-web-templ-pebble/pom.xml index 1be8450fe..c65535ef2 100644 --- a/generator/io.vertx/vertx-web-templ-pebble/pom.xml +++ b/generator/io.vertx/vertx-web-templ-pebble/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-web-templ-pebble - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-web-templ-rocker/pom.xml b/generator/io.vertx/vertx-web-templ-rocker/pom.xml index 00f83460b..7fd29f5ee 100644 --- a/generator/io.vertx/vertx-web-templ-rocker/pom.xml +++ b/generator/io.vertx/vertx-web-templ-rocker/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-web-templ-rocker - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-web-templ-rythm/pom.xml b/generator/io.vertx/vertx-web-templ-rythm/pom.xml index c09defe34..1df68a092 100644 --- a/generator/io.vertx/vertx-web-templ-rythm/pom.xml +++ b/generator/io.vertx/vertx-web-templ-rythm/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-web-templ-rythm - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-web-templ-thymeleaf/pom.xml b/generator/io.vertx/vertx-web-templ-thymeleaf/pom.xml index de3c49da4..e00678314 100644 --- a/generator/io.vertx/vertx-web-templ-thymeleaf/pom.xml +++ b/generator/io.vertx/vertx-web-templ-thymeleaf/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-web-templ-thymeleaf - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-web-validation/pom.xml b/generator/io.vertx/vertx-web-validation/pom.xml index da382d11a..78b42719a 100644 --- a/generator/io.vertx/vertx-web-validation/pom.xml +++ b/generator/io.vertx/vertx-web-validation/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-web-validation - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/io.vertx/vertx-web/pom.xml b/generator/io.vertx/vertx-web/pom.xml index 36d0f71c0..b7c8f9c83 100644 --- a/generator/io.vertx/vertx-web/pom.xml +++ b/generator/io.vertx/vertx-web/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-web - 0.15.0 + 0.16.0 io.vertx @@ -34,11 +34,13 @@ { "@vertx/auth-htdigest": "${stack.version}", "@vertx/auth-jwt": "${stack.version}", - "@vertx/auth-oauth2": "${stack.version}" + "@vertx/auth-oauth2": "${stack.version}", + "@vertx/auth-webauthn": "${stack.version}", + "@vertx/auth-otp": "${stack.version}" } - ["@vertx/auth-htdigest", "@vertx/auth-jwt", "@vertx/auth-oauth2", "@vertx/auth-webauthn"] + ["@vertx/auth-htdigest", "@vertx/auth-jwt", "@vertx/auth-oauth2", "@vertx/auth-webauthn", "@vertx/auth-otp"] ["io.vertx.ext.web.handler.sockjs.PermittedOptions"] @@ -68,6 +70,12 @@ ${stack.version} true + + io.vertx + vertx-auth-otp + ${stack.version} + true + ${maven.groupId} diff --git a/generator/io.vertx/vertx-zipkin/pom.xml b/generator/io.vertx/vertx-zipkin/pom.xml index b2d04ba0b..7578b1d33 100644 --- a/generator/io.vertx/vertx-zipkin/pom.xml +++ b/generator/io.vertx/vertx-zipkin/pom.xml @@ -6,14 +6,14 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. 4.0.0 vertx-zipkin - 0.15.0 + 0.16.0 io.vertx diff --git a/generator/pom.xml b/generator/pom.xml index 9d82e92de..90a77b43a 100644 --- a/generator/pom.xml +++ b/generator/pom.xml @@ -6,13 +6,13 @@ io.reactiverse es4x-parent - 0.15.0 + 0.16.0 .. io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 pom @@ -62,7 +62,7 @@ io.vertx - + @@ -81,6 +81,7 @@ io.vertx/vertx-auth-shiro io.vertx/vertx-auth-sql-client io.vertx/vertx-auth-webauthn + io.vertx/vertx-auth-otp io.vertx/vertx-bridge-common io.vertx/vertx-camel-bridge io.vertx/vertx-cassandra-client @@ -89,6 +90,7 @@ io.vertx/vertx-consul-client io.vertx/vertx-core io.vertx/vertx-db2-client + io.vertx/vertx-oracle-client io.vertx/vertx-dropwizard-metrics io.vertx/vertx-grpc io.vertx/vertx-health-check @@ -135,6 +137,7 @@ io.vertx/vertx-web-templ-thymeleaf io.vertx/vertx-web-validation io.vertx/vertx-zipkin + io.vertx/vertx-http-proxy io.vertx @@ -143,6 +146,7 @@ io.reactiverse io.reactiverse/elasticsearch-client + io.reactiverse/reactiverse-contextual-logging @@ -269,7 +273,7 @@ vertx-docgen provided true - 0.9.3 + 0.9.4 diff --git a/generator/xyz.jetdrone/hot-reload/pom.xml b/generator/xyz.jetdrone/hot-reload/pom.xml index 0da8d33dc..e470cc307 100644 --- a/generator/xyz.jetdrone/hot-reload/pom.xml +++ b/generator/xyz.jetdrone/hot-reload/pom.xml @@ -8,18 +8,18 @@ io.reactiverse.es4x es4x-generator - 0.15.0 + 0.16.0 ../.. hot-reload - 0.15.0 + 0.16.0 jar xyz.jetdrone - 0.0.5 + 0.0.6 false diff --git a/package.json b/package.json index 776717c8a..f0e135966 100644 --- a/package.json +++ b/package.json @@ -3,9 +3,9 @@ "version": "1.0.0", "private": true, "dependencies": { - "typedoc": "^0.20.36", - "typescript": "^4.3.2", - "vuepress": "^1.8.2" + "typedoc": "0.19.2", + "typescript": "4.0.8", + "vuepress": "1.8.2" }, "scripts": { "docs:tsdocs": "cd generator && ./build.sh tsdocs", diff --git a/pm/pom.xml b/pm/pom.xml index 0169d9d14..299b53f30 100644 --- a/pm/pom.xml +++ b/pm/pom.xml @@ -4,21 +4,21 @@ io.reactiverse es4x-parent - 0.15.0 + 0.16.0 .. 4.0.0 es4x-pm - 0.15.0 + 0.16.0 UTF-8 1.7.0 3.8.1 1.7.30 - 9.1 + 9.2 diff --git a/pm/src/assembly/bin/es4x b/pm/src/assembly/bin/es4x index 85f077fb7..325e4e02b 100644 --- a/pm/src/assembly/bin/es4x +++ b/pm/src/assembly/bin/es4x @@ -30,7 +30,17 @@ else fi fi -if [ ! -f "node_modules/es4x_install_successful" ]; then +# if package.json exists then prefix is node_modules +# and binDir is hidden to respect npm semantics +if [[ -f "package.json" ]]; then + PREFIX="node_modules" + BINDIR="$PREFIX/.bin" +else + PREFIX="" + BINDIR="bin" +fi + +if [ ! -f "$BINDIR/es4x-launcher.jar" ]; then "$JAVA_EXE" $JAVA_OPTS -Dsilent-install -jar "$basedir/../es4x-pm-${project.version}.jar" "$@" EXIT_STATUS=$? if [[ "$EXIT_STATUS" -ne "0" ]]; then @@ -39,8 +49,8 @@ if [ ! -f "node_modules/es4x_install_successful" ]; then fi # Use JVMCI if installed -if [[ -d "node_modules/.jvmci" ]]; then - JVMCI="--module-path=node_modules/.jvmci -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI --upgrade-module-path=node_modules/.jvmci/compiler.jar" +if [[ -d "$PREFIX/.jvmci" ]]; then + JVMCI="--module-path=$PREFIX/.jvmci -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI --upgrade-module-path=$PREFIX/.jvmci/compiler.jar" fi # If exists security.policy start the VM in secure mode @@ -53,9 +63,9 @@ if [[ -f "logging.properties" ]]; then LOGGING_PROPERTIES="-Djava.util.logging.config.file=logging.properties" fi -if [[ -f "node_modules/.bin/es4x-launcher.jar" ]]; then - exec "$JAVA_EXE" -XX:+IgnoreUnrecognizedVMOptions $JVMCI $SECURITY_MANAGER $LOGGING_PROPERTIES $JAVA_OPTS $TTY_OPTS -cp "node_modules/.bin/es4x-launcher.jar:$basedir/../es4x-pm-${project.version}.jar" io.reactiverse.es4x.ES4X "$@" +if [[ -f "$BINDIR/es4x-launcher.jar" ]]; then + exec "$JAVA_EXE" -XX:+IgnoreUnrecognizedVMOptions $JVMCI $SECURITY_MANAGER $LOGGING_PROPERTIES $JAVA_OPTS $TTY_OPTS -cp "$BINDIR/es4x-launcher.jar:$basedir/../es4x-pm-${project.version}.jar" io.reactiverse.es4x.ES4X "$@" else - echo "Missing node_modules/.bin/es4x-launcher.jar" >&2 + echo "Missing $BINDIR/es4x-launcher.jar" >&2 exit 3 fi diff --git a/pm/src/assembly/bin/es4x-cli.js b/pm/src/assembly/bin/es4x-cli.js index 006f5cac9..5401f86d3 100644 --- a/pm/src/assembly/bin/es4x-cli.js +++ b/pm/src/assembly/bin/es4x-cli.js @@ -15,12 +15,23 @@ if (process.env['JAVA_HOME']) { } } -if (!existsSync(path.join(process.cwd(), 'node_modules', 'es4x_install_successful'))) { +let prefix; +let binDir; + +if (existsSync(path.join(process.cwd(), 'package.json'))) { + prefix = "node_modules"; + binDir = path.join(prefix, ".bin"); +} else { + prefix = ""; + binDir = "bin"; +} + +if (!existsSync(path.join(process.cwd(), binDir, 'es4x-launcher.jar'))) { // classpath is incomplete we need to run the PM package let statusCode = spawnSync( java, - [ '-Dsilent-install', '-jar', `${path.join(__dirname, '..', pm)}`].concat(process.argv.slice(2)), + ['-Dsilent-install', '-jar', `${path.join(__dirname, '..', pm)}`].concat(process.argv.slice(2)), {cwd: process.cwd(), env: process.env, stdio: 'inherit'}).status; if (statusCode !== 0) { @@ -32,7 +43,7 @@ let argv = [ '-XX:+IgnoreUnrecognizedVMOptions' ]; -let jvmci = path.join('node_modules', '.jvmci'); +let jvmci = path.join(prefix, '.jvmci'); if (existsSync(path.join(process.cwd(), jvmci))) { argv.push(`--module-path=${jvmci}`); argv.push('-XX:+UnlockExperimentalVMOptions'); @@ -57,7 +68,7 @@ if (!process.stdout.isTTY) { argv.push('-cp'); -let launcher = path.join('node_modules', '.bin', 'es4x-launcher.jar'); +let launcher = path.join(binDir, 'es4x-launcher.jar'); if (existsSync(path.join(process.cwd(), launcher))) { argv.push(`${launcher}${path.delimiter}${path.join(__dirname, '..', pm)}`); argv.push('io.reactiverse.es4x.ES4X'); diff --git a/pm/src/assembly/bin/es4x.cmd b/pm/src/assembly/bin/es4x.cmd index 1fbb1376f..9375bd299 100644 --- a/pm/src/assembly/bin/es4x.cmd +++ b/pm/src/assembly/bin/es4x.cmd @@ -10,7 +10,15 @@ IF NOT EXIST "%JAVA_EXE%" ( SET "JAVA_EXE=java" ) -IF NOT EXIST "node_modules\es4x_install_successful" ( +IF EXIST "package.json" ( + SET "PREFIX=node_modules" + SET "BINDIR=node_modules\.bin" +) ELSE ( + SET "PREFIX=" + SET "BINDIR=bin" +) + +IF NOT EXIST "%BINDIR%\es4x-launcher.jar" ( %JAVA_EXE% %JAVA_OPTS% -Dsilent-install -jar %~dp0\..\es4x-pm-${project.version}.jar %* IF %ERRORLEVEL% NEQ 0 ( EXIT /B %ERRORLEVEL% @@ -18,8 +26,8 @@ IF NOT EXIST "node_modules\es4x_install_successful" ( ) :: Use JVMCI if installed -IF EXIST "node_modules\.jvmci" ( - SET "JVMCI=--module-path=node_modules\.jvmci -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI --upgrade-module-path=node_modules\.jvmci\compiler.jar" +IF EXIST "%PREFIX%\.jvmci" ( + SET "JVMCI=--module-path=%PREFIX%\.jvmci -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI --upgrade-module-path=%PREFIX%\.jvmci\compiler.jar" ) :: If exists security.policy start the VM in secure mode @@ -32,9 +40,9 @@ IF EXIST "logging.properties" ( SET "LOGGING_PROPERTIES=-Djava.util.logging.config.file=logging.properties" ) -IF EXIST "node_modules\.bin\es4x-launcher.jar" ( - %JAVA_EXE% -XX:+IgnoreUnrecognizedVMOptions %JVMCI% %SECURITY_MANAGER% %LOGGING_PROPERTIES% %JAVA_OPTS% -cp "node_modules\.bin\es4x-launcher.jar;%~dp0\..\es4x-pm-${project.version}.jar" io.reactiverse.es4x.ES4X %* +IF EXIST "%BINDIR%\es4x-launcher.jar" ( + %JAVA_EXE% -XX:+IgnoreUnrecognizedVMOptions %JVMCI% %SECURITY_MANAGER% %LOGGING_PROPERTIES% %JAVA_OPTS% -cp "%BINDIR%\es4x-launcher.jar;%~dp0\..\es4x-pm-${project.version}.jar" io.reactiverse.es4x.ES4X %* ) ELSE ( - ECHO "Missing node_modules\.bin\es4x-launcher.jar" + ECHO "Missing %BINDIR%\es4x-launcher.jar" EXIT /B 3 ) diff --git a/pm/src/main/java/io/reactiverse/es4x/cli/PM.java b/pm/src/main/java/io/reactiverse/es4x/cli/PM.java index e84eb8e57..3fd766463 100644 --- a/pm/src/main/java/io/reactiverse/es4x/cli/PM.java +++ b/pm/src/main/java/io/reactiverse/es4x/cli/PM.java @@ -143,7 +143,7 @@ public static void main(String[] args) { // then perform the silent install and let the control flow from the script if (System.getProperty("silent-install") != null) { verifyRuntime(true); - new Install().run(); + new Install(true).run(); System.exit(0); } else { verifyRuntime(false); diff --git a/pm/src/main/java/io/reactiverse/es4x/commands/Install.java b/pm/src/main/java/io/reactiverse/es4x/commands/Install.java index e5e077f42..5acbb42e4 100644 --- a/pm/src/main/java/io/reactiverse/es4x/commands/Install.java +++ b/pm/src/main/java/io/reactiverse/es4x/commands/Install.java @@ -37,6 +37,8 @@ public class Install implements Runnable { public static final String NAME = "install"; public static final String SUMMARY = "Installs required jars from maven to 'node_modules'."; + private final boolean silent; + enum Environment { PROD, PRODUCTION, @@ -45,32 +47,6 @@ enum Environment { ALL } - enum Mode { - NODE_MODULES("node_modules", "node_modules"), - IMPORT_MAP("import-map", null); - - final String baseDir; - final String name; - - Mode(String name, String baseDir) { - this.name = name; - this.baseDir = baseDir; - } - - File baseDir(File cwd) { - if (baseDir != null) { - return new File(cwd, baseDir); - } else { - return cwd; - } - } - - @Override - public String toString() { - return name; - } - } - private static final Properties VERSIONS = new Properties(); static { @@ -89,20 +65,21 @@ public String toString() { private List vendor; private File coreJar; private Environment environment = Environment.ALL; - private Mode mode = Mode.NODE_MODULES; private File cwd; - public Install() { + public Install(boolean silent) { + this.silent = silent; + this.cwd = new File("."); } public Install(String[] args) { + silent = false; CmdLineParser parser = new CmdLineParser(); CmdLineParser.Option helpOption = parser.addBooleanOption('h', "help"); CmdLineParser.Option vendorOption = parser.addStringOption('v', "vendor"); CmdLineParser.Option linkOption = parser.addBooleanOption('l', "link"); CmdLineParser.Option environmentOption = parser.addStringOption('e', "environment"); - CmdLineParser.Option destOption = parser.addStringOption('d', "dest"); try { parser.parse(args); @@ -127,7 +104,6 @@ public Install(String[] args) { setVendor(parser.getOptionValue(vendorOption)); setEnvironment(parser.getOptionValue(environmentOption, "all")); - setMode(parser.getOptionValue(destOption, "node_modules")); setCwd(new File(".")); } @@ -137,10 +113,8 @@ private void printUsage() { System.err.println(SUMMARY); System.err.println(); System.err.println("Options and Arguments:"); - System.err.println(" -e,--environment\t\t\t\tEnvironment 'prod[uction]/dev[elopment]' (default: all)."); - System.err.println(" -f,--force\t\t\t\tWill always install a basic runtime in the current working dir."); + System.err.println(" -e,--environment\t\t\t\tEnvironment 'prod[uction]/dev[elopment]/all' (default: all)."); System.err.println(" -l,--link\t\t\t\tSymlink jars instead of copy."); - System.err.println(" -m,--mode\t\t\t\tMode 'node_modules/import-map' (default: node_modules)."); System.err.println(" -v,--vendor \tComma separated list of vendor jars."); System.err.println(); } @@ -170,13 +144,7 @@ public void setEnvironment(String environment) { } } - public void setMode(String mode) { - if (mode != null) { - this.mode = Mode.valueOf(mode.toUpperCase().replace('-', '_')); - } - } - - private void processPackageJson(File json, Set dependencies) throws IOException { + private void processJson(File json, Set dependencies) throws IOException { if (json.exists()) { JSONObject npm = JSON.parseObject(json); if (npm.has("maven")) { @@ -226,7 +194,7 @@ private void processModules(File dir, Set dependencies) throws IOExcepti File json = new File(mod, "package.json"); // process - processPackageJson(json, dependencies); + processJson(json, dependencies); File submod = new File(mod, "node_modules"); if (submod.exists() && submod.isDirectory()) { @@ -236,19 +204,37 @@ private void processModules(File dir, Set dependencies) throws IOExcepti } } + private File baseDir; + private File binDir; + private boolean hasImportMap; + private boolean hasPackageJson; + @Override public void run() { + // mode is dependent on the availability of "package.json" + if (new File(cwd, "package.json").exists()) { + baseDir = new File(cwd, "node_modules"); + binDir = new File(baseDir, ".bin"); + hasPackageJson = true; + } else { + baseDir = cwd; + binDir = new File(baseDir, "bin"); + } + + hasImportMap = new File(cwd, "import-map.json").exists(); + final List artifacts = new ArrayList<>(); - final Runnable run = () -> { - switch (mode) { - case NODE_MODULES: - installNodeModules(artifacts); - return; - case IMPORT_MAP: - err("Not implemented"); - return; + final Runnable runAction = () -> { + if (hasPackageJson) { + installModules(artifacts, "package.json"); + } + if (hasImportMap) { + installModules(artifacts, "import-map.json"); + } + if (!hasPackageJson && !hasImportMap) { + installModules(artifacts, null); } if (!GraalVMVersion.isGraalVM()) { @@ -278,29 +264,26 @@ public void run() { createLauncher(artifacts); }; + // control + if (!hasPackageJson && !hasImportMap) { + if (!silent) { + fatal("Nothing to install, missing 'package.json' or 'import-map.json'"); + } + } + switch (environment) { case ALL: case DEV: case DEVELOPMENT: - File control = new File(mode.baseDir(cwd), "es4x_install_successful"); + File control = new File(baseDir, "es4x-launcher.jar"); if (control.exists()) { warn("Skipping install (recent successful run)"); return; } - run.run(); - // touch the control file - try (FileOutputStream fileOutputStream = new FileOutputStream(control)) { - for (String s : artifacts) { - fileOutputStream.write(s.getBytes(StandardCharsets.UTF_8)); - fileOutputStream.write('\n'); - } - } catch (IOException e) { - fatal(e.getMessage()); - } break; - default: - run.run(); } + + runAction.run(); } private static void addIfMissing(Collection collection, T element) { @@ -310,16 +293,14 @@ private static void addIfMissing(Collection collection, T element) { } private void installGraalJS(Collection artifacts) { - final File base = mode.baseDir(cwd); - - File lib = new File(base, ".lib"); + File lib = new File(baseDir, ".lib"); if (!lib.exists()) { if (!lib.mkdirs()) { fatal(String.format("Failed to mkdirs '%s'.", lib)); } } - File jvmci = new File(base, ".jvmci"); + File jvmci = new File(baseDir, ".jvmci"); try { Resolver resolver = new Resolver(); @@ -351,9 +332,7 @@ private void installGraalJS(Collection artifacts) { } private void installGraalJMVCICompiler() { - final File base = mode.baseDir(cwd); - - File jvmci = new File(base, ".jvmci"); + File jvmci = new File(baseDir, ".jvmci"); if (!jvmci.exists()) { if (!jvmci.mkdirs()) { fatal(String.format("Failed to mkdirs '%s'.", jvmci)); @@ -378,27 +357,30 @@ private void installGraalJMVCICompiler() { } } - private void installNodeModules(Collection artifacts) { - final File base = mode.baseDir(cwd); + private void installModules(Collection artifacts, String jsonProject) { final Set dependencies = new HashSet<>(); // process mvnDependencies from CWD package.json - try { - processPackageJson(new File(cwd, "package.json"), dependencies); - } catch (IOException e) { - fatal(e.getMessage()); - } - - // crawl node modules - if (base.exists() && base.isDirectory()) { + if (jsonProject != null) { try { - processModules(base, dependencies); + processJson(new File(cwd, jsonProject), dependencies); } catch (IOException e) { fatal(e.getMessage()); } + + // crawl node modules + if (!baseDir.equals(cwd)) { + if (baseDir.exists() && baseDir.isDirectory()) { + try { + processModules(baseDir, dependencies); + } catch (IOException e) { + fatal(e.getMessage()); + } + } + } } - File libs = new File(base, ".lib"); + File libs = new File(baseDir, ".lib"); try { Resolver resolver = new Resolver(); @@ -442,14 +424,14 @@ private void installNodeModules(Collection artifacts) { } private void createLauncher(Collection artifacts) { - File json = new File(cwd, "package.json"); - if (json.exists()) { + // default main script + String main = null; + String verticleFactory = "js"; + + if (hasPackageJson) { try { - JSONObject npm = JSON.parseObject(json); - // default main script - String main = "."; - String verticleFactory = "js"; + JSONObject npm = JSON.parseObject(new File(cwd, "package.json")); // if package json declares a different main, then it shall be used if (npm.has("main")) { @@ -460,89 +442,104 @@ private void createLauncher(Collection artifacts) { } } - // if package json declares a different main, then it shall be used - if (npm.has("module")) { - main = (String) npm.get("module"); - verticleFactory = "mjs"; - } - - final File base = mode.baseDir(cwd); - File bin = new File(base, ".bin"); - if (!bin.exists()) { - if (!bin.mkdirs()) { - fatal(String.format("Failed to mkdirs '%s'.", bin)); + // if package json declares a different type, then it shall be used + if (npm.has("type")) { + switch ((String) npm.get("module")) { + case "commonjs": + verticleFactory = "js"; + break; + case "module": + verticleFactory = "mjs"; + break; + default: + fatal("Unknown package.json type: " + npm.get("module")); } } + } catch (IOException e) { + fatal(e.getMessage()); + } + } - final Manifest manifest = new Manifest(); - final Attributes attributes = manifest.getMainAttributes(); - - attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0"); - attributes.put(new Attributes.Name("Created-By"), "ES4X " + VERSIONS.getProperty("es4x")); - attributes.put(new Attributes.Name("Built-By"), System.getProperty("user.name")); - attributes.put(new Attributes.Name("Build-Jdk"), System.getProperty("java.version")); - attributes.put(Attributes.Name.MAIN_CLASS, "io.reactiverse.es4x.ES4X"); - String classpath = String.join(" ", artifacts); - if (vendor != null && vendor.size() > 0) { - classpath += " " + String.join(" ", vendor); - } - attributes.put(Attributes.Name.CLASS_PATH, classpath); - attributes.put(new Attributes.Name("Main-Verticle"), main); - attributes.put(new Attributes.Name("Main-Command"), "run"); - attributes.put(new Attributes.Name("Default-Verticle-Factory"), verticleFactory); - attributes.put(new Attributes.Name("Import-Map"), mode.toString()); - - try (OutputStream os = new FileOutputStream(new File(bin, "es4x-launcher.jar"))) { - try (JarOutputStream target = new JarOutputStream(os, manifest)) { - if (coreJar != null) { - try (InputStream in = new FileInputStream(coreJar)) { - try (JarInputStream jar = new JarInputStream(in)) { - JarEntry je; - while ((je = jar.getNextJarEntry()) != null) { - switch (je.getName()) { - case "io/vertx/core/json/JsonObject.class": - target.putNextEntry(je); - target.write(new JsonObjectVisitor().rewrite(jar)); - target.closeEntry(); - break; - case "io/vertx/core/json/JsonArray.class": - target.putNextEntry(je); - target.write(new JsonArrayVisitor().rewrite(jar)); - target.closeEntry(); - break; - case "io/vertx/core/impl/future/FutureBase.class": - target.putNextEntry(je); - target.write(new FutureBaseVisitor().rewrite(jar)); - target.closeEntry(); - break; - } + if (!binDir.exists()) { + if (!binDir.mkdirs()) { + fatal(String.format("Failed to mkdirs '%s'.", binDir)); + } + } + + final Manifest manifest = new Manifest(); + final Attributes attributes = manifest.getMainAttributes(); + + attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0"); + attributes.put(new Attributes.Name("Created-By"), "ES4X " + VERSIONS.getProperty("es4x")); + attributes.put(new Attributes.Name("Built-By"), System.getProperty("user.name")); + attributes.put(new Attributes.Name("Build-Jdk"), System.getProperty("java.version")); + attributes.put(Attributes.Name.MAIN_CLASS, "io.reactiverse.es4x.ES4X"); + String classpath = String.join(" ", artifacts); + if (vendor != null && vendor.size() > 0) { + classpath += " " + String.join(" ", vendor); + } + attributes.put(Attributes.Name.CLASS_PATH, classpath); + if (main != null) { + attributes.put(new Attributes.Name("Main-Command"), "run"); + attributes.put(new Attributes.Name("Main-Verticle"), main); + } + attributes.put(new Attributes.Name("Default-Verticle-Factory"), verticleFactory); + if (hasImportMap) { + attributes.put(new Attributes.Name("Import-Map"), "import-map.json"); + } + + try { + try (OutputStream os = new FileOutputStream(new File(binDir, "es4x-launcher.jar"))) { + try (JarOutputStream target = new JarOutputStream(os, manifest)) { + if (coreJar != null) { + try (InputStream in = new FileInputStream(coreJar)) { + try (JarInputStream jar = new JarInputStream(in)) { + JarEntry je; + while ((je = jar.getNextJarEntry()) != null) { + switch (je.getName()) { + case "io/vertx/core/json/JsonObject.class": + target.putNextEntry(je); + target.write(new JsonObjectVisitor().rewrite(jar)); + target.closeEntry(); + break; + case "io/vertx/core/json/JsonArray.class": + target.putNextEntry(je); + target.write(new JsonArrayVisitor().rewrite(jar)); + target.closeEntry(); + break; + case "io/vertx/core/impl/future/FutureBase.class": + target.putNextEntry(je); + target.write(new FutureBaseVisitor().rewrite(jar)); + target.closeEntry(); + break; } - } catch (RuntimeException e) { - warn(e.getMessage()); } } catch (RuntimeException e) { warn(e.getMessage()); } + } catch (RuntimeException e) { + warn(e.getMessage()); } } } + } - // create the launcher scripts - if (isUnix()) { - createUNIXScript(bin); - } - if (isWindows()) { - createDOSScript(bin); - } - - } catch (IOException e) { - fatal(e.getMessage()); + // create the launcher scripts + if (isUnix()) { + createUNIXScript(binDir); } + if (isWindows()) { + createDOSScript(binDir); + } + } catch (IOException e) { + fatal(e.getMessage()); } } private void createUNIXScript(File bin) throws IOException { + String relPath = baseDir.equals(cwd) ? ".." : "../.."; + String script = "#!/usr/bin/env bash\n" + "(set -o igncr) 2>/dev/null && set -o igncr; # cygwin encoding fix\n" + @@ -575,12 +572,12 @@ private void createUNIXScript(File bin) throws IOException { " JVMCI=\"--module-path=$basedir/../.jvmci -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI --upgrade-module-path=$basedir/../.jvmci/compiler.jar\"\n" + "fi\n" + "\n" + - "if [[ -f \"$basedir/../../security.policy\" ]]; then\n" + - " SECURITY_MANAGER=\"-Djava.security.manager -Djava.security.policy=$basedir/../../security.policy\"\n" + + "if [[ -f \"$basedir/" + relPath + "/security.policy\" ]]; then\n" + + " SECURITY_MANAGER=\"-Djava.security.manager -Djava.security.policy=$basedir/" + relPath + "/security.policy\"\n" + "fi\n" + "\n" + - "if [[ -f \"$basedir/../../logging.properties\" ]]; then\n" + - " LOGGING_PROPERTIES=\"-Djava.util.logging.config.file=$basedir/../../logging.properties\"\n" + + "if [[ -f \"$basedir/" + relPath + "/logging.properties\" ]]; then\n" + + " LOGGING_PROPERTIES=\"-Djava.util.logging.config.file=$basedir/" + relPath + "/logging.properties\"\n" + "fi\n" + "\n" + "exec \"$JAVA_EXE\" -XX:+IgnoreUnrecognizedVMOptions $JVMCI $SECURITY_MANAGER $LOGGING_PROPERTIES $JAVA_OPTS $TTY_OPTS -jar \"$basedir/es4x-launcher.jar\" \"$@\"\n"; @@ -598,6 +595,9 @@ private void createUNIXScript(File bin) throws IOException { private void createDOSScript(File bin) throws IOException { + String relPath = baseDir.equals(cwd) ? ".." : "..\\.."; + + String script = "@ECHO OFF\n" + "\n" + @@ -612,12 +612,12 @@ private void createDOSScript(File bin) throws IOException { " SET \"JVMCI=--module-path=\"\"%~dp0\\..\\.jvmci\"\" -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI --upgrade-module-path=\"\"%~dp0\\..\\.jvmci\\compiler.jar\"\"\"\n" + ")\n" + "\n" + - "IF EXIST \"%~dp0\\..\\..\\security.policy\" (\n" + - " SET \"SECURITY_MANAGER=-Djava.security.manager -Djava.security.policy=\"\"%~dp0\\..\\..\\security.policy\"\"\"\n" + + "IF EXIST \"%~dp0\\" + relPath + "\\security.policy\" (\n" + + " SET \"SECURITY_MANAGER=-Djava.security.manager -Djava.security.policy=\"\"%~dp0\\" + relPath + "\\security.policy\"\"\"\n" + ")\n" + "\n" + - "IF EXIST \"%~dp0\\..\\..\\logging.properties\" (\n" + - " SET \"LOGGING_PROPERTIES=-Djava.util.logging.config.file=\"\"%~dp0\\..\\..\\logging.properties\"\"\"\n" + + "IF EXIST \"%~dp0\\" + relPath + "\\logging.properties\" (\n" + + " SET \"LOGGING_PROPERTIES=-Djava.util.logging.config.file=\"\"%~dp0\\" + relPath + "\\logging.properties\"\"\"\n" + ")\n" + "\n" + "\"%JAVA_EXE%\" -XX:+IgnoreUnrecognizedVMOptions %JVMCI% %SECURITY_MANAGER% %LOGGING_PROPERTIES% %JAVA_OPTS% -jar \"%~dp0\\es4x-launcher.jar\" %*\n"; diff --git a/pm/src/main/java/io/reactiverse/es4x/commands/InstallCommand.java b/pm/src/main/java/io/reactiverse/es4x/commands/InstallCommand.java index 870aab3fa..9833dd9a4 100644 --- a/pm/src/main/java/io/reactiverse/es4x/commands/InstallCommand.java +++ b/pm/src/main/java/io/reactiverse/es4x/commands/InstallCommand.java @@ -23,7 +23,7 @@ @Summary(Install.SUMMARY) public class InstallCommand extends DefaultCommand { - private final Install command = new Install(); + private final Install command = new Install(false); @Option(longName = "vendor", shortName = "v") @Description("Comma separated list of vendor jars.") @@ -44,13 +44,6 @@ public void setEnvironment(String environment) { command.setEnvironment(environment); } - @Option(longName = "mode", shortName = "m") - @Description("Mode 'node_modules/import-map' (default: node_modules).") - @DefaultValue("node_modules") - public void setMode(String mode) { - command.setMode(mode); - } - @Override public void run() throws CLIException { command diff --git a/pm/src/main/java/io/reactiverse/es4x/commands/Project.java b/pm/src/main/java/io/reactiverse/es4x/commands/Project.java index 1e669ce95..4ef3c222f 100644 --- a/pm/src/main/java/io/reactiverse/es4x/commands/Project.java +++ b/pm/src/main/java/io/reactiverse/es4x/commands/Project.java @@ -32,6 +32,7 @@ public class Project implements Runnable { private File cwd; private boolean typeScript; + private boolean importMap; public Project() { } @@ -39,6 +40,7 @@ public Project() { public Project(String[] args) { CmdLineParser parser = new CmdLineParser(); CmdLineParser.Option helpOption = parser.addBooleanOption('h', "help"); + CmdLineParser.Option importMapOption = parser.addBooleanOption('i', "importmap"); CmdLineParser.Option tsOption = parser.addBooleanOption('t', "ts"); try { @@ -61,6 +63,10 @@ public Project(String[] args) { if (typeScript != null && typeScript) { setTypeScript(true); } + Boolean importMap = parser.getOptionValue(importMapOption, Boolean.FALSE); + if (importMap != null && importMap) { + setImportMap(true); + } String[] commandArgs = parser.getRemainingArgs(); @@ -92,6 +98,7 @@ private void printUsage() { System.err.println(SUMMARY); System.err.println(); System.err.println("Options and Arguments:"); + System.err.println(" -i,--importmap\t\t\tCreate a import-map.json instead of package.json."); System.err.println(" -t,--ts\t\t\t\tCreate a TypeScript project instead of JavaScript."); System.err.println(); } @@ -105,26 +112,30 @@ public void setTypeScript(boolean typeScript) { this.typeScript = typeScript; } + public void setImportMap(boolean importMap) { + this.importMap = importMap; + } + @Override public void run() { try { final File file = new File(cwd, "package.json"); if (file.exists()) { - fatal(file.toPath().toRealPath().toString() + " already exists!"); + fatal(file.toPath().toRealPath() + " already exists!"); } String[] templates = typeScript ? new String[] { - "META-INF/es4x-commands/init/ts/package.json", + importMap ? "META-INF/es4x-commands/init/ts/import-map.json" : "META-INF/es4x-commands/init/ts/package.json", "META-INF/es4x-commands/init/ts/index.ts", "META-INF/es4x-commands/init/ts/index.test.ts", "META-INF/es4x-commands/init/ts/tsconfig.json" } : new String[] { - "META-INF/es4x-commands/init/js/package.json", + importMap ? "META-INF/es4x-commands/init/js/import-map.json" : "META-INF/es4x-commands/init/js/package.json", "META-INF/es4x-commands/init/js/index.js", "META-INF/es4x-commands/init/js/index.test.js" }; diff --git a/pm/src/main/java/io/reactiverse/es4x/commands/ProjectCommand.java b/pm/src/main/java/io/reactiverse/es4x/commands/ProjectCommand.java index 7a2683bfd..afe882a10 100644 --- a/pm/src/main/java/io/reactiverse/es4x/commands/ProjectCommand.java +++ b/pm/src/main/java/io/reactiverse/es4x/commands/ProjectCommand.java @@ -29,9 +29,15 @@ public class ProjectCommand extends DefaultCommand { private final Project command = new Project(); @Option(longName = "ts", shortName = "t", flag = true) - @Description("Init a TypeScript project.") - public void setForce(boolean force) { - command.setTypeScript(force); + @Description("Create a TypeScript project instead of JavaScript.") + public void setTypeScript(boolean typeScript) { + command.setTypeScript(typeScript); + } + + @Option(longName = "importmap", shortName = "i", flag = true) + @Description("Create a import-map.json instead of package.json.") + public void setImportMap(boolean importMap) { + command.setImportMap(importMap); } @Override diff --git a/pm/src/main/java/io/reactiverse/es4x/commands/SecurityPolicy.java b/pm/src/main/java/io/reactiverse/es4x/commands/SecurityPolicy.java index c196a2b2d..1cea956ee 100644 --- a/pm/src/main/java/io/reactiverse/es4x/commands/SecurityPolicy.java +++ b/pm/src/main/java/io/reactiverse/es4x/commands/SecurityPolicy.java @@ -25,6 +25,7 @@ import static io.reactiverse.es4x.cli.Helper.fatal; import static io.reactiverse.es4x.cli.Helper.warn; +@Deprecated public class SecurityPolicy implements Runnable { public static final String NAME = "security-policy"; diff --git a/pm/src/main/java/io/reactiverse/es4x/commands/SecurityPolicyCommand.java b/pm/src/main/java/io/reactiverse/es4x/commands/SecurityPolicyCommand.java index 7f3a4ac67..0b84dcc02 100644 --- a/pm/src/main/java/io/reactiverse/es4x/commands/SecurityPolicyCommand.java +++ b/pm/src/main/java/io/reactiverse/es4x/commands/SecurityPolicyCommand.java @@ -20,6 +20,7 @@ import io.vertx.core.cli.annotations.Summary; import io.vertx.core.spi.launcher.DefaultCommand; +@Deprecated @Name(SecurityPolicy.NAME) @Summary(SecurityPolicy.SUMMARY) public class SecurityPolicyCommand extends DefaultCommand { diff --git a/pm/src/main/java/io/reactiverse/es4x/commands/SecurityPolicyCommandFactory.java b/pm/src/main/java/io/reactiverse/es4x/commands/SecurityPolicyCommandFactory.java index 9e0d0299b..65b7b0f9f 100644 --- a/pm/src/main/java/io/reactiverse/es4x/commands/SecurityPolicyCommandFactory.java +++ b/pm/src/main/java/io/reactiverse/es4x/commands/SecurityPolicyCommandFactory.java @@ -17,6 +17,7 @@ import io.vertx.core.spi.launcher.DefaultCommandFactory; +@Deprecated public class SecurityPolicyCommandFactory extends DefaultCommandFactory { public SecurityPolicyCommandFactory() { diff --git a/pm/src/main/resources/META-INF/es4x-commands/init/js/import-map.json b/pm/src/main/resources/META-INF/es4x-commands/init/js/import-map.json new file mode 100644 index 000000000..be4d663fd --- /dev/null +++ b/pm/src/main/resources/META-INF/es4x-commands/init/js/import-map.json @@ -0,0 +1,6 @@ +{ + "imports": { + "@vertx/core": "https://ga.jspm.io/npm:@vertx/core@${stack.version}/index.mjs", + "@vertx/unit": "https://ga.jspm.io/npm:@vertx/unit@${stack.version}/index.mjs" + } +} diff --git a/pm/src/main/resources/META-INF/es4x-commands/init/js/package.json b/pm/src/main/resources/META-INF/es4x-commands/init/js/package.json index 780e47e44..4c4087265 100644 --- a/pm/src/main/resources/META-INF/es4x-commands/init/js/package.json +++ b/pm/src/main/resources/META-INF/es4x-commands/init/js/package.json @@ -2,7 +2,8 @@ "name": "template-js", "version": "1.0.0", "private": true, - "description": "A barebones es4x application", + "description": "A bare-bones es4x application", + "type": "commonjs", "main": "index.js", "keywords": [], "author": "", diff --git a/pm/src/main/resources/META-INF/es4x-commands/init/ts/import-map.json b/pm/src/main/resources/META-INF/es4x-commands/init/ts/import-map.json new file mode 100644 index 000000000..be4d663fd --- /dev/null +++ b/pm/src/main/resources/META-INF/es4x-commands/init/ts/import-map.json @@ -0,0 +1,6 @@ +{ + "imports": { + "@vertx/core": "https://ga.jspm.io/npm:@vertx/core@${stack.version}/index.mjs", + "@vertx/unit": "https://ga.jspm.io/npm:@vertx/unit@${stack.version}/index.mjs" + } +} diff --git a/pm/src/main/resources/META-INF/es4x-commands/init/ts/package.json b/pm/src/main/resources/META-INF/es4x-commands/init/ts/package.json index 8432be3cc..1b1d26be8 100644 --- a/pm/src/main/resources/META-INF/es4x-commands/init/ts/package.json +++ b/pm/src/main/resources/META-INF/es4x-commands/init/ts/package.json @@ -2,7 +2,8 @@ "name": "template-js", "version": "1.0.0", "private": true, - "description": "A barebones es4x application", + "description": "A bare-bones es4x application", + "type": "commonjs", "main": "dist/index.js", "keywords": [], "author": "", diff --git a/pom.xml b/pom.xml index 23a8affcc..6f1bf7e98 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ io.reactiverse es4x-parent - 0.15.0 + 0.16.0 pom @@ -14,8 +14,8 @@ 1.8 UTF-8 - 4.1.0 - 21.1.0 + 4.2.0 + 21.3.0 https://oss.sonatype.org/content/repositories/snapshots/ @@ -69,6 +69,17 @@ true + + sonatype-nexus-s01-snapshots + Sonatype Nexus S01 Snapshots + https://s01.oss.sonatype.org/content/repositories/snapshots + + false + + + true + + @@ -118,7 +129,7 @@ org.apache.maven.plugins maven-dependency-plugin - 3.1.2 + 3.2.0 org.apache.maven.plugins