bertramdev / hcl4j Goto Github PK
View Code? Open in Web Editor NEWHCL is the Hashicorp Configuration Language used in Terraform. This is a java Parser for parsing HCL and converting to Map objects.
License: Apache License 2.0
HCL is the Hashicorp Configuration Language used in Terraform. This is a java Parser for parsing HCL and converting to Map objects.
License: Apache License 2.0
The following .tf
file results in a ClassCastException
:
locals {
domains = ["a.example.com", "b.example.com"]
}
resource "aws_acm_certificate" "cert_1" {
for_each = local.domains
domain_name = each.key
subject_alternative_names = [each.key]
validation_method = "DNS"
}
locals {
c = aws_acm_certificate.cert_1["a.example.com"].domain_validation_options
}
in hcl4j 0.6.1 while it works fine in hcl4j 0.4.4.
java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.util.Map
at com.bertramlabs.plugins.hcl4j.HCLParser.processEvaluation(HCLParser.java:875)
at com.bertramlabs.plugins.hcl4j.HCLParser.processSymbolPass2(HCLParser.java:459)
at com.bertramlabs.plugins.hcl4j.HCLParser.processSymbolPass2(HCLParser.java:641)
at com.bertramlabs.plugins.hcl4j.HCLParser.processSymbolPass2(HCLParser.java:421)
at com.bertramlabs.plugins.hcl4j.HCLParser.processSymbolPass2(HCLParser.java:421)
at com.bertramlabs.plugins.hcl4j.HCLParser.processSymbolPass2(HCLParser.java:421)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:323)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:121)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:108)
at com.mycode.MyCode(MyCode.java:19)
Merge the two locals{}
into one:
locals {
domains = ["a.example.com", "b.example.com"]
c = aws_acm_certificate.cert_1["a.example.com"].domain_validation_options
}
resource "aws_acm_certificate" "cert_1" {
for_each = local.domains
domain_name = each.key
subject_alternative_names = [each.key]
validation_method = "DNS"
}
and the ClassCastException
goes away.
(and you land with #24 which I think is another problem)
Hi,
Thanks for the library, it works most of the case, However I am just facing one issue with this when we have the content as below, even if it gives that method string as it is in the object notation, it would be good.
alarm_free_storage_size_threshold = ceil(
var.alarm_free_storage_pct_threshold * local.alarm_storage_size * 1073741824 / 100
)
database_parameters = concat(
var.database_parameters,
local.mandatory_database_parameters
)
Regards
Pari.V
Our .tfvars
files often contain object values like:
my_object = {
object_elem_a: 1,
object_elem_b: 2
}
When I try to parse a file containing one of these with HCLParser
, I get the following:
com.bertramlabs.plugins.hcl4j.HCLParserException: Illegal character <(o) - state: 6> found on line: 2 col: 3
at com.bertramlabs.plugins.hcl4j.HCLLexer.yylex(HCLLexer.java:1388)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:307)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:274)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:252)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:217)
It appears that this is being interpreted as a block rather than an object value.
Context: Started using hcl4j to parse yet another Terraform codebase in my org and I encounter another batch of errors. Thus I thought I should report them.
The following seems to be a legit Terraform code:
locals {
maybe = true
perhaps = ! local.maybe
}
while it results in the error:
com.bertramlabs.plugins.hcl4j.HCLParserException: Illegal character <(!) - state: 14> found on line: 4 col: 13
at com.bertramlabs.plugins.hcl4j.HCLLexer.yylex(HCLLexer.java:1368)
I am receiving error while parsing the following hcl files:
cidr-blocks = [
"10.12.22.22/24", # Test
"10.65.0.0/23", # Example
]
Parsing is good when I take "# Example" out. The error messages is like below,
com.bertramlabs.plugins.hcl4j.HCLParserException: Illegal character <(]) - state: 14> found on line: 4 col: 1
at com.bertramlabs.plugins.hcl4j.HCLLexer.yylex(HCLLexer.java:993)
Thanks, in advance.
Hi,
with parse API I have parsed a terraform script and updated 1 resource inside the Map.
Now, how I will again convert back the change in terraform script.
Do hcl4j provide any API for that?
Or any other lib using which I can achieve that
thanks in advance.
Context:
If the variable declaration and the comment are present in the same line then there is a parsing error.
Works fine if the comment is present in a new line.
Example:
user = "ec2-user" # comment regarding the variable
Error:
Illegal character <(=) - state: 14>
com.bertramlabs.plugins.hcl4j.HCLParserException: Illegal character <(=) - state: 14>
at com.bertramlabs.plugins.hcl4j.HCLLexer.yylex(HCLLexer.java:1388) ~[hcl4j-0.6.3.jar:?]
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:307) ~[hcl4j-0.6.3.jar:?]
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:121) ~[hcl4j-0.6.3.jar:?]
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:108) ~[hcl4j-0.6.3.jar:?]
Any plans to do the reverse? Go from parsed objects back into Terraform file?
The following code:
module "example" {
source = "../../modules/my-example"
bad_property_id = "${module.example.bad_property_id}"
}
fails with:
Exception in thread "main" java.lang.StackOverflowError
at com.bertramlabs.plugins.hcl4j.HCLParser.processSymbolPass2(HCLParser.java:440)
at com.bertramlabs.plugins.hcl4j.HCLParser.processSymbolPass2(HCLParser.java:681)
at com.bertramlabs.plugins.hcl4j.HCLParser.processSymbolPass2(HCLParser.java:615)
at com.bertramlabs.plugins.hcl4j.HCLParser.processSymbolPass2(HCLParser.java:681)
at com.bertramlabs.plugins.hcl4j.HCLParser.processEvaluation(HCLParser.java:1208)
at com.bertramlabs.plugins.hcl4j.HCLParser.processEvaluation(HCLParser.java:1082)
[...]
when running new HCLParser().parse() against it.
Using hcl4j 0.9.1 and 0.7.7
Hi guys....first of all I want to thank you for this amazing project.
Is there any chance to remove slf4j-parent library from dependencies because that library has multiple vulnerabilities and all security scanning tools are RED because of this? Thanks in advance.
https://mvnrepository.com/artifact/org.slf4j/slf4j-parent/1.7.26
**code : **
resource "oci_identity_compartment" "testcompartment1" {
#Required
compartment_id = var.compartment_ocid
description = "demo_compartment"
name = "demo_compartment1"
}
** coresponding parsemap :**
resource={
oci_identity_compartment={
testcompartment1={
compartment_id=null,
description=demo_compartment,
name=demo_compartment1
}
}
}
parser is working fine with name,description.
when it comes to variable resolution in (compartment_id = var.compartment_ocid)
var.compartment_ocid is parsed as either "null" or "com.bertramlabs.plugins.hcl4j.RuntimeSymbols.Variable@56cbfb61"
issue :
is there anyway so that i can get variable resolution feature included in the parser
@davydotcom how about opting in the repository to Hacktoberfest?
(you need to add the hacktoberfest
label to the repository)
It looks the project could gain some contributions this way.
Thanks for update.
I have string in this HCL format.
appId: 1
transactionId: 1
txnViolationConfig {
txnKpiType: FALIURE_PERCENTAGE
}
Map<String,Object> mapObject = new HCLParser().parse(string);
And when i m trying to parse this string, I am getting the exception as below:
Exception in thread "main" com.bertramlabs.plugins.hcl4j.HCLParserException: Illegal character <(t) - state: 6> found on line: 4 col: 3
at com.bertramlabs.plugins.hcl4j.HCLLexer.yylex(HCLLexer.java:993)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:186)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:62)
at ProtobufConvert.main(ProtobufConvert.java:47)
Thanks, in advance.
There is an issue when parsing a file with a resource that uses the Terraform jsonencode
function. For example:
resource "aws_ecs_task_definition" "service" {
family = "service"
container_definitions = jsonencode([
{
name = "first"
image = "service-first"
cpu = 10
memory = 512
essential = true
portMappings = [
{
containerPort = 80
hostPort = 80
}
]
},
{
name = "second"
image = "service-second"
cpu = 10
memory = 256
essential = true
portMappings = [
{
containerPort = 443
hostPort = 443
}
]
}
])
volume {
name = "service-storage"
host_path = "/ecs/service-storage"
}
placement_constraints {
type = "memberOf"
expression = "attribute:ecs.availability-zone in [us-west-2a, us-west-2b]"
}
}
When executing the HCLParser::parse
function for this example, we got a HCLParserException
for the line of the jsonencode
. Is the library supposed to be able to parse this function?
Anyway, if we set the ignoreParseExceptions
to true, the error is ignored, but the parsing of the file is stopped at the point the exception was raised instead of trying to parse the rest of the document. In this cases, IMO a better behaviour would be to ignore the field where the error appeared and try to get the rest of the components of the HCL file.
While defining list and maps with Collection Types e.g.
variable "variable_name" {
type = map(object({
field1 = string
field2 = list(string)
}))
default = {}
}
Failure is raised while parrsing. I know it's 0.12 which is not supported yet here, but would be nice to have a capability to set a lenient mode intenationally to ignore colection types definitions. So error will not be raised at (
when type: map(...)
is defined. And collection type will be skipped.
This will allow us to use collection types and not rollback our current configuration.
When trying to parse this:
locals {
enabled = (var.enable ? 1 : 0)
}
resource "aws_iam_user" "sync" {
count = local.enabled
name = "${'$'}{var.sync_username}-${'$'}{var.idp_name}"
tags = var.tags
}
resource "aws_iam_policy" "list_roles" {
count = local.enabled
name = "list-roles-${'$'}{var.sync_username}-${'$'}{var.idp_name}"
policy = file("${'$'}{path.module}/list-policy.json")
tags = var.tags
}
resource "aws_iam_policy_attachment" "this" {
count = local.enabled
name = "saml-role-sync-policy"
users = [aws_iam_user.sync[0].name]
policy_arn = aws_iam_policy.list_roles[0].arn
}
resource "aws_iam_access_key" "sync_creds" {
count = local.enabled
user = aws_iam_user.sync[0].name
}
I get this error:
Infinite recursion (StackOverflowError) (through reference chain: com.bertramlabs.plugins.hcl4j.symbols.HCLArray[\"children\"]->java.util.ArrayList[0]->com.bertramlabs.plugins.hcl4j.symbols.HCLValue[\"parent\"]->com.bertramlabs.plugins.hcl4j.symbols.HCLArray[\"children\"]->java.util.ArrayList[0]->com.bert","text":"locals {\n enabled = (var.enable ? 1 : 0)\n}\n\nresource \"aws_iam_user\" \"sync\" {\n count = local.enabled\n name = \"${var.sync_username}-${var.idp_name}\"\n tags = var.tags\n}\n\nresource \"aws_iam_policy\" \"list_roles\" {\n count = local.enabled\n name = \"list-roles-${var.sync_username}-${var.idp_name}\"\n policy = file(\"${path.module}/list-policy.json\")\n tags = var.tags\n}\n\nresource \"aws_iam_policy_attachment\" \"this\" {\n count = local.enabled\n name = \"saml-role-sync-policy\"\n users = [aws_iam_user.sync[0].name]\n policy_arn = aws_iam_policy.list_roles[0].arn\n}\n\nresource \"aws_iam_access_key\" \"sync_creds\" {\n count = local.enabled\n user = aws_iam_user.sync[0].name\n}
This "trimmed down" example also gets a similar error:
resource "something" "here" {
count = 1
name = "bobby"
}
resource "something" "there" {
count = 1
name = something.here[0].name
}
It doesn't seem to like the something.here[0].name
. Here is my call:
(HCLParser().parse(file.byteInputStream(), "UTF-8", false)
I am using 0.6.8 of hcl4j.
Question: @davydotcom do you have any plans for the parsing outcome to be more strongly-typed?
i.e. introduce types for Resources, etc.
Context: I know you can have tons of different resource types and we cannot have object representation hard-coded for any of them. Yet, currently when trying to use the library for parsing my .tf
files I end up having:
results.get("resource")
which I need to cast to a Map<String, String>
and then .get("the_resource_type_I_know")
and then I get a Map
instance which makes some sense (resource id -> Map of properties).
After I upgrading to version 0.3.3, I got errors when I am parsing the following,
variable "cluster-name" {
type = string
}
The error message is as below. The same input works with 0.2.3.
com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: com.bertramlabs.plugins.hcl4j.symbols
Thank you for checking this.
The following .tf
file results in a HCLParserException
:
terraform {
backend "s3" {
bucket = "my-configuration" # in my-main account
key = "my-terraform-state"
region = "us-west-1"
}
}
in hcl4j 0.6.1 while works fine in hcl4j 0.4.4.
com.bertramlabs.plugins.hcl4j.HCLParserException: Illegal character <(=) - state: 14> found on line: 4 col: 9
at com.bertramlabs.plugins.hcl4j.HCLLexer.yylex(HCLLexer.java:1388)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:307)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:274)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:198)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:181)
at com.my.code.ParsingTerraform$.loadFile(ParsingTerraform.scala:40)
Move the comment to separate line. This works fine:
terraform {
backend "s3" {
# in my-main account
bucket = "my-configuration"
key = "my-terraform-state"
region = "us-west-1"
}
}
Version: 0.7.3
In the below example ${key}
is causing the parsing error. It works fine if the value of Name
attribute is set as "any string value"
locals {
list = {for key in toset(["value1", "value2"]) :
replace(key, ".", "_") =>
{
key = key
tags = { Name = "${id}-${key}" }
} }
}
This is noticed only when for
loop is used the, parsing works fine in other cases for example -
locals {
dynamodb_table = "${csm-eks-tfstatelock} - ${sdf}"
}
Error Message
java.lang.RuntimeException: com.bertramlabs.plugins.hcl4j.HCLParserException: Illegal character <({) - state: 50> found on line: 6 col: 34
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:320)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:123)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:110)
The project currently uses Gradle 6.5. It could be upgraded to current 7.6.
Hey, I was trying to use the parser for variables parsing of terraform scripts but I am unable to find maven dependency for ur repo.
I tried:
Hi,
I'm not sure if this is even possible (can't find log lines in any code you've written) but whenever hcl4j parses something it has some log lines like this:
[12:50:54 INFO]: Block Element: firstRun - Attribute
[12:50:54 INFO]: Block Element: core - Block
[12:50:54 INFO]: Block Element: core - Block
Is there any way these can be disabled?
Cheers.
The following .tf
file results in an infinite loop and StackOverflowError
as a consequence:
resource "aws_acm_certificate" "cert_1" {
domain_name = "example.com"
subject_alternative_names = ["example.com"]
validation_method = "DNS"
}
locals {
c = aws_acm_certificate.cert_1.domain_validation_options
}
in hcl4j 0.6.1 while it works fine in hcl4j 0.4.4.
com.bertramlabs.plugins.hcl4j.HCLMyParserSpec > should generate Map from hcl FAILED
java.lang.StackOverflowError
at org.apache.groovy.json.internal.SimpleCache.get(SimpleCache.java:44)
at org.apache.groovy.json.internal.CharBuf.addInt(CharBuf.java:140)
at groovy.json.DefaultJsonGenerator.writeNumber(DefaultJsonGenerator.java:127)
at groovy.json.DefaultJsonGenerator.writeObject(DefaultJsonGenerator.java:194)
at groovy.json.DefaultJsonGenerator.writeMapEntry(DefaultJsonGenerator.java:387)
at groovy.json.DefaultJsonGenerator.writeMap(DefaultJsonGenerator.java:375)
at groovy.json.DefaultJsonGenerator.writeObject(DefaultJsonGenerator.java:237)
at groovy.json.DefaultJsonGenerator.writeMapEntry(DefaultJsonGenerator.java:387)
The following code:
locals {
one = 1
two = 3 - one
}
fails with:
com.bertramlabs.plugins.hcl4j.HCLParserException: Error Parsing Numerical Value in HCL Attribute
at com.bertramlabs.plugins.hcl4j.HCLParser.processValue(HCLParser.java:841)
at com.bertramlabs.plugins.hcl4j.HCLParser.processSymbolPass2(HCLParser.java:462)
at com.bertramlabs.plugins.hcl4j.HCLParser.processSymbolPass2(HCLParser.java:656)
at com.bertramlabs.plugins.hcl4j.HCLParser.processSymbolPass2(HCLParser.java:418)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:315)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:276)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:200)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:183)
[...]
Caused by: java.lang.NumberFormatException: For input string: "-"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at com.bertramlabs.plugins.hcl4j.HCLParser.processValue(HCLParser.java:838)
... 54 more
when running new HCLParser().parse()
against it.
Using hcl4j 0.7.3
Version: 0.7.2
The first test testValueWithoutColon
passes while the second test testValueWithColon
fails.
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import com.bertramlabs.plugins.hcl4j.HCLParser;
import org.junit.jupiter.api.Test;
class HCL4JBugReport {
@Test
void testValueWithoutColon() {
String valueWithoutColon = """
variable "variable1"{
default = [
{
key = "someKey"
attributes = {
"attribute1" = "valueWithoutColon"
}
}
]
}""";
HCLParser parser = new HCLParser();
assertDoesNotThrow(
() -> parser.parse(valueWithoutColon));
}
@Test
void testValueWithColon() {
String valueWithColon = """
variable "variable1"{
default = [
{
key = "someKey"
attributes = {
"attribute1" = ":valueWithColon"
}
}
]
}""";
HCLParser parser = new HCLParser();
assertDoesNotThrow(
() -> parser.parse(valueWithColon));
}
}
05:58:10.274 [Test worker] ERROR com.bertramlabs.plugins.hcl4j.HCLParser - Error Parsing HCL...Illegal character <(=) - state: 22> found on line: 6 col: 22
com.bertramlabs.plugins.hcl4j.HCLParserException: Illegal character <(=) - state: 22> found on line: 6 col: 22
at com.bertramlabs.plugins.hcl4j.HCLLexer.yylex(HCLLexer.java:1403) ~[hcl4j-0.7.2.jar:?]
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:302) ~[hcl4j-0.7.2.jar:?]
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:123) ~[hcl4j-0.7.2.jar:?]
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:110) ~[hcl4j-0.7.2.jar:?]
Parse this code security_group_ids = [var.test]
, the result is ArrayList = []
Here is the content of my tf file -
access_log_settings {
destination_arn = "${aws_cloudwatch_log_group.api_gw_cloudwatch.arn}"
format = "${replace(file("api_log_format.json"), "\n", "")}"
}
And parsing fails when it encounters "".
Stacktrace -
Exception in thread "main" com.bertramlabs.plugins.hcl4j.HCLParserException: Illegal character <() - state: 26> found on line: 3 col: 64
at com.bertramlabs.plugins.hcl4j.HCLLexer.yylex(HCLLexer.java:993)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:186)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:173)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:113)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:74)
at Main.isRemoteStateConfigured(Main.java:17)
at Main.main(Main.java:30)
I'm using Maven and with 0.9.1 I'm getting the same error as in #53. I tried to build a new jar from master
, but am getting many compile errors during task compileJava like:
build/generated/sources/main/com/bertramlabs/plugins/hcl4j/HCLLexer.java:1894: error: incompatible types: long cannot be converted to Integer
{ currentBlock.appendChild(new StringPrimitiveType(yyline,yycolumn,yychar));
^
Are there any special steps needed to compile or is the build simply broken right now?
Exception in thread "main" com.bertramlabs.plugins.hcl4j.HCLParserException: Illegal character <(l) - state: 6> found on line: 3 col: 5
is this because due to "interpolation syntax"?
What license is this available under?
Hello,
Are you planning to add HCL v2 (terraform 0.12) support?
Thanks!
As a hcl4j user I would like to parse well defined HCL (2) according to the language spec.
resource xxx "images" {
default = "empty.jpg"
}
Is a resource
block with labels xxx
(identifier) and "images"
(string literal) wrt. to the language spec.
The parser parses it to a block with name xxx
and silently drops the preceding resource
.
Disclaimer: Not sure whether this is only valid HCL 2 while hcl4j currently only supports HCL (1), cf. #5?
The following code:
module "submodule" {
source = "./submodule"
providers = {
aws.us-west-2-infrastructure = aws.us-west-2-infrastructure
}
}
fails with:
com.bertramlabs.plugins.hcl4j.HCLParserException: Illegal character <(a) - state: 6> found on line: 4 col: 5
at com.bertramlabs.plugins.hcl4j.HCLLexer.yylex(HCLLexer.java:1403)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:302)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:276)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:200)
at com.bertramlabs.plugins.hcl4j.HCLParser.parse(HCLParser.java:183)
when running new HCLParser().parse()
against it.
Using hcl4j 0.7.3
I suggest to consider configuring @dependabot for managing the dependencies of the library. Some of the dependencies we are using are already a couple of years old (2019, 2020).
This has the same symptoms as #13. I don't know whether it's the same problem or not.
I've worked a repro case down to
parser.parse ("module \"foo\" { providers = { bar.baz = quux } }")
This results in
Execution error (HCLParserException) at com.bertramlabs.plugins.hcl4j.HCLLexer/yylex (HCLLexer.java:1085).
Illegal character <(b) - state: 6> found on line: 1 col: 32
(The spacing may be off. I retyped that from a different machine).
I don't know whether this is related or totally different, or even if this is working as designed. If I take out the dot from the inner attribute name:
parser.parse ("module \"foo\" { providers = { barbaz = quux } }")
The resulting hash map has a Null property value for the barbaz key. Maybe because it's a nonsense value with no variable interpretation.
If I make that a string:
parser.parse ("module \"foo\" { providers = { barbaz = \"quux\" } }")
it works as I expect.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.