From d04bcfd995c42f9f6be273a15e98a9e956fc87ea Mon Sep 17 00:00:00 2001 From: Clemens Vasters Date: Mon, 9 Nov 2026 21:17:30 +0100 Subject: [PATCH 1/5] Resolve generated SDK dependency vulnerabilities Align TypeScript 5.9 tooling and propagate patched dependency overrides to generated SDKs. Update dashboard and MQTT compatibility, align Go transport dependencies, and use the available patched Python MQTT client. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: dfdd160a-bd4a-4a7e-bfb0-34d189fc944a Signed-off-by: Clemens Vasters --- test/codegen/test_codegen.py | 37 ++++++++++++++++++ xrcg/dependencies/go/go121/go.mod | 6 ++- .../python/py312/requirements.txt | 2 +- .../typescript/node22/package.json | 29 +++++++++++--- xrcg/templates/go/amqpconsumer/go.mod.jinja | 7 ++-- xrcg/templates/go/amqpproducer/go.mod.jinja | 7 ++-- .../{testdir}producer_test.go.jinja | 2 +- xrcg/templates/go/ehconsumer/go.mod.jinja | 3 +- xrcg/templates/go/ehproducer/go.mod.jinja | 3 +- .../{testdir}producer_test.go.jinja | 2 +- xrcg/templates/go/kafkaconsumer/go.mod.jinja | 9 +++-- xrcg/templates/go/kafkaproducer/go.mod.jinja | 9 +++-- .../{testdir}producer_test.go.jinja | 2 +- xrcg/templates/go/mqttclient/go.mod.jinja | 7 ++-- .../mqttclient/{testdir}client_test.go.jinja | 2 +- xrcg/templates/go/producer/go.mod.jinja | 5 ++- .../producer/{testdir}producer_test.go.jinja | 2 +- xrcg/templates/go/sbconsumer/go.mod.jinja | 3 +- xrcg/templates/go/sbproducer/go.mod.jinja | 3 +- .../{testdir}producer_test.go.jinja | 2 +- .../ts/_common/package.json.jinja.include | 32 ++++++++-------- xrcg/templates/ts/_common/util.jinja.include | 12 ++++++ .../ts/amqpconsumer/package.json.jinja | 20 +++++----- .../ts/amqpproducer/package.json.jinja | 22 ++++++----- .../dashboard-backend/package.json.jinja | 15 ++++---- .../src/clientManager.ts.jinja | 2 +- .../src/kafkaConsumer.ts.jinja | 11 +++--- .../dashboard-backend/src/kqlClient.ts.jinja | 3 +- .../dashboard-frontend/angular.json.jinja | 9 +++-- .../dashboard-frontend/package.json.jinja | 38 +++++++++---------- .../src/app/app.component.less.jinja | 2 +- .../src/app/app.component.ts.jinja | 1 + .../dashboard-frontend/tsconfig.json.jinja | 4 ++ .../templates/ts/dashboard/package.json.jinja | 2 + .../ts/egproducer/package.json.jinja | 26 +++++++------ .../ts/ehconsumer/package.json.jinja | 30 ++++++++------- .../ts/ehproducer/package.json.jinja | 26 +++++++------ .../ts/kafkaconsumer/package.json.jinja | 32 ++++++++-------- .../ts/kafkaproducer/package.json.jinja | 36 +++++++++--------- .../ts/mqttclient/package.json.jinja | 24 ++++++------ .../ts/mqttclient/src/client.ts.jinja | 4 +- .../ts/mqttclient/test/client.test.ts.jinja | 12 +++--- .../ts/sbconsumer/package.json.jinja | 22 ++++++----- .../ts/sbproducer/package.json.jinja | 26 +++++++------ 44 files changed, 333 insertions(+), 220 deletions(-) diff --git a/test/codegen/test_codegen.py b/test/codegen/test_codegen.py index a46e4ded..0fc2079f 100644 --- a/test/codegen/test_codegen.py +++ b/test/codegen/test_codegen.py @@ -719,6 +719,43 @@ def _tfm_of(path): shutil.rmtree(output_dir, ignore_errors=True) +@pytest.mark.parametrize("language,style", [ + ("ts", "kafkaproducer"), ("ts", "egproducer"), ("ts", "producerhttp"), + ("ts", "dashboard"), ("ts", "mqttclient"), + ("go", "ehproducer"), ("go", "kafkaproducer"), +]) +def test_generated_projects_use_central_dependency_floors(tmp_path, monkeypatch, language, style): + definitions = os.path.join(project_root, "test", "xreg", "lightbulb.xreg.json") + monkeypatch.setattr(sys, "argv", [ + "xrcg", "generate", "--definitions", definitions, + "--output", str(tmp_path), "--projectname", "DependencyFloors", + "--language", language, "--style", style, + ]) + assert xrcg.cli() == 0 + if language == "ts": + with open(os.path.join(project_root, "xrcg", "dependencies", "typescript", + "node22", "package.json"), encoding="utf-8") as handle: + central = json.load(handle) + manifests = list(tmp_path.rglob("package.json")) + assert manifests + overrides_found = False + for manifest in manifests: + package = json.loads(manifest.read_text(encoding="utf-8")) + if "overrides" in package: + overrides_found = True + assert package["overrides"] == central["overrides"] + for section in ("dependencies", "devDependencies"): + for name, version in package.get(section, {}).items(): + if name in central.get(section, {}) and "overrides" in package: + assert version == central[section][name] + assert overrides_found + else: + manifest = tmp_path / "DependencyFloors" / "go.mod" + content = manifest.read_text(encoding="utf-8") + floor = TemplateRenderer.dependency("go", "go121", "golang.org/x/net").strip() + assert floor in content + + def test_extract_schema_info_keeps_names_for_top_level_schemagroup_refs(): """Top-level schemagroup refs must retain class and namespace metadata. diff --git a/xrcg/dependencies/go/go121/go.mod b/xrcg/dependencies/go/go121/go.mod index 91b07055..1c241aad 100644 --- a/xrcg/dependencies/go/go121/go.mod +++ b/xrcg/dependencies/go/go121/go.mod @@ -1,3 +1,7 @@ module xrcg_dependencies -go 1.21 +go 1.26.0 + +require ( + golang.org/x/net v0.62.0 +) diff --git a/xrcg/dependencies/python/py312/requirements.txt b/xrcg/dependencies/python/py312/requirements.txt index 8e7409c8..69ad423d 100644 --- a/xrcg/dependencies/python/py312/requirements.txt +++ b/xrcg/dependencies/python/py312/requirements.txt @@ -9,7 +9,7 @@ azure-servicebus>=7.15.0 azure-storage-blob>=12.31.1 cloudevents>=2.2.0 confluent-kafka>=2.16.1 -paho-mqtt>=2.2.0 +paho-mqtt>=2.1.0 python-qpid-proton>=0.41.1 # Development dependencies diff --git a/xrcg/dependencies/typescript/node22/package.json b/xrcg/dependencies/typescript/node22/package.json index 3698260e..b000acc3 100644 --- a/xrcg/dependencies/typescript/node22/package.json +++ b/xrcg/dependencies/typescript/node22/package.json @@ -12,23 +12,40 @@ "kafkajs": "^2.2.4", "mqtt": "^5.0.0", "rhea": "^3.0.0", - "uuid": "^14.0.0" + "uuid": "^11.1.1" }, "devDependencies": { + "aedes": "^0.51.3", "@jest/globals": "^30.2.0", "@stylistic/eslint-plugin": "^5.6.1", "@testcontainers/kafka": "^12.0.1", "@types/jest": "^30.0.0", - "@types/node": "^26.1.1", + "@types/node": "^22.19.0", "@types/uuid": "^11.0.0", - "@typescript-eslint/eslint-plugin": "^8.8.1", - "@typescript-eslint/parser": "^8.8.1", + "@typescript-eslint/eslint-plugin": "^8.72.1", + "@typescript-eslint/parser": "^8.72.1", "eslint": "^10.1.0", "jest": "^30.2.0", "nock": "^14.0.10", "testcontainers": "^12.0.1", - "ts-jest": "^29.2.5", + "ts-jest": "^29.4.15", "ts-node": "^10.9.0", - "typescript": "^7.0.2" + "typedoc": "^0.28.17", + "typescript": "~5.9.3" + }, + "overrides": { + "deepmerge": "npm:@stackline/deepmerge@1.1.0", + "cloudevents": { + "uuid": "^11.1.1" + }, + "uuid@>=7 <11.1.1": "^11.1.1", + "ajv-cli": { + "fast-json-patch": "^3.1.1" + }, + "@typescript-eslint/typescript-estree": { + "minimatch": "^11.0.1" + }, + "minimatch@>=9": "^11.0.1", + "glob@>=9": "^14.0.3" } } diff --git a/xrcg/templates/go/amqpconsumer/go.mod.jinja b/xrcg/templates/go/amqpconsumer/go.mod.jinja index b1b5633f..d5124d2a 100644 --- a/xrcg/templates/go/amqpconsumer/go.mod.jinja +++ b/xrcg/templates/go/amqpconsumer/go.mod.jinja @@ -1,15 +1,16 @@ {%- import "util.jinja.include" as util -%} module {{ project_name | snake }} -go 1.21 +go 1.26.0 require ( + {{ dependency("go", "go121", "golang.org/x/net") }} github.com/Azure/go-amqp v1.7.0 github.com/cloudevents/sdk-go/v2 v2.15.2 github.com/google/uuid v1.6.0 github.com/username/{{ data_project_name | go_package }} v0.0.0 - github.com/stretchr/testify v1.8.4 - github.com/testcontainers/testcontainers-go v0.27.0 + github.com/stretchr/testify v1.10.0 + github.com/testcontainers/testcontainers-go v0.38.0 ) replace github.com/username/{{ data_project_name | go_package }} => ../{{ data_project_name }} diff --git a/xrcg/templates/go/amqpproducer/go.mod.jinja b/xrcg/templates/go/amqpproducer/go.mod.jinja index b1b5633f..d5124d2a 100644 --- a/xrcg/templates/go/amqpproducer/go.mod.jinja +++ b/xrcg/templates/go/amqpproducer/go.mod.jinja @@ -1,15 +1,16 @@ {%- import "util.jinja.include" as util -%} module {{ project_name | snake }} -go 1.21 +go 1.26.0 require ( + {{ dependency("go", "go121", "golang.org/x/net") }} github.com/Azure/go-amqp v1.7.0 github.com/cloudevents/sdk-go/v2 v2.15.2 github.com/google/uuid v1.6.0 github.com/username/{{ data_project_name | go_package }} v0.0.0 - github.com/stretchr/testify v1.8.4 - github.com/testcontainers/testcontainers-go v0.27.0 + github.com/stretchr/testify v1.10.0 + github.com/testcontainers/testcontainers-go v0.38.0 ) replace github.com/username/{{ data_project_name | go_package }} => ../{{ data_project_name }} diff --git a/xrcg/templates/go/amqpproducer/{testdir}producer_test.go.jinja b/xrcg/templates/go/amqpproducer/{testdir}producer_test.go.jinja index c53ff44d..1cb0549a 100644 --- a/xrcg/templates/go/amqpproducer/{testdir}producer_test.go.jinja +++ b/xrcg/templates/go/amqpproducer/{testdir}producer_test.go.jinja @@ -26,7 +26,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" {%- if avro_messages %} - "github.com/hamba/avro/v2" + "github.com/iskorotkov/avro/v2" {%- endif %} testcontainers "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" diff --git a/xrcg/templates/go/ehconsumer/go.mod.jinja b/xrcg/templates/go/ehconsumer/go.mod.jinja index 54fbbae8..687924fc 100644 --- a/xrcg/templates/go/ehconsumer/go.mod.jinja +++ b/xrcg/templates/go/ehconsumer/go.mod.jinja @@ -1,9 +1,10 @@ {%- import "util.jinja.include" as util -%} module {{ project_name | snake }} -go 1.23.0 +go 1.26.0 require ( + {{ dependency("go", "go121", "golang.org/x/net") }} github.com/Azure/azure-sdk-for-go/sdk/messaging/azeventhubs v1.4.0 github.com/cloudevents/sdk-go/v2 v2.15.2 github.com/google/uuid v1.6.0 diff --git a/xrcg/templates/go/ehproducer/go.mod.jinja b/xrcg/templates/go/ehproducer/go.mod.jinja index 59784f53..7f0d79c0 100644 --- a/xrcg/templates/go/ehproducer/go.mod.jinja +++ b/xrcg/templates/go/ehproducer/go.mod.jinja @@ -1,9 +1,10 @@ {%- import "util.jinja.include" as util -%} module {{ project_name | snake }} -go 1.23.0 +go 1.26.0 require ( + {{ dependency("go", "go121", "golang.org/x/net") }} github.com/Azure/azure-sdk-for-go/sdk/messaging/azeventhubs v1.4.0 github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 github.com/cloudevents/sdk-go/v2 v2.15.2 diff --git a/xrcg/templates/go/ehproducer/{testdir}producer_test.go.jinja b/xrcg/templates/go/ehproducer/{testdir}producer_test.go.jinja index 1ba815d0..e45b0e32 100644 --- a/xrcg/templates/go/ehproducer/{testdir}producer_test.go.jinja +++ b/xrcg/templates/go/ehproducer/{testdir}producer_test.go.jinja @@ -45,7 +45,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" {%- if avro_messages %} - "github.com/hamba/avro/v2" + "github.com/iskorotkov/avro/v2" {%- endif %} {%- if live_is_ce %} "github.com/testcontainers/testcontainers-go" diff --git a/xrcg/templates/go/kafkaconsumer/go.mod.jinja b/xrcg/templates/go/kafkaconsumer/go.mod.jinja index 7c950092..7c75062d 100644 --- a/xrcg/templates/go/kafkaconsumer/go.mod.jinja +++ b/xrcg/templates/go/kafkaconsumer/go.mod.jinja @@ -1,16 +1,17 @@ {%- import "util.jinja.include" as util -%} module {{ project_name | snake }} -go 1.21 +go 1.26.0 require ( + {{ dependency("go", "go121", "golang.org/x/net") }} github.com/cloudevents/sdk-go/v2 v2.15.2 github.com/segmentio/kafka-go v0.4.47 github.com/google/uuid v1.6.0 github.com/username/{{ data_project_name | go_package }} v0.0.0 - github.com/testcontainers/testcontainers-go v0.27.0 - github.com/testcontainers/testcontainers-go/modules/kafka v0.27.0 - github.com/stretchr/testify v1.8.4 + github.com/testcontainers/testcontainers-go v0.38.0 + github.com/testcontainers/testcontainers-go/modules/kafka v0.38.0 + github.com/stretchr/testify v1.10.0 ) replace github.com/username/{{ data_project_name | go_package }} => ../{{ data_project_name }} diff --git a/xrcg/templates/go/kafkaproducer/go.mod.jinja b/xrcg/templates/go/kafkaproducer/go.mod.jinja index 7c950092..7c75062d 100644 --- a/xrcg/templates/go/kafkaproducer/go.mod.jinja +++ b/xrcg/templates/go/kafkaproducer/go.mod.jinja @@ -1,16 +1,17 @@ {%- import "util.jinja.include" as util -%} module {{ project_name | snake }} -go 1.21 +go 1.26.0 require ( + {{ dependency("go", "go121", "golang.org/x/net") }} github.com/cloudevents/sdk-go/v2 v2.15.2 github.com/segmentio/kafka-go v0.4.47 github.com/google/uuid v1.6.0 github.com/username/{{ data_project_name | go_package }} v0.0.0 - github.com/testcontainers/testcontainers-go v0.27.0 - github.com/testcontainers/testcontainers-go/modules/kafka v0.27.0 - github.com/stretchr/testify v1.8.4 + github.com/testcontainers/testcontainers-go v0.38.0 + github.com/testcontainers/testcontainers-go/modules/kafka v0.38.0 + github.com/stretchr/testify v1.10.0 ) replace github.com/username/{{ data_project_name | go_package }} => ../{{ data_project_name }} diff --git a/xrcg/templates/go/kafkaproducer/{testdir}producer_test.go.jinja b/xrcg/templates/go/kafkaproducer/{testdir}producer_test.go.jinja index 37052f21..410833b5 100644 --- a/xrcg/templates/go/kafkaproducer/{testdir}producer_test.go.jinja +++ b/xrcg/templates/go/kafkaproducer/{testdir}producer_test.go.jinja @@ -26,7 +26,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" {%- if avro_messages %} - "github.com/hamba/avro/v2" + "github.com/iskorotkov/avro/v2" {%- endif %} testcontainers "github.com/testcontainers/testcontainers-go" tckafka "github.com/testcontainers/testcontainers-go/modules/kafka" diff --git a/xrcg/templates/go/mqttclient/go.mod.jinja b/xrcg/templates/go/mqttclient/go.mod.jinja index e5f3dc5a..c504f4ae 100644 --- a/xrcg/templates/go/mqttclient/go.mod.jinja +++ b/xrcg/templates/go/mqttclient/go.mod.jinja @@ -9,17 +9,18 @@ {%- endfor -%} module {{ project_name | snake }} -go 1.21 +go 1.26.0 require ( + {{ dependency("go", "go121", "golang.org/x/net") }} github.com/cloudevents/sdk-go/v2 v2.15.2 github.com/eclipse/paho.golang v0.23.0 github.com/google/uuid v1.6.0 {%- if uses_data_package %} github.com/username/{{ data_project_name | go_package }} v0.0.0 {%- endif %} - github.com/stretchr/testify v1.8.4 - github.com/testcontainers/testcontainers-go v0.27.0 + github.com/stretchr/testify v1.10.0 + github.com/testcontainers/testcontainers-go v0.38.0 ) {%- if uses_data_package %} diff --git a/xrcg/templates/go/mqttclient/{testdir}client_test.go.jinja b/xrcg/templates/go/mqttclient/{testdir}client_test.go.jinja index 11747f43..73999ce7 100644 --- a/xrcg/templates/go/mqttclient/{testdir}client_test.go.jinja +++ b/xrcg/templates/go/mqttclient/{testdir}client_test.go.jinja @@ -32,7 +32,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" {%- if avro_messages %} - "github.com/hamba/avro/v2" + "github.com/iskorotkov/avro/v2" {%- endif %} "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" diff --git a/xrcg/templates/go/producer/go.mod.jinja b/xrcg/templates/go/producer/go.mod.jinja index c4171cfe..9af8d047 100644 --- a/xrcg/templates/go/producer/go.mod.jinja +++ b/xrcg/templates/go/producer/go.mod.jinja @@ -1,13 +1,14 @@ {%- import "util.jinja.include" as util -%} module {{ project_name | snake }} -go 1.21 +go 1.26.0 require ( + {{ dependency("go", "go121", "golang.org/x/net") }} github.com/cloudevents/sdk-go/v2 v2.15.2 github.com/google/uuid v1.6.0 github.com/username/{{ data_project_name | go_package }} v0.0.0 - github.com/stretchr/testify v1.8.4 + github.com/stretchr/testify v1.10.0 ) replace github.com/username/{{ data_project_name | go_package }} => ../{{ data_project_name }} diff --git a/xrcg/templates/go/producer/{testdir}producer_test.go.jinja b/xrcg/templates/go/producer/{testdir}producer_test.go.jinja index cd1142dc..f8d6df84 100644 --- a/xrcg/templates/go/producer/{testdir}producer_test.go.jinja +++ b/xrcg/templates/go/producer/{testdir}producer_test.go.jinja @@ -29,7 +29,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" {%- if avro_messages %} - "github.com/hamba/avro/v2" + "github.com/iskorotkov/avro/v2" {%- endif %} {%- if _t_uses_data %} diff --git a/xrcg/templates/go/sbconsumer/go.mod.jinja b/xrcg/templates/go/sbconsumer/go.mod.jinja index 424be21b..2d8d7578 100644 --- a/xrcg/templates/go/sbconsumer/go.mod.jinja +++ b/xrcg/templates/go/sbconsumer/go.mod.jinja @@ -1,9 +1,10 @@ {%- import "util.jinja.include" as util -%} module {{ project_name | snake }} -go 1.23.0 +go 1.26.0 require ( + {{ dependency("go", "go121", "golang.org/x/net") }} github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus v1.9.0 github.com/cloudevents/sdk-go/v2 v2.15.2 github.com/stretchr/testify v1.10.0 diff --git a/xrcg/templates/go/sbproducer/go.mod.jinja b/xrcg/templates/go/sbproducer/go.mod.jinja index 68150818..98310ac5 100644 --- a/xrcg/templates/go/sbproducer/go.mod.jinja +++ b/xrcg/templates/go/sbproducer/go.mod.jinja @@ -1,9 +1,10 @@ {%- import "util.jinja.include" as util -%} module {{ project_name | snake }} -go 1.23.0 +go 1.26.0 require ( + {{ dependency("go", "go121", "golang.org/x/net") }} github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus v1.9.0 github.com/cloudevents/sdk-go/v2 v2.15.2 github.com/google/uuid v1.6.0 diff --git a/xrcg/templates/go/sbproducer/{testdir}producer_test.go.jinja b/xrcg/templates/go/sbproducer/{testdir}producer_test.go.jinja index ac23f44a..e176608b 100644 --- a/xrcg/templates/go/sbproducer/{testdir}producer_test.go.jinja +++ b/xrcg/templates/go/sbproducer/{testdir}producer_test.go.jinja @@ -31,7 +31,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" {%- if avro_messages %} - "github.com/hamba/avro/v2" + "github.com/iskorotkov/avro/v2" {%- endif %} {%- if live_is_ce %} "github.com/testcontainers/testcontainers-go" diff --git a/xrcg/templates/ts/_common/package.json.jinja.include b/xrcg/templates/ts/_common/package.json.jinja.include index 0056aae1..6f3dcac1 100644 --- a/xrcg/templates/ts/_common/package.json.jinja.include +++ b/xrcg/templates/ts/_common/package.json.jinja.include @@ -1,3 +1,4 @@ +{%- import "util.jinja.include" as util -%} {%- macro DeclarePackageJson( packageName ) -%} { "name": "{{ packageName }}", @@ -6,6 +7,7 @@ "type": "module", "main": "dist/index.js", "types": "dist/index.d.ts", + "overrides": {{ util.DependencyOverrides() }}, "scripts": { "watch": "tsc --project tsconfig.json --watch", "build:src": "tsc --project tsconfig.json", @@ -29,24 +31,24 @@ "dependencies": { "ajv": "^8.17.1", "ajv-formats": "^3.0.1", - "uuid": "^10.0.0", - "cloudevents": "^8.0.2" + {{ dependency("ts", "node22", "uuid") }}, + {{ dependency("ts", "node22", "cloudevents") }} }, "devDependencies": { - "@jest/globals": "^29.7.0", - "@types/jest": "^29.5.12", - "@types/node": "^22.7.5", - "@types/uuid": "^10.0.0", - "@typescript-eslint/eslint-plugin": "^8.8.1", - "@typescript-eslint/parser": "^8.8.1", - "@stylistic/eslint-plugin": "^2.9.0", + {{ dependency("ts", "node22", "@jest/globals") }}, + {{ dependency("ts", "node22", "@types/jest") }}, + {{ dependency("ts", "node22", "@types/node") }}, + {{ dependency("ts", "node22", "@types/uuid") }}, + {{ dependency("ts", "node22", "@typescript-eslint/eslint-plugin") }}, + {{ dependency("ts", "node22", "@typescript-eslint/parser") }}, + {{ dependency("ts", "node22", "@stylistic/eslint-plugin") }}, "ajv-cli": "^5.0.0", - "eslint": "^9.12.0", - "jest": "^29.7.0", - "ts-jest": "^29.2.5", - "ts-node": "^10.9.2", - "typedoc": "^0.26.8", - "typescript": "^5.6.3", + {{ dependency("ts", "node22", "eslint") }}, + {{ dependency("ts", "node22", "jest") }}, + {{ dependency("ts", "node22", "ts-jest") }}, + {{ dependency("ts", "node22", "ts-node") }}, + {{ dependency("ts", "node22", "typedoc") }}, + {{ dependency("ts", "node22", "typescript") }}, "webpack": "^5.95.0", "webpack-cli": "^5.1.4" }, diff --git a/xrcg/templates/ts/_common/util.jinja.include b/xrcg/templates/ts/_common/util.jinja.include index a6f82fdc..d0ef2937 100644 --- a/xrcg/templates/ts/_common/util.jinja.include +++ b/xrcg/templates/ts/_common/util.jinja.include @@ -1,5 +1,17 @@ {# Utility macros for TypeScript templates #} +{% macro DependencyOverrides() -%} +{ + "deepmerge": "npm:@stackline/deepmerge@1.1.0", + "cloudevents": {"uuid": "^11.1.1"}, + "uuid@>=7 <11.1.1": "^11.1.1", + "ajv-cli": {"fast-json-patch": "^3.1.1"}, + "@typescript-eslint/typescript-estree": {"minimatch": "^11.0.1"}, + "minimatch@>=9": "^11.0.1", + "glob@>=9": "^14.0.3" +} +{%- endmacro %} + {% macro CommonFileHeader() %} // This code was auto-generated by xRegistry CLI {% endmacro %} diff --git a/xrcg/templates/ts/amqpconsumer/package.json.jinja b/xrcg/templates/ts/amqpconsumer/package.json.jinja index 3b263822..333dc818 100644 --- a/xrcg/templates/ts/amqpconsumer/package.json.jinja +++ b/xrcg/templates/ts/amqpconsumer/package.json.jinja @@ -1,3 +1,4 @@ +{%- import "util.jinja.include" as util -%} { "name": "{{ project_name | lower | replace('.', '-') }}-amqp-consumer", "version": "1.0.0", @@ -5,6 +6,7 @@ "description": "AMQP 1.0 Consumer for {{ project_name }}", "main": "dist/index.js", "types": "dist/index.d.ts", + "overrides": {{ util.DependencyOverrides() }}, "scripts": { "build": "tsc", "test": "jest", @@ -12,16 +14,16 @@ "clean": "rm -rf dist" }, "dependencies": { - "rhea": "^3.0.0", - "cloudevents": "^8.0.2" + {{ dependency("ts", "node22", "rhea") }}, + {{ dependency("ts", "node22", "cloudevents") }} }, "devDependencies": { - "@jest/globals": "^29.7.0", - "@types/jest": "^29.5.12", - "@types/node": "^22.7.5", - "jest": "^29.7.0", - "ts-jest": "^29.2.5", - "typescript": "^5.6.3", - "testcontainers": "^10.0.0" + {{ dependency("ts", "node22", "@jest/globals") }}, + {{ dependency("ts", "node22", "@types/jest") }}, + {{ dependency("ts", "node22", "@types/node") }}, + {{ dependency("ts", "node22", "jest") }}, + {{ dependency("ts", "node22", "ts-jest") }}, + {{ dependency("ts", "node22", "typescript") }}, + {{ dependency("ts", "node22", "testcontainers") }} } } diff --git a/xrcg/templates/ts/amqpproducer/package.json.jinja b/xrcg/templates/ts/amqpproducer/package.json.jinja index 3d56e234..2981bf32 100644 --- a/xrcg/templates/ts/amqpproducer/package.json.jinja +++ b/xrcg/templates/ts/amqpproducer/package.json.jinja @@ -1,3 +1,4 @@ +{%- import "util.jinja.include" as util -%} { "name": "{{ project_name | lower | replace('.', '-') }}-amqp-producer", "version": "1.0.0", @@ -5,6 +6,7 @@ "description": "AMQP 1.0 Producer for {{ project_name }}", "main": "dist/index.js", "types": "dist/index.d.ts", + "overrides": {{ util.DependencyOverrides() }}, "scripts": { "build": "tsc", "test": "jest", @@ -12,17 +14,17 @@ "clean": "rm -rf dist" }, "dependencies": { - "rhea": "^3.0.0", - "cloudevents": "^8.0.2", - "uuid": "^9.0.0" + {{ dependency("ts", "node22", "rhea") }}, + {{ dependency("ts", "node22", "cloudevents") }}, + {{ dependency("ts", "node22", "uuid") }} }, "devDependencies": { - "@jest/globals": "^29.7.0", - "@types/jest": "^29.5.12", - "@types/node": "^22.7.5", - "@types/uuid": "^9.0.0", - "jest": "^29.7.0", - "ts-jest": "^29.2.5", - "typescript": "^5.6.3" + {{ dependency("ts", "node22", "@jest/globals") }}, + {{ dependency("ts", "node22", "@types/jest") }}, + {{ dependency("ts", "node22", "@types/node") }}, + {{ dependency("ts", "node22", "@types/uuid") }}, + {{ dependency("ts", "node22", "jest") }}, + {{ dependency("ts", "node22", "ts-jest") }}, + {{ dependency("ts", "node22", "typescript") }} } } diff --git a/xrcg/templates/ts/dashboard/dashboard-backend/package.json.jinja b/xrcg/templates/ts/dashboard/dashboard-backend/package.json.jinja index 569d392e..bf56b04d 100644 --- a/xrcg/templates/ts/dashboard/dashboard-backend/package.json.jinja +++ b/xrcg/templates/ts/dashboard/dashboard-backend/package.json.jinja @@ -1,11 +1,13 @@ +{%- import "util.jinja.include" as util -%} { "name": "{{project_name|dotdash|lower}}-dashboard-backend", "version": "1.0.0", "description": "Backend server for dashboard", "type": "module", "main": "dist/index.js", + "overrides": {{ util.DependencyOverrides() }}, "scripts": { - "build": "tsc && cpx \"public/**/*\" dist/public", + "build": "tsc && node -e \"const fs = require('node:fs'); if (fs.existsSync('public')) fs.cpSync('public', 'dist/public', { recursive: true })\"", "start": "node dist/index.js", "dev": "ts-node src/index.ts", "debug": "nodemon --inspect --watch 'src/**/*.ts' --exec 'ts-node' src/index.ts" @@ -16,20 +18,19 @@ "dependencies": { "async-sema": "3.1.1", "azure-kusto-data": "^6.0.2", - "cloudevents": "^8.0.2", + {{ dependency("ts", "node22", "cloudevents") }}, "dotenv": "^16.4.5", "express": "^4.21.0", - "kafkajs": "^2.2.4", + {{ dependency("ts", "node22", "kafkajs") }}, "pako": "^2.1.0", "socket.io": "^4.8.0", "winston": "^3.14.2" }, "devDependencies": { "@types/express": "^4.17.21", - "@types/node": "^22.7.5", - "cpx": "^1.5.0", + {{ dependency("ts", "node22", "@types/node") }}, "nodemon": "^3.0.1", - "ts-node": "^10.9.2", - "typescript": "^5.6.3" + {{ dependency("ts", "node22", "ts-node") }}, + {{ dependency("ts", "node22", "typescript") }} } } diff --git a/xrcg/templates/ts/dashboard/dashboard-backend/src/clientManager.ts.jinja b/xrcg/templates/ts/dashboard/dashboard-backend/src/clientManager.ts.jinja index 569d993b..c37c4b24 100644 --- a/xrcg/templates/ts/dashboard/dashboard-backend/src/clientManager.ts.jinja +++ b/xrcg/templates/ts/dashboard/dashboard-backend/src/clientManager.ts.jinja @@ -88,7 +88,7 @@ export class ClientManager { }); } - private createCloudEventFromRow(row: Record): CloudEvent { + private createCloudEventFromRow(row: Record): CloudEvent> { const cloudEvent: Record = {}; const data: Record = {}; diff --git a/xrcg/templates/ts/dashboard/dashboard-backend/src/kafkaConsumer.ts.jinja b/xrcg/templates/ts/dashboard/dashboard-backend/src/kafkaConsumer.ts.jinja index a4722728..7bc8b444 100644 --- a/xrcg/templates/ts/dashboard/dashboard-backend/src/kafkaConsumer.ts.jinja +++ b/xrcg/templates/ts/dashboard/dashboard-backend/src/kafkaConsumer.ts.jinja @@ -39,14 +39,13 @@ export class KafkaConsumer { clientId: 'my-app', brokers: config.KAFKA_BROKERS.split(','), ssl: config.KAFKA_SSL === 'true', - sasl: - config.KAFKA_USERNAME && config.KAFKA_PASSWORD - ? { - mechanism: 'plain', + ...(config.KAFKA_USERNAME && config.KAFKA_PASSWORD + ? { sasl: { + mechanism: 'plain' as const, username: config.KAFKA_USERNAME, password: config.KAFKA_PASSWORD, - } - : undefined, + } } + : {}), }); this.consumer = kafka.consumer({ groupId: config.CONSUMER_GROUP }); diff --git a/xrcg/templates/ts/dashboard/dashboard-backend/src/kqlClient.ts.jinja b/xrcg/templates/ts/dashboard/dashboard-backend/src/kqlClient.ts.jinja index 89b72883..57c76d90 100644 --- a/xrcg/templates/ts/dashboard/dashboard-backend/src/kqlClient.ts.jinja +++ b/xrcg/templates/ts/dashboard/dashboard-backend/src/kqlClient.ts.jinja @@ -49,7 +49,8 @@ export class KqlClient { `strcmp( ___tid, "${fromTime.toISOString()}") >= 0 and strcmp(___tid, "${toTime.toISOString()}") <= 0` ); } else { - filterStrings.push(`strcmp(___tid,strcat(datetime("${value.toISOString()}"), ___id)) >= 0`); + const fromTime = value instanceof Date ? value : new Date(value); + filterStrings.push(`strcmp(___tid,strcat(datetime("${fromTime.toISOString()}"), ___id)) >= 0`); } } else if (typeof value === 'string') { filterStrings.push(`${key} startswith "${value}"`); diff --git a/xrcg/templates/ts/dashboard/dashboard-frontend/angular.json.jinja b/xrcg/templates/ts/dashboard/dashboard-frontend/angular.json.jinja index 1caefe71..05795b30 100644 --- a/xrcg/templates/ts/dashboard/dashboard-frontend/angular.json.jinja +++ b/xrcg/templates/ts/dashboard/dashboard-frontend/angular.json.jinja @@ -25,6 +25,9 @@ ], "tsConfig": "tsconfig.app.json", "inlineStyleLanguage": "less", + "optimization": { + "fonts": false + }, "assets": [ "src/favicon.ico", "src/assets" @@ -65,10 +68,10 @@ "builder": "@angular-devkit/build-angular:dev-server", "configurations": { "production": { - "browserTarget": "dashboard-frontend:build:production" + "buildTarget": "dashboard-frontend:build:production" }, "development": { - "browserTarget": "dashboard-frontend:build:development" + "buildTarget": "dashboard-frontend:build:development" } }, "defaultConfiguration": "development" @@ -76,7 +79,7 @@ "extract-i18n": { "builder": "@angular-devkit/build-angular:extract-i18n", "options": { - "browserTarget": "dashboard-frontend:build" + "buildTarget": "dashboard-frontend:build" } }, "test": { diff --git a/xrcg/templates/ts/dashboard/dashboard-frontend/package.json.jinja b/xrcg/templates/ts/dashboard/dashboard-frontend/package.json.jinja index ddbf5344..cd44cb82 100644 --- a/xrcg/templates/ts/dashboard/dashboard-frontend/package.json.jinja +++ b/xrcg/templates/ts/dashboard/dashboard-frontend/package.json.jinja @@ -1,7 +1,9 @@ +{%- import "util.jinja.include" as util -%} { "name": "{{project_name|dotdash|lower}}-dashboard-frontend", "version": "0.0.0", "type": "module", + "overrides": {{ util.DependencyOverrides() }}, "scripts": { "ng": "ng", "start": "ng serve", @@ -11,31 +13,32 @@ }, "private": true, "dependencies": { - "@angular/animations": "^18.2.5", - "@angular/common": "^18.2.5", - "@angular/compiler": "^18.2.5", - "@angular/core": "^18.2.5", - "@angular/forms": "^18.2.5", - "@angular/platform-browser": "^18.2.5", - "@angular/platform-browser-dynamic": "^18.2.5", - "@angular/router": "^18.2.5", + "@angular/animations": "^21.2.25", + "@angular/common": "^21.2.25", + "@angular/compiler": "^21.2.25", + "@angular/core": "^21.2.25", + "@angular/forms": "^21.2.25", + "@angular/platform-browser": "^21.2.25", + "@angular/platform-browser-dynamic": "^21.2.25", + "@angular/router": "^21.2.25", + {{ dependency("ts", "node22", "cloudevents") }}, + "buffer": "^6.0.3", + "util": "^0.12.5", "@types/d3": "7.4.3", "d3": "7.9.0", "dashboard-frontend": "file:", - "glob": "^11.0.0", "{{project_name|dotunderscore|lower}}_data": "file:../{{project_name|dotunderscore|lower}}_data", - "rollup": "^4.22.4", "rxjs": "^7.8.1", "socket.io-client": "4.8.0", "tslib": "^2.7.0", "typedjson": "1.8.0", - "zone.js": "^0.14.10" + "zone.js": "~0.15.1" }, "devDependencies": { - "@angular-devkit/build-angular": "^18.2.5", - "@angular/build": "^18.2.5", - "@angular/cli": "^18.2.5", - "@angular/compiler-cli": "^18.2.5", + "@angular-devkit/build-angular": "^21.2.29", + "@angular/build": "^21.2.29", + "@angular/cli": "^21.2.29", + "@angular/compiler-cli": "^21.2.25", "@types/jasmine": "^5.1.4", "jasmine-core": "5.3.0", "karma": "~6.4.0", @@ -44,9 +47,6 @@ "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "2.1.0", "rimraf": "^6.0.1", - "rollup": "4.22.4", - "typescript": "5.4.5", - "undici": "6.19.8", - "vite": "5.4.8" + {{ dependency("ts", "node22", "typescript") }} } } diff --git a/xrcg/templates/ts/dashboard/dashboard-frontend/src/app/app.component.less.jinja b/xrcg/templates/ts/dashboard/dashboard-frontend/src/app/app.component.less.jinja index 40216724..8410bf11 100644 --- a/xrcg/templates/ts/dashboard/dashboard-frontend/src/app/app.component.less.jinja +++ b/xrcg/templates/ts/dashboard/dashboard-frontend/src/app/app.component.less.jinja @@ -1,5 +1,5 @@ /* Ensure font is loaded */ -@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap"); +@import (css) url("https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap"); body { font-family: 'Roboto', sans-serif; diff --git a/xrcg/templates/ts/dashboard/dashboard-frontend/src/app/app.component.ts.jinja b/xrcg/templates/ts/dashboard/dashboard-frontend/src/app/app.component.ts.jinja index aa46d1ad..fc99e71c 100644 --- a/xrcg/templates/ts/dashboard/dashboard-frontend/src/app/app.component.ts.jinja +++ b/xrcg/templates/ts/dashboard/dashboard-frontend/src/app/app.component.ts.jinja @@ -24,6 +24,7 @@ import * as d3 from 'd3'; import { TypedJSON } from 'typedjson'; @Component({ + standalone: false, selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.less'], diff --git a/xrcg/templates/ts/dashboard/dashboard-frontend/tsconfig.json.jinja b/xrcg/templates/ts/dashboard/dashboard-frontend/tsconfig.json.jinja index e39f72c9..33bf2482 100644 --- a/xrcg/templates/ts/dashboard/dashboard-frontend/tsconfig.json.jinja +++ b/xrcg/templates/ts/dashboard/dashboard-frontend/tsconfig.json.jinja @@ -3,6 +3,10 @@ "compileOnSave": false, "compilerOptions": { "baseUrl": "./", + "paths": { + "buffer": ["node_modules/buffer", "../node_modules/buffer"], + "util": ["node_modules/util", "../node_modules/util"] + }, "outDir": "./dist/out-tsc", "forceConsistentCasingInFileNames": true, "strict": true, diff --git a/xrcg/templates/ts/dashboard/package.json.jinja b/xrcg/templates/ts/dashboard/package.json.jinja index 3bce07ad..03a5ce28 100644 --- a/xrcg/templates/ts/dashboard/package.json.jinja +++ b/xrcg/templates/ts/dashboard/package.json.jinja @@ -1,6 +1,8 @@ +{%- import "util.jinja.include" as util -%} { "name": "dashboard", "version": "1.0.0", + "overrides": {{ util.DependencyOverrides() }}, "scripts": { "bootstrap": "npm install", "build": "npm run build --workspaces", diff --git a/xrcg/templates/ts/egproducer/package.json.jinja b/xrcg/templates/ts/egproducer/package.json.jinja index 120bd01c..0f72d2a3 100644 --- a/xrcg/templates/ts/egproducer/package.json.jinja +++ b/xrcg/templates/ts/egproducer/package.json.jinja @@ -1,3 +1,4 @@ +{%- import "util.jinja.include" as util -%} { "name": "{{ project_name | lower | replace('.', '-') }}-eventgrid-producer", "version": "1.0.0", @@ -5,6 +6,7 @@ "description": "Azure Event Grid Producer for {{ project_name }}", "main": "dist/index.js", "types": "dist/index.d.ts", + "overrides": {{ util.DependencyOverrides() }}, "scripts": { "build": "tsc", "test": "jest", @@ -12,19 +14,19 @@ "clean": "rm -rf dist" }, "dependencies": { - "@azure/eventgrid": "^5.0.0", - "@azure/identity": "^4.0.0", - "cloudevents": "^8.0.2", - "uuid": "^9.0.0" + {{ dependency("ts", "node22", "@azure/eventgrid") }}, + {{ dependency("ts", "node22", "@azure/identity") }}, + {{ dependency("ts", "node22", "cloudevents") }}, + {{ dependency("ts", "node22", "uuid") }} }, "devDependencies": { - "@jest/globals": "^29.7.0", - "@types/jest": "^29.5.12", - "@types/node": "^22.7.5", - "@types/uuid": "^9.0.0", - "jest": "^29.7.0", - "nock": "^13.5.0", - "ts-jest": "^29.2.5", - "typescript": "^5.6.3" + {{ dependency("ts", "node22", "@jest/globals") }}, + {{ dependency("ts", "node22", "@types/jest") }}, + {{ dependency("ts", "node22", "@types/node") }}, + {{ dependency("ts", "node22", "@types/uuid") }}, + {{ dependency("ts", "node22", "jest") }}, + {{ dependency("ts", "node22", "nock") }}, + {{ dependency("ts", "node22", "ts-jest") }}, + {{ dependency("ts", "node22", "typescript") }} } } diff --git a/xrcg/templates/ts/ehconsumer/package.json.jinja b/xrcg/templates/ts/ehconsumer/package.json.jinja index 62dfdce0..0207207d 100644 --- a/xrcg/templates/ts/ehconsumer/package.json.jinja +++ b/xrcg/templates/ts/ehconsumer/package.json.jinja @@ -1,3 +1,4 @@ +{%- import "util.jinja.include" as util -%} { "name": "{{ project_name | snake | replace('_', '-') }}", "version": "1.0.0", @@ -5,6 +6,7 @@ "description": "Azure Event Hubs consumer for {{ project_name }}", "main": "dist/index.js", "types": "dist/index.d.ts", + "overrides": {{ util.DependencyOverrides() }}, "scripts": { "build": "tsc", "watch": "tsc --watch", @@ -18,22 +20,22 @@ "author": "", "license": "MIT", "dependencies": { - "@azure/event-hubs": "^5.11.0", + {{ dependency("ts", "node22", "@azure/event-hubs") }}, "@azure/storage-blob": "^12.17.0", - "@azure/identity": "^4.0.0", - "cloudevents": "^8.0.2" + {{ dependency("ts", "node22", "@azure/identity") }}, + {{ dependency("ts", "node22", "cloudevents") }} }, "devDependencies": { - "@jest/globals": "^29.7.0", - "@types/jest": "^29.5.12", - "@types/node": "^22.7.5", - "@typescript-eslint/eslint-plugin": "^8.8.1", - "@typescript-eslint/parser": "^8.8.1", - "@stylistic/eslint-plugin": "^2.9.0", - "eslint": "^9.12.0", - "jest": "^29.7.0", - "ts-jest": "^29.2.5", - "ts-node": "^10.9.0", - "typescript": "^5.6.3" + {{ dependency("ts", "node22", "@jest/globals") }}, + {{ dependency("ts", "node22", "@types/jest") }}, + {{ dependency("ts", "node22", "@types/node") }}, + {{ dependency("ts", "node22", "@typescript-eslint/eslint-plugin") }}, + {{ dependency("ts", "node22", "@typescript-eslint/parser") }}, + {{ dependency("ts", "node22", "@stylistic/eslint-plugin") }}, + {{ dependency("ts", "node22", "eslint") }}, + {{ dependency("ts", "node22", "jest") }}, + {{ dependency("ts", "node22", "ts-jest") }}, + {{ dependency("ts", "node22", "ts-node") }}, + {{ dependency("ts", "node22", "typescript") }} } } diff --git a/xrcg/templates/ts/ehproducer/package.json.jinja b/xrcg/templates/ts/ehproducer/package.json.jinja index 3c8f1c8f..4ba3bd2f 100644 --- a/xrcg/templates/ts/ehproducer/package.json.jinja +++ b/xrcg/templates/ts/ehproducer/package.json.jinja @@ -1,3 +1,4 @@ +{%- import "util.jinja.include" as util -%} { "name": "{{ project_name | lower | replace('.', '-') }}-eventhubs-producer", "version": "1.0.0", @@ -5,6 +6,7 @@ "description": "Azure Event Hubs Producer for {{ project_name }}", "main": "dist/index.js", "types": "dist/index.d.ts", + "overrides": {{ util.DependencyOverrides() }}, "scripts": { "build": "tsc", "test": "jest", @@ -12,19 +14,19 @@ "clean": "rm -rf dist" }, "dependencies": { - "@azure/event-hubs": "^5.11.0", - "@azure/identity": "^4.0.0", - "cloudevents": "^8.0.2", - "uuid": "^9.0.0" + {{ dependency("ts", "node22", "@azure/event-hubs") }}, + {{ dependency("ts", "node22", "@azure/identity") }}, + {{ dependency("ts", "node22", "cloudevents") }}, + {{ dependency("ts", "node22", "uuid") }} }, "devDependencies": { - "@jest/globals": "^29.7.0", - "@types/jest": "^29.5.12", - "@types/node": "^22.7.5", - "@types/uuid": "^9.0.0", - "jest": "^29.7.0", - "testcontainers": "^10.0.0", - "ts-jest": "^29.2.5", - "typescript": "^5.6.3" + {{ dependency("ts", "node22", "@jest/globals") }}, + {{ dependency("ts", "node22", "@types/jest") }}, + {{ dependency("ts", "node22", "@types/node") }}, + {{ dependency("ts", "node22", "@types/uuid") }}, + {{ dependency("ts", "node22", "jest") }}, + {{ dependency("ts", "node22", "testcontainers") }}, + {{ dependency("ts", "node22", "ts-jest") }}, + {{ dependency("ts", "node22", "typescript") }} } } diff --git a/xrcg/templates/ts/kafkaconsumer/package.json.jinja b/xrcg/templates/ts/kafkaconsumer/package.json.jinja index cab62e57..68d5aa4a 100644 --- a/xrcg/templates/ts/kafkaconsumer/package.json.jinja +++ b/xrcg/templates/ts/kafkaconsumer/package.json.jinja @@ -1,3 +1,4 @@ +{%- import "util.jinja.include" as util -%} { "name": "{{ project_name | snake | replace('_', '-') }}", "version": "1.0.0", @@ -5,6 +6,7 @@ "type": "module", "main": "dist/index.js", "types": "dist/index.d.ts", + "overrides": {{ util.DependencyOverrides() }}, "scripts": { "build": "tsc", "watch": "tsc --watch", @@ -18,22 +20,22 @@ "author": "", "license": "MIT", "dependencies": { - "kafkajs": "^2.2.4", - "cloudevents": "^8.0.2" + {{ dependency("ts", "node22", "kafkajs") }}, + {{ dependency("ts", "node22", "cloudevents") }} }, "devDependencies": { - "@jest/globals": "^29.7.0", - "@types/jest": "^29.5.12", - "@types/node": "^22.7.5", - "@typescript-eslint/eslint-plugin": "^8.8.1", - "@typescript-eslint/parser": "^8.8.1", - "@stylistic/eslint-plugin": "^2.9.0", - "eslint": "^9.12.0", - "jest": "^29.7.0", - "ts-jest": "^29.2.5", - "ts-node": "^10.9.2", - "typescript": "^5.6.3", - "testcontainers": "^10.13.2", - "@testcontainers/kafka": "^11.7.2" + {{ dependency("ts", "node22", "@jest/globals") }}, + {{ dependency("ts", "node22", "@types/jest") }}, + {{ dependency("ts", "node22", "@types/node") }}, + {{ dependency("ts", "node22", "@typescript-eslint/eslint-plugin") }}, + {{ dependency("ts", "node22", "@typescript-eslint/parser") }}, + {{ dependency("ts", "node22", "@stylistic/eslint-plugin") }}, + {{ dependency("ts", "node22", "eslint") }}, + {{ dependency("ts", "node22", "jest") }}, + {{ dependency("ts", "node22", "ts-jest") }}, + {{ dependency("ts", "node22", "ts-node") }}, + {{ dependency("ts", "node22", "typescript") }}, + {{ dependency("ts", "node22", "testcontainers") }}, + {{ dependency("ts", "node22", "@testcontainers/kafka") }} } } diff --git a/xrcg/templates/ts/kafkaproducer/package.json.jinja b/xrcg/templates/ts/kafkaproducer/package.json.jinja index edb20d35..b88968ed 100644 --- a/xrcg/templates/ts/kafkaproducer/package.json.jinja +++ b/xrcg/templates/ts/kafkaproducer/package.json.jinja @@ -1,3 +1,4 @@ +{%- import "util.jinja.include" as util -%} { "name": "{{ project_name | snake | replace('_', '-') }}", "version": "1.0.0", @@ -5,6 +6,7 @@ "description": "Kafka producer for {{ project_name }}", "main": "dist/index.js", "types": "dist/index.d.ts", + "overrides": {{ util.DependencyOverrides() }}, "scripts": { "build": "tsc", "watch": "tsc --watch", @@ -18,24 +20,24 @@ "author": "", "license": "MIT", "dependencies": { - "kafkajs": "^2.2.4", - "cloudevents": "^8.0.2", - "uuid": "^9.0.0" + {{ dependency("ts", "node22", "kafkajs") }}, + {{ dependency("ts", "node22", "cloudevents") }}, + {{ dependency("ts", "node22", "uuid") }} }, "devDependencies": { - "@jest/globals": "^29.7.0", - "@types/jest": "^29.5.12", - "@types/node": "^22.7.5", - "@types/uuid": "^9.0.0", - "@typescript-eslint/eslint-plugin": "^8.8.1", - "@typescript-eslint/parser": "^8.8.1", - "@stylistic/eslint-plugin": "^2.9.0", - "eslint": "^9.12.0", - "jest": "^29.7.0", - "ts-jest": "^29.2.5", - "ts-node": "^10.9.0", - "typescript": "^5.6.3", - "testcontainers": "^10.0.0", - "@testcontainers/kafka": "^11.7.2" + {{ dependency("ts", "node22", "@jest/globals") }}, + {{ dependency("ts", "node22", "@types/jest") }}, + {{ dependency("ts", "node22", "@types/node") }}, + {{ dependency("ts", "node22", "@types/uuid") }}, + {{ dependency("ts", "node22", "@typescript-eslint/eslint-plugin") }}, + {{ dependency("ts", "node22", "@typescript-eslint/parser") }}, + {{ dependency("ts", "node22", "@stylistic/eslint-plugin") }}, + {{ dependency("ts", "node22", "eslint") }}, + {{ dependency("ts", "node22", "jest") }}, + {{ dependency("ts", "node22", "ts-jest") }}, + {{ dependency("ts", "node22", "ts-node") }}, + {{ dependency("ts", "node22", "typescript") }}, + {{ dependency("ts", "node22", "testcontainers") }}, + {{ dependency("ts", "node22", "@testcontainers/kafka") }} } } diff --git a/xrcg/templates/ts/mqttclient/package.json.jinja b/xrcg/templates/ts/mqttclient/package.json.jinja index de794a11..612b6950 100644 --- a/xrcg/templates/ts/mqttclient/package.json.jinja +++ b/xrcg/templates/ts/mqttclient/package.json.jinja @@ -1,3 +1,4 @@ +{%- import "util.jinja.include" as util -%} { "name": "{{ project_name | lower | replace('.', '-') }}-mqtt-client", "version": "1.0.0", @@ -5,6 +6,7 @@ "description": "MQTT Client for {{ project_name }}", "main": "dist/index.js", "types": "dist/index.d.ts", + "overrides": {{ util.DependencyOverrides() }}, "scripts": { "build": "tsc", "test": "jest", @@ -12,18 +14,18 @@ "clean": "rm -rf dist" }, "dependencies": { - "mqtt": "^5.0.0", - "cloudevents": "^8.0.2", - "uuid": "^9.0.0" + {{ dependency("ts", "node22", "mqtt") }}, + {{ dependency("ts", "node22", "cloudevents") }}, + {{ dependency("ts", "node22", "uuid") }} }, "devDependencies": { - "@jest/globals": "^29.7.0", - "@types/jest": "^29.5.12", - "@types/node": "^22.7.5", - "@types/uuid": "^9.0.0", - "aedes": "^0.51.0", - "jest": "^29.7.0", - "ts-jest": "^29.2.5", - "typescript": "^5.6.3" + {{ dependency("ts", "node22", "@jest/globals") }}, + {{ dependency("ts", "node22", "@types/jest") }}, + {{ dependency("ts", "node22", "@types/node") }}, + {{ dependency("ts", "node22", "@types/uuid") }}, + {{ dependency("ts", "node22", "aedes") }}, + {{ dependency("ts", "node22", "jest") }}, + {{ dependency("ts", "node22", "ts-jest") }}, + {{ dependency("ts", "node22", "typescript") }} } } diff --git a/xrcg/templates/ts/mqttclient/src/client.ts.jinja b/xrcg/templates/ts/mqttclient/src/client.ts.jinja index 036cdbb2..c5af9a99 100644 --- a/xrcg/templates/ts/mqttclient/src/client.ts.jinja +++ b/xrcg/templates/ts/mqttclient/src/client.ts.jinja @@ -123,7 +123,7 @@ export class {{ class_name }} { * {{ message.description }} {%- endif %} */ - public {{ messagename }}Handler?: ({% if isCloudEvent %}cloudEvent: CloudEvent, {% endif %}data: {{ message_body_type }}, topicParams: Record) => Promise; + public {{ messagename }}Handler?: ({% if isCloudEvent %}cloudEvent: CloudEvent, {% endif %}data: {{ message_body_type }}, topicParams: Record) => Promise; {%- endfor %} /** @@ -275,7 +275,7 @@ export class {{ class_name }} { }); const cloudEvent = Array.isArray(result) ? result[0] : result; if (cloudEvent) { - await this.dispatchCloudEvent(topic, cloudEvent); + await this.dispatchCloudEvent(topic, new CloudEvent(cloudEvent)); return; } } diff --git a/xrcg/templates/ts/mqttclient/test/client.test.ts.jinja b/xrcg/templates/ts/mqttclient/test/client.test.ts.jinja index 8c1c6ac2..af625dcd 100644 --- a/xrcg/templates/ts/mqttclient/test/client.test.ts.jinja +++ b/xrcg/templates/ts/mqttclient/test/client.test.ts.jinja @@ -167,7 +167,7 @@ describe('{{ test_class_name }}', () => { await new Promise(resolve => setTimeout(resolve, 500)); const received: Array<{ - cloudEvent: CloudEvent; + cloudEvent: CloudEvent; data: {{ body_type }}; topicParams: Record; }> = []; @@ -175,7 +175,7 @@ describe('{{ test_class_name }}', () => { const donePromise = new Promise(resolve => { _resolve = resolve; }); subscriber.{{ messagename }}Handler = async ( - cloudEvent: CloudEvent, + cloudEvent: CloudEvent, data: {{ body_type }}, topicParams: Record, ) => { @@ -229,9 +229,9 @@ describe('{{ test_class_name }}', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any jest.spyOn((client as any).client as mqtt.MqttClient, 'publish').mockImplementation( // eslint-disable-next-line @typescript-eslint/no-explicit-any - (t: any, p: any, o: any, cb?: (err?: Error | null) => void) => { + (t: any, p: any, o: any, cb?: mqtt.PacketCallback) => { captured.push({ topic: String(t), payload: String(p), opts: o as mqtt.IClientPublishOptions }); - cb?.(null); + cb?.(); // eslint-disable-next-line @typescript-eslint/no-explicit-any return (client as any).client; }, @@ -274,9 +274,9 @@ describe('{{ test_class_name }}', () => { test('{{ messagename }}: binary-mode User Property decoding (no-broker)', async () => { // Tests handleMessage with a simulated MQTT5 PUBLISH packet carrying CE User Properties. const client = new {{ class_name }}('mqtt://localhost:1', { manualConnect: true }, undefined, 'binary'); - const received: Array<{ cloudEvent: CloudEvent; data: {{ body_type }}; topicParams: Record }> = []; + const received: Array<{ cloudEvent: CloudEvent; data: {{ body_type }}; topicParams: Record }> = []; client.{{ messagename }}Handler = async ( - cloudEvent: CloudEvent, + cloudEvent: CloudEvent, data: {{ body_type }}, topicParams: Record, ) => { diff --git a/xrcg/templates/ts/sbconsumer/package.json.jinja b/xrcg/templates/ts/sbconsumer/package.json.jinja index 77f51d2e..a81f244e 100644 --- a/xrcg/templates/ts/sbconsumer/package.json.jinja +++ b/xrcg/templates/ts/sbconsumer/package.json.jinja @@ -1,3 +1,4 @@ +{%- import "util.jinja.include" as util -%} { "name": "{{ project_name | lower | replace('.', '-') }}-servicebus-consumer", "version": "1.0.0", @@ -5,6 +6,7 @@ "description": "Azure Service Bus Consumer for {{ project_name }}", "main": "dist/index.js", "types": "dist/index.d.ts", + "overrides": {{ util.DependencyOverrides() }}, "scripts": { "build": "tsc", "test": "jest", @@ -12,17 +14,17 @@ "clean": "rm -rf dist" }, "dependencies": { - "@azure/service-bus": "^7.9.0", - "@azure/identity": "^4.0.0", - "cloudevents": "^8.0.2" + {{ dependency("ts", "node22", "@azure/service-bus") }}, + {{ dependency("ts", "node22", "@azure/identity") }}, + {{ dependency("ts", "node22", "cloudevents") }} }, "devDependencies": { - "@jest/globals": "^29.7.0", - "@types/jest": "^29.5.12", - "@types/node": "^22.7.5", - "jest": "^29.7.0", - "testcontainers": "^10.16.0", - "ts-jest": "^29.2.5", - "typescript": "^5.6.3" + {{ dependency("ts", "node22", "@jest/globals") }}, + {{ dependency("ts", "node22", "@types/jest") }}, + {{ dependency("ts", "node22", "@types/node") }}, + {{ dependency("ts", "node22", "jest") }}, + {{ dependency("ts", "node22", "testcontainers") }}, + {{ dependency("ts", "node22", "ts-jest") }}, + {{ dependency("ts", "node22", "typescript") }} } } diff --git a/xrcg/templates/ts/sbproducer/package.json.jinja b/xrcg/templates/ts/sbproducer/package.json.jinja index e5dd9145..576d49c6 100644 --- a/xrcg/templates/ts/sbproducer/package.json.jinja +++ b/xrcg/templates/ts/sbproducer/package.json.jinja @@ -1,3 +1,4 @@ +{%- import "util.jinja.include" as util -%} { "name": "{{ project_name | lower | replace('.', '-') }}-servicebus-producer", "version": "1.0.0", @@ -5,6 +6,7 @@ "description": "Azure Service Bus Producer for {{ project_name }}", "main": "dist/index.js", "types": "dist/index.d.ts", + "overrides": {{ util.DependencyOverrides() }}, "scripts": { "build": "tsc", "test": "jest", @@ -12,19 +14,19 @@ "clean": "rm -rf dist" }, "dependencies": { - "@azure/service-bus": "^7.9.0", - "@azure/identity": "^4.0.0", - "cloudevents": "^8.0.2", - "uuid": "^9.0.0" + {{ dependency("ts", "node22", "@azure/service-bus") }}, + {{ dependency("ts", "node22", "@azure/identity") }}, + {{ dependency("ts", "node22", "cloudevents") }}, + {{ dependency("ts", "node22", "uuid") }} }, "devDependencies": { - "@jest/globals": "^29.7.0", - "@types/jest": "^29.5.12", - "@types/node": "^22.7.5", - "@types/uuid": "^9.0.0", - "jest": "^29.7.0", - "testcontainers": "^10.13.2", - "ts-jest": "^29.2.5", - "typescript": "^5.6.3" + {{ dependency("ts", "node22", "@jest/globals") }}, + {{ dependency("ts", "node22", "@types/jest") }}, + {{ dependency("ts", "node22", "@types/node") }}, + {{ dependency("ts", "node22", "@types/uuid") }}, + {{ dependency("ts", "node22", "jest") }}, + {{ dependency("ts", "node22", "testcontainers") }}, + {{ dependency("ts", "node22", "ts-jest") }}, + {{ dependency("ts", "node22", "typescript") }} } } From 29dbda86c215a272eb4a94240a5ab07fbe4910d2 Mon Sep 17 00:00:00 2001 From: Clemens Vasters Date: Mon, 9 Nov 2026 21:31:16 +0100 Subject: [PATCH 2/5] Require the published Avrotize decoder security fix Raise the Avrotize minimum to 3.9.5 after successful Marketplace and PyPI publication. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: dfdd160a-bd4a-4a7e-bfb0-34d189fc944a Signed-off-by: Clemens Vasters --- pyproject.toml | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 2e164d5d..85731e3e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ dependencies = [ "jsonschema>=4.22.0", "pydot>=2.0.0", "anytree>=2.12.1", - "avrotize>=3.9.1", + "avrotize>=3.9.5", "avro>=1.11.5", "toml>=0.10.2", "platformdirs>=4.0.0" diff --git a/requirements.txt b/requirements.txt index 87674f7c..bf85a87d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,5 +7,5 @@ jsonschema>=4.17.3 pydot>=1.4.2 anytree>=2.8.0 flit>=4.2.0 -avrotize>=3.9.1 +avrotize>=3.9.5 toml>=0.10.2 \ No newline at end of file From 65092e52a93b03e2b05a65c043bac6965e2546b1 Mon Sep 17 00:00:00 2001 From: Clemens Vasters Date: Mon, 9 Nov 2026 22:09:17 +0100 Subject: [PATCH 3/5] Align CI runtime and C# dependencies with updated generators Run TypeScript integration tests on Node 22 and prevent System.Memory.Data downgrades against Avrotize 3.9.5 data projects. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: dfdd160a-bd4a-4a7e-bfb0-34d189fc944a Signed-off-by: Clemens Vasters --- .github/workflows/test.yml | 2 +- xrcg/dependencies/cs/net100/dependencies.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5c203ac4..b4f9ff17 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -181,7 +181,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v7 with: - node-version: '20' + node-version: '22' - name: Set up Python uses: actions/setup-python@v7 with: diff --git a/xrcg/dependencies/cs/net100/dependencies.csproj b/xrcg/dependencies/cs/net100/dependencies.csproj index e3b0da36..68130704 100644 --- a/xrcg/dependencies/cs/net100/dependencies.csproj +++ b/xrcg/dependencies/cs/net100/dependencies.csproj @@ -32,7 +32,7 @@ - + From 9ea231855ddb826e77ffff9d86e35f46038aedaf Mon Sep 17 00:00:00 2001 From: Clemens Vasters Date: Mon, 9 Nov 2026 22:13:17 +0100 Subject: [PATCH 4/5] Use Node 22 for extension release tooling Keep release packaging and Marketplace workflows on the runtime required by the updated VSCE toolchain. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: dfdd160a-bd4a-4a7e-bfb0-34d189fc944a Signed-off-by: Clemens Vasters --- .github/workflows/build.yml | 2 +- .github/workflows/publish-vscode.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5f6951c9..11cb0501 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,7 +31,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v7 with: - node-version: '20' + node-version: '22' - name: Validate VSCode extension for duplicate commands run: python tools/validate_vscode_package.py --package-json xrcg_vscode/package.json - name: Build VSCode extension diff --git a/.github/workflows/publish-vscode.yml b/.github/workflows/publish-vscode.yml index 166fee9d..20086852 100644 --- a/.github/workflows/publish-vscode.yml +++ b/.github/workflows/publish-vscode.yml @@ -37,7 +37,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v7 with: - node-version: '20' + node-version: '22' - name: Set up Python uses: actions/setup-python@v7 From 059f44bbbc75a65a332322686a38ae878c0480b9 Mon Sep 17 00:00:00 2001 From: Clemens Vasters Date: Mon, 9 Nov 2026 23:00:19 +0100 Subject: [PATCH 5/5] Fix updated Azure TypeScript SDK compatibility Transform ESM proxy dependencies in generated Azure SDK Jest suites and adapt CloudEvent timestamps to Event Grid's Date input. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: dfdd160a-bd4a-4a7e-bfb0-34d189fc944a Signed-off-by: Clemens Vasters --- xrcg/templates/ts/egproducer/jest.config.js.jinja | 3 ++- xrcg/templates/ts/egproducer/src/producer.ts.jinja | 8 ++++++-- xrcg/templates/ts/sbconsumer/jest.config.js.jinja | 3 ++- xrcg/templates/ts/sbproducer/jest.config.js.jinja | 3 ++- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/xrcg/templates/ts/egproducer/jest.config.js.jinja b/xrcg/templates/ts/egproducer/jest.config.js.jinja index c9c171aa..e7e8573c 100644 --- a/xrcg/templates/ts/egproducer/jest.config.js.jinja +++ b/xrcg/templates/ts/egproducer/jest.config.js.jinja @@ -10,11 +10,12 @@ export default { 'ts-jest', { useESM: true, + tsconfig: { allowJs: true }, }, ], }, transformIgnorePatterns: [ - '/node_modules/', + '/node_modules/(?!(?:https-proxy-agent|http-proxy-agent|agent-base|proxy-agent-negotiate)/)', ], testMatch: ['**/test/**/*.test.ts'], collectCoverageFrom: ['src/**/*.ts'], diff --git a/xrcg/templates/ts/egproducer/src/producer.ts.jinja b/xrcg/templates/ts/egproducer/src/producer.ts.jinja index e0602f4e..49bb139a 100644 --- a/xrcg/templates/ts/egproducer/src/producer.ts.jinja +++ b/xrcg/templates/ts/egproducer/src/producer.ts.jinja @@ -130,7 +130,8 @@ export class {{ class_name }} { datacontenttype: contentType }); - await this.client.send([cloudEvent]); + const { time, ...event } = cloudEvent; + await this.client.send([{ ...event, ...(time ? { time: new Date(time) } : {}) }]); } /** @@ -185,7 +186,10 @@ export class {{ class_name }} { }); }); - await this.client.send(events); + await this.client.send(events.map(({ time, ...event }) => ({ + ...event, + ...(time ? { time: new Date(time) } : {}), + }))); } {% endfor %} } diff --git a/xrcg/templates/ts/sbconsumer/jest.config.js.jinja b/xrcg/templates/ts/sbconsumer/jest.config.js.jinja index c9c171aa..e7e8573c 100644 --- a/xrcg/templates/ts/sbconsumer/jest.config.js.jinja +++ b/xrcg/templates/ts/sbconsumer/jest.config.js.jinja @@ -10,11 +10,12 @@ export default { 'ts-jest', { useESM: true, + tsconfig: { allowJs: true }, }, ], }, transformIgnorePatterns: [ - '/node_modules/', + '/node_modules/(?!(?:https-proxy-agent|http-proxy-agent|agent-base|proxy-agent-negotiate)/)', ], testMatch: ['**/test/**/*.test.ts'], collectCoverageFrom: ['src/**/*.ts'], diff --git a/xrcg/templates/ts/sbproducer/jest.config.js.jinja b/xrcg/templates/ts/sbproducer/jest.config.js.jinja index c9c171aa..e7e8573c 100644 --- a/xrcg/templates/ts/sbproducer/jest.config.js.jinja +++ b/xrcg/templates/ts/sbproducer/jest.config.js.jinja @@ -10,11 +10,12 @@ export default { 'ts-jest', { useESM: true, + tsconfig: { allowJs: true }, }, ], }, transformIgnorePatterns: [ - '/node_modules/', + '/node_modules/(?!(?:https-proxy-agent|http-proxy-agent|agent-base|proxy-agent-negotiate)/)', ], testMatch: ['**/test/**/*.test.ts'], collectCoverageFrom: ['src/**/*.ts'],