diff --git a/README.md b/README.md index c39e6fa..1590bb5 100644 --- a/README.md +++ b/README.md @@ -16,18 +16,16 @@ sequenceDiagram Hercules->>Aquila: Register datatypes
because maybe they are needed in the config definitions Aquila-->>Hercules: Validation result - - Hercules->>Stream: Open bi-directional stream - Hercules->>Stream: ActionLogon request - - Hercules->>Aquila: Register function definitions Aquila-->>Hercules: Validation result Hercules->>Aquila: Register flow types Aquila-->>Hercules: Validation result + Hercules->>Stream: Open bi-directional stream + Hercules->>Stream: ActionLogon request + Stream-->>Hercules: Receive action configurations ``` @@ -62,3 +60,4 @@ To use a simple test server use the following command: ./bin/test_server.rb ``` This will start a test server on `localhost:50051` that you can connect to with the action sdk. +Watch out this test server isnt really working its just an way to test the connection. diff --git a/bin/.rubocop.yml b/bin/.rubocop.yml deleted file mode 100644 index 69e4753..0000000 --- a/bin/.rubocop.yml +++ /dev/null @@ -1,26 +0,0 @@ -AllCops: - NewCops: enable - -Lint/AmbiguousBlockAssociation: - AllowedMethods: [change] - -Metrics: - Enabled: false - -Naming/BlockForwarding: - Enabled: false - -Naming/MethodParameterName: - Enabled: false - -Style/ArgumentsForwarding: - Enabled: false - -Style/Documentation: - Enabled: false - -Style/HashSyntax: - EnforcedShorthandSyntax: never - -Style/TrailingCommaInHashLiteral: - EnforcedStyleForMultiline: comma diff --git a/bin/Gemfile b/bin/Gemfile deleted file mode 100644 index 23c96af..0000000 --- a/bin/Gemfile +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -source 'https://rubygems.org' - -ruby '3.4.7' - -gem 'grpc', '~> 1.67' -gem 'tucana', '0.0.57' diff --git a/bin/Gemfile.lock b/bin/Gemfile.lock deleted file mode 100644 index a0fe082..0000000 --- a/bin/Gemfile.lock +++ /dev/null @@ -1,35 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - bigdecimal (4.0.1) - google-protobuf (4.34.0) - bigdecimal - rake (~> 13.3) - google-protobuf (4.34.0-x86_64-linux-gnu) - bigdecimal - rake (~> 13.3) - googleapis-common-protos-types (1.22.0) - google-protobuf (~> 4.26) - grpc (1.78.1) - google-protobuf (>= 3.25, < 5.0) - googleapis-common-protos-types (~> 1.0) - grpc (1.78.1-x86_64-linux-gnu) - google-protobuf (>= 3.25, < 5.0) - googleapis-common-protos-types (~> 1.0) - rake (13.3.1) - tucana (0.0.57) - grpc (~> 1.64) - -PLATFORMS - ruby - x86_64-linux - -DEPENDENCIES - grpc (~> 1.67) - tucana (= 0.0.57) - -RUBY VERSION - ruby 3.4.7p58 - -BUNDLED WITH - 2.7.2 diff --git a/bin/test_server.rb b/bin/test_server.rb deleted file mode 100755 index cd4d80e..0000000 --- a/bin/test_server.rb +++ /dev/null @@ -1,186 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -require 'grpc' -require 'tucana' - -Tucana.load_protocol(:aquila) - -class State - attr_reader :data_types, :runtime_functions, :flow_types, :action_config_definitions - - def initialize - @data_types = [] - @runtime_functions = [] - @flow_types = [] - @action_config_definitions = [] - end - - def add_flow_types(flow_types) - @flow_types += flow_types - end - - def add_data_types(dts) - @data_types += dts - end - - def add_runtime_functions(functions) - @runtime_functions += functions - end - - def add_action_config_definition(config) - @action_config_definitions << config - end -end - -class FlowTypeTransferService < Tucana::Aquila::FlowTypeService::Service - def initialize(state) - @state = state - end - - def update(req, call) - puts "Got Auth token: #{call.metadata['authorization']}" - @state.add_flow_types(req.flow_types) - - puts "Flowtypes received: #{req.flow_types.map(&:identifier).join(', ')}" - - Tucana::Aquila::RuntimeFunctionDefinitionUpdateResponse.new(success: true) - end -end - -class RuntimeFunctionDefinitionTransferService < Tucana::Aquila::RuntimeFunctionDefinitionService::Service - def initialize(state) - @state = state - end - - def update(req, call) - puts "Got Auth token: #{call.metadata['authorization']}" - @state.add_runtime_functions(req.runtime_functions) - - puts "RuntimeFunctionDefinitions received: #{req.runtime_functions.map(&:runtime_name).join(', ')}" - - Tucana::Aquila::RuntimeFunctionDefinitionUpdateResponse.new(success: true) - end -end - -class DataTypeTransferService < Tucana::Aquila::DataTypeService::Service - def initialize(state) - @state = state - end - - def update(req, call) - puts "Got Auth token: #{call.metadata['authorization']}" - @state.add_data_types(req.data_types) - puts "Data types received: #{req.data_types.map(&:identifier).join(', ')}" - Tucana::Aquila::DataTypeUpdateResponse.new(success: true) - end -end - -class ActionTransferService < Tucana::Aquila::ActionTransferService::Service - def initialize(state) - @state = state - @sent_configs = [] - end - - def construct_parameters(func) - struct = Tucana::Shared::Struct.new - - func.runtime_parameter_definitions.each do |param_def| - struct.fields[param_def.runtime_name] = param_def.default_value - end - - struct - end - - def transfer(requests, call) - token = call.metadata['authorization'] - puts "Got Auth token: #{token}" - Enumerator.new do |yielder| - Thread.new do - loop do - sleep 5 - @state.action_config_definitions.each do |config| - next if @sent_configs.include?(config[:identifier]) - - puts "Received action config definition: #{config[:action_identifier]} (v#{config[:version]})" - count = Random.rand(1..5) - puts "Creating #{count} mock project config" - proj_conf = [] - - count.times do |i| - proj_conf << Tucana::Shared::ActionProjectConfiguration.new( - project_id: Random.rand(1..1000), - action_configurations: [ - Tucana::Shared::ActionConfiguration.new( - identifier: config[:identifier], - value: Tucana::Shared::Value.from_ruby("test value for project: #{i}") - ) - ] - ) - end - - yielder << Tucana::Aquila::TransferResponse.new( - { - action_configurations: - Tucana::Shared::ActionConfigurations.new(action_configurations: proj_conf), - } - ) - @sent_configs << config[:identifier] - end - @state.runtime_functions.each do |func| - puts "Sending execute request for: #{func.runtime_name}" - exec_identifier = "exec_#{func.runtime_name}_#{Time.now.to_i}" - puts "Execution identifier: #{exec_identifier}" - yielder << Tucana::Aquila::TransferResponse.new( - { - execution: Tucana::Aquila::ExecutionRequest.new( - project_id: Random.rand(1..1000), - execution_identifier: exec_identifier, - function_identifier: func.runtime_name, - parameters: construct_parameters(func) - ), - } - ) - end - end - end - - requests.each do |req| - unless req.result.nil? - puts "Received execution result for: #{req.result.execution_identifier}" - puts "Result value: #{req.result.result}" - next - end - - unless req.event.nil? - puts "Received event: #{req.event.event_type}" - puts "Event data: #{req.event.payload}" - puts "Project id: #{req.event.project_id}" - next - end - next if req.logon.nil? - - logon = req.logon - - @state.add_action_config_definition({ - auth_token: token, - action_identifier: logon.action_identifier, - version: logon.version, - config_definitions: logon.action_configurations, - }) - - puts "Action logon received: #{logon.action_identifier} (v#{logon.version})" - end - end - end -end - -state = State.new - -server = GRPC::RpcServer.new -server.add_http2_port('0.0.0.0:50051', :this_port_is_insecure) -server.handle(ActionTransferService.new(state)) -server.handle(DataTypeTransferService.new(state)) -server.handle(RuntimeFunctionDefinitionTransferService.new(state)) -server.handle(FlowTypeTransferService.new(state)) -server.run_till_terminated_or_interrupted(%w[INT TERM QUIT]) diff --git a/ts/.gitignore b/ts/.gitignore index 3c10377..337f5b2 100644 --- a/ts/.gitignore +++ b/ts/.gitignore @@ -1,3 +1,35 @@ -node_modules -dist -code0-tech-hercules-*.tgz \ No newline at end of file +# Dependencies +node_modules/ + +# Build output +dist/ + +# Packed tarballs +*.tgz + +# Environment +.env +.env.* +!.env.example + +# Logs +*.log +logs/ + +# OS +.DS_Store +Thumbs.db + +# IDE +.idea/ +.vscode/ +*.suo +*.ntvs* +*.njsproj +*.sln + +# Test coverage +coverage/ + +#definitions +/src/definitions/**/* diff --git a/ts/examples/simple-example-ts/.gitignore b/ts/examples/simple-example-ts/.gitignore new file mode 100644 index 0000000..c744b43 --- /dev/null +++ b/ts/examples/simple-example-ts/.gitignore @@ -0,0 +1,5 @@ +node_modules/ +dist/ +.env +.env.* +!.env.example diff --git a/ts/examples/simple-example-ts/example.env b/ts/examples/simple-example-ts/example.env new file mode 100644 index 0000000..8f27264 --- /dev/null +++ b/ts/examples/simple-example-ts/example.env @@ -0,0 +1,4 @@ +AUTH_TOKEN=your_auth_token_here +AQUILA_URL=https://127.0.0.1:8000 +ACTION_ID=your_action_id_here +VERSION=0.0.0 \ No newline at end of file diff --git a/ts/examples/simple-example-ts/index.ts b/ts/examples/simple-example-ts/index.ts deleted file mode 100644 index f1a9ede..0000000 --- a/ts/examples/simple-example-ts/index.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { - createSdk, - HerculesActionProjectConfiguration, - HerculesFunctionContext, - RuntimeErrorException -} from "@code0-tech/hercules"; - -const sdk = createSdk({ - authToken: "token", - aquilaUrl: "127.0.0.1:8081", - actionId: "example", - version: "0.0.0", -}, [ - { - type: "string[]", - identifier: "config_discord_bot_token", - } -]) - -sdk.registerDataTypes({ - identifier: "SOME_DATATYPE", - type: "any", -}) - -sdk.registerRuntimeFunctionDefinitionsAndFunctionDefinitions({ - definition: { - signature: "(number: number) => number", - parameters: [ - { - runtimeName: "number", - defaultValue: 20, - } - ], - runtimeName: "fib", - }, - //This param is optional and can be omitted - handler: (context: HerculesFunctionContext, number: bigint): bigint => { - console.log(context) - console.log("Project id:", context.projectId); - console.log("Execution id:", context.executionId); - console.log("Matched configs:", context.matchedConfig); // matched configs for the current execution - - function fibonacci(num: bigint): bigint { - if (num <= 1) return num; - return fibonacci(num - 1n) + fibonacci(num - 2n); - } - - return fibonacci(number) - } - } -) - -sdk.registerFlowTypes( - { - signature: "(): string", - editable: false, - identifier: "test_flow", - } -) - - -connectToSdk(); - -function connectToSdk() { - sdk.connect().then((configs: HerculesActionProjectConfiguration[]) => { - console.log("SDK connected successfully"); - - sdk.dispatchEvent("test_flow", configs[0].projectId, "Hello, World! Configs loaded: " + configs.length).then(() => { - console.log("Event dispatched successfully"); - }) - }).catch(() => { - // will be handled by logger internally - process.exit(1) - }) - - sdk.onError((error) => { - console.error("SDK Error occurred:", error.message); - console.log("Attempting to reconnect in 5s..."); - setTimeout(() => { - connectToSdk(); - }, 5000) - }) -} diff --git a/ts/examples/simple-example-ts/package-lock.json b/ts/examples/simple-example-ts/package-lock.json index b9a1c24..577815c 100644 --- a/ts/examples/simple-example-ts/package-lock.json +++ b/ts/examples/simple-example-ts/package-lock.json @@ -9,671 +9,36 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@code0-tech/hercules": "file:../../code0-tech-hercules-0.0.0.tgz" - } - }, - "node_modules/@code0-tech/hercules": { - "version": "0.0.0", - "resolved": "file:../../code0-tech-hercules-0.0.0.tgz", - "integrity": "sha512-0J+8A+AN0rmy8YTXBAGPBgHYUARwf60k63kiWVHA2dob9xJfX7PyyncnRfPdRG0DtENLVN26qmtTmCRo4mM0kQ==", - "license": "ISC", - "dependencies": { - "@code0-tech/tucana": "0.0.67", - "@grpc/grpc-js": "^1.14.3", - "@protobuf-ts/grpc-backend": "^2.11.1", - "@protobuf-ts/grpc-transport": "^2.11.1", - "@protobuf-ts/runtime": "^2.11.1", - "@protobuf-ts/runtime-rpc": "^2.11.1", - "pino": "^10.3.1", - "pino-pretty": "^13.1.3" - } - }, - "node_modules/@code0-tech/tucana": { - "version": "0.0.67", - "resolved": "https://registry.npmjs.org/@code0-tech/tucana/-/tucana-0.0.67.tgz", - "integrity": "sha512-3V1h3LB+iWeXnt80nsIQo+TeMgVTgbDxvDsAArbffHyU37ii1tsAAV6Ty7wAdkrCSsObyFRpdiIZgzgYVVKfzw==", - "license": "Apache-2.0" - }, - "node_modules/@grpc/grpc-js": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.3.tgz", - "integrity": "sha512-Iq8QQQ/7X3Sac15oB6p0FmUg/klxQvXLeileoqrTRGJYLV+/9tubbr9ipz0GKHjmXVsgFPo/+W+2cA8eNcR+XA==", - "license": "Apache-2.0", - "dependencies": { - "@grpc/proto-loader": "^0.8.0", - "@js-sdsl/ordered-map": "^4.4.2" - }, - "engines": { - "node": ">=12.10.0" - } - }, - "node_modules/@grpc/proto-loader": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.0.tgz", - "integrity": "sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==", - "license": "Apache-2.0", - "dependencies": { - "lodash.camelcase": "^4.3.0", - "long": "^5.0.0", - "protobufjs": "^7.5.3", - "yargs": "^17.7.2" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@js-sdsl/ordered-map": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", - "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, - "node_modules/@pinojs/redact": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz", - "integrity": "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==", - "license": "MIT" - }, - "node_modules/@protobuf-ts/grpc-backend": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/@protobuf-ts/grpc-backend/-/grpc-backend-2.11.1.tgz", - "integrity": "sha512-llAkJ03SlR/+p70YBTMOAQqdkXWghsTWwlPuGXC+Hj99hDQq6fa2CoVePPqbcn7A7/aLBcPG/9Ag3yqlltldxw==", - "license": "Apache-2.0", - "dependencies": { - "@protobuf-ts/runtime": "^2.11.1", - "@protobuf-ts/runtime-rpc": "^2.11.1" - }, - "peerDependencies": { - "@grpc/grpc-js": "^1.8.22" - } - }, - "node_modules/@protobuf-ts/grpc-transport": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/@protobuf-ts/grpc-transport/-/grpc-transport-2.11.1.tgz", - "integrity": "sha512-l6wrcFffY+tuNnuyrNCkRM8hDIsAZVLA8Mn7PKdVyYxITosYh60qW663p9kL6TWXYuDCL3oxH8ih3vLKTDyhtg==", - "license": "Apache-2.0", - "dependencies": { - "@protobuf-ts/runtime": "^2.11.1", - "@protobuf-ts/runtime-rpc": "^2.11.1" + "zod": "^4.4.3" }, - "peerDependencies": { - "@grpc/grpc-js": "^1.6.0" - } - }, - "node_modules/@protobuf-ts/runtime": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/@protobuf-ts/runtime/-/runtime-2.11.1.tgz", - "integrity": "sha512-KuDaT1IfHkugM2pyz+FwiY80ejWrkH1pAtOBOZFuR6SXEFTsnb/jiQWQ1rCIrcKx2BtyxnxW6BWwsVSA/Ie+WQ==", - "license": "(Apache-2.0 AND BSD-3-Clause)" - }, - "node_modules/@protobuf-ts/runtime-rpc": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/@protobuf-ts/runtime-rpc/-/runtime-rpc-2.11.1.tgz", - "integrity": "sha512-4CqqUmNA+/uMz00+d3CYKgElXO9VrEbucjnBFEjqI4GuDrEQ32MaI3q+9qPBvIGOlL4PmHXrzM32vBPWRhQKWQ==", - "license": "Apache-2.0", - "dependencies": { - "@protobuf-ts/runtime": "^2.11.1" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" + "devDependencies": { + "@types/node": "^22.0.0" } }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", - "license": "BSD-3-Clause" - }, "node_modules/@types/node": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz", - "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==", - "license": "MIT", - "dependencies": { - "undici-types": "~7.18.0" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/atomic-sleep": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", - "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", - "license": "MIT", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "license": "MIT" - }, - "node_modules/dateformat": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", - "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/end-of-stream": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/fast-copy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-4.0.2.tgz", - "integrity": "sha512-ybA6PDXIXOXivLJK/z9e+Otk7ve13I4ckBvGO5I2RRmBU1gMHLVDJYEuJYhGwez7YNlYji2M2DvVU+a9mSFDlw==", - "license": "MIT" - }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", - "license": "MIT" - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/help-me": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", - "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==", - "license": "MIT" - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/joycon": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", - "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "license": "MIT" - }, - "node_modules/long": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", - "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", - "license": "Apache-2.0" - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-exit-leak-free": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", - "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/pino": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/pino/-/pino-10.3.1.tgz", - "integrity": "sha512-r34yH/GlQpKZbU1BvFFqOjhISRo1MNx1tWYsYvmj6KIRHSPMT2+yHOEb1SG6NMvRoHRF0a07kCOox/9yakl1vg==", - "license": "MIT", - "dependencies": { - "@pinojs/redact": "^0.4.0", - "atomic-sleep": "^1.0.0", - "on-exit-leak-free": "^2.1.0", - "pino-abstract-transport": "^3.0.0", - "pino-std-serializers": "^7.0.0", - "process-warning": "^5.0.0", - "quick-format-unescaped": "^4.0.3", - "real-require": "^0.2.0", - "safe-stable-stringify": "^2.3.1", - "sonic-boom": "^4.0.1", - "thread-stream": "^4.0.0" - }, - "bin": { - "pino": "bin.js" - } - }, - "node_modules/pino-abstract-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-3.0.0.tgz", - "integrity": "sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg==", - "license": "MIT", - "dependencies": { - "split2": "^4.0.0" - } - }, - "node_modules/pino-pretty": { - "version": "13.1.3", - "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-13.1.3.tgz", - "integrity": "sha512-ttXRkkOz6WWC95KeY9+xxWL6AtImwbyMHrL1mSwqwW9u+vLp/WIElvHvCSDg0xO/Dzrggz1zv3rN5ovTRVowKg==", - "license": "MIT", - "dependencies": { - "colorette": "^2.0.7", - "dateformat": "^4.6.3", - "fast-copy": "^4.0.0", - "fast-safe-stringify": "^2.1.1", - "help-me": "^5.0.0", - "joycon": "^3.1.1", - "minimist": "^1.2.6", - "on-exit-leak-free": "^2.1.0", - "pino-abstract-transport": "^3.0.0", - "pump": "^3.0.0", - "secure-json-parse": "^4.0.0", - "sonic-boom": "^4.0.1", - "strip-json-comments": "^5.0.2" - }, - "bin": { - "pino-pretty": "bin.js" - } - }, - "node_modules/pino-std-serializers": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.1.0.tgz", - "integrity": "sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==", - "license": "MIT" - }, - "node_modules/process-warning": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz", - "integrity": "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "MIT" - }, - "node_modules/protobufjs": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", - "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/pump": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", - "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/quick-format-unescaped": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", - "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", - "license": "MIT" - }, - "node_modules/real-require": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", - "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", - "license": "MIT", - "engines": { - "node": ">= 12.13.0" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/safe-stable-stringify": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", - "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/secure-json-parse": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-4.1.0.tgz", - "integrity": "sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/sonic-boom": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.1.tgz", - "integrity": "sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==", - "license": "MIT", - "dependencies": { - "atomic-sleep": "^1.0.0" - } - }, - "node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "license": "ISC", - "engines": { - "node": ">= 10.x" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.3.tgz", - "integrity": "sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==", - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/thread-stream": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-4.0.0.tgz", - "integrity": "sha512-4iMVL6HAINXWf1ZKZjIPcz5wYaOdPhtO8ATvZ+Xqp3BTdaqtAwQkNmKORqcIo5YkQqGXq5cwfswDwMqqQNrpJA==", + "version": "22.19.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.21.tgz", + "integrity": "sha512-VMeFBSCKQKmm2swI2kW51SFusDqekC6q9trBCvJ/JliDchFSuoYYKN7yVNjPthP1HKZcx3U1gI/wTcEBjEFKTA==", + "dev": true, "license": "MIT", "dependencies": { - "real-require": "^0.2.0" - }, - "engines": { - "node": ">=20" + "undici-types": "~6.21.0" } }, "node_modules/undici-types": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", - "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, "license": "MIT" }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "node_modules/zod": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", + "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "license": "ISC", - "engines": { - "node": ">=12" + "url": "https://github.com/sponsors/colinhacks" } } } diff --git a/ts/examples/simple-example-ts/package.json b/ts/examples/simple-example-ts/package.json index 80046ca..a5a0a98 100644 --- a/ts/examples/simple-example-ts/package.json +++ b/ts/examples/simple-example-ts/package.json @@ -7,10 +7,14 @@ "type": "module", "main": "index.js", "scripts": { - "build": "tsc -p tsconfig.json", - "dev": "cd ../.. && npm install && npm run build && npm pack && cd examples/simple-example-ts && npm install ../../code0-tech-hercules-0.0.0.tgz && npx tsx index.ts" + "typecheck": "tsc --noEmit", + "build": "vite build .", + "start": "npm run build && node dist/index.js" + }, + "devDependencies": { + "@types/node": "^22.0.0" }, "dependencies": { - "@code0-tech/hercules": "file:../../code0-tech-hercules-0.0.0.tgz" + "zod": "^4.4.3" } } diff --git a/ts/examples/simple-example-ts/src/data_types/emailDataType.ts b/ts/examples/simple-example-ts/src/data_types/emailDataType.ts new file mode 100644 index 0000000..2acb9bf --- /dev/null +++ b/ts/examples/simple-example-ts/src/data_types/emailDataType.ts @@ -0,0 +1,10 @@ +import {Identifier, Name, Schema} from "@code0-tech/hercules"; +import {z} from "zod"; + +const EmailSchema = z.string().regex(/^[^@]+@[^@]+\.[^@]+$/) +export type EmailType = z.infer + +@Identifier("email_address") +@Name({code: "en-US", content: "Email Address"}) +@Schema(EmailSchema) +export class EmailDataType {} diff --git a/ts/examples/simple-example-ts/src/events/userCreatedEvent.ts b/ts/examples/simple-example-ts/src/events/userCreatedEvent.ts new file mode 100644 index 0000000..5ac9074 --- /dev/null +++ b/ts/examples/simple-example-ts/src/events/userCreatedEvent.ts @@ -0,0 +1,8 @@ +import {Editable, Identifier, Name} from "@code0-tech/hercules"; +import {UserCreatedRuntimeEvent} from "./userCreatedRuntimeEvent.ts"; + +@Identifier("user_created_event") +@Name({code: "en-US", content: "On User Created"}) +@Editable(false) +export class UserCreatedEvent extends UserCreatedRuntimeEvent { +} diff --git a/ts/examples/simple-example-ts/src/events/userCreatedRuntimeEvent.ts b/ts/examples/simple-example-ts/src/events/userCreatedRuntimeEvent.ts new file mode 100644 index 0000000..c390f85 --- /dev/null +++ b/ts/examples/simple-example-ts/src/events/userCreatedRuntimeEvent.ts @@ -0,0 +1,12 @@ +import {Identifier, Name, EventSetting, Signature} from "@code0-tech/hercules"; + +@Identifier("user_created") +@Signature("(userId: number): void") +@Name({code: "en-US", content: "User Created"}) +@EventSetting({ + identifier: "FILTER_ROLE", + name: [{code: "en-US", content: "Role Filter"}], + description: [{code: "en-US", content: "Only trigger for users with this role"}], + optional: true, +}) +export class UserCreatedRuntimeEvent {} diff --git a/ts/examples/simple-example-ts/src/functions/fibonacciFunction.ts b/ts/examples/simple-example-ts/src/functions/fibonacciFunction.ts new file mode 100644 index 0000000..145a187 --- /dev/null +++ b/ts/examples/simple-example-ts/src/functions/fibonacciFunction.ts @@ -0,0 +1,12 @@ +import {FunctionParameter, Identifier, Name} from "@code0-tech/hercules"; +import {FibonacciRuntimeFunction} from "./fibonacciRuntimeFunction.js"; + +@Identifier("fibonacci") +@Name({code: "en-US", content: "Compute Fibonacci Number"}) +@FunctionParameter({ + runtimeName: "n", + name: [{code: "en-US", content: "Input Number"}], + description: [{code: "en-US", content: "The position in the Fibonacci sequence"}], + defaultValue: 10, +}) +export class FibonacciFunction extends FibonacciRuntimeFunction {} diff --git a/ts/examples/simple-example-ts/src/functions/fibonacciRuntimeFunction.ts b/ts/examples/simple-example-ts/src/functions/fibonacciRuntimeFunction.ts new file mode 100644 index 0000000..bec8e16 --- /dev/null +++ b/ts/examples/simple-example-ts/src/functions/fibonacciRuntimeFunction.ts @@ -0,0 +1,26 @@ +import { + DisplayMessage, + FunctionContext, FunctionParameter, + Identifier, + Name, + OmitFunctionDefinition, + Signature, +} from "@code0-tech/hercules"; + +@Identifier("fibonacci_runtime") +@Signature("(n: number): number") +@Name({code: "en-US", content: "Fibonacci (Runtime)"}) +@DisplayMessage({code: "en-US", content: "Computes the n-th Fibonacci number"}) +@OmitFunctionDefinition() +@FunctionParameter({runtimeName: "n", name: [{code: "en-US", content: "N"}]}) +export class FibonacciRuntimeFunction { + run(context: FunctionContext, n: number): number { + console.log(`[fibonacci] project=${context.projectId} execution=${context.executionId}`); + return this.fib(n); + } + + private fib(n: number): number { + if (n <= 1) return n; + return this.fib(n - 1) + this.fib(n - 2); + } +} diff --git a/ts/examples/simple-example-ts/src/index.ts b/ts/examples/simple-example-ts/src/index.ts new file mode 100644 index 0000000..ea5ce77 --- /dev/null +++ b/ts/examples/simple-example-ts/src/index.ts @@ -0,0 +1,50 @@ +import {Action, CodeZeroEvent} from "@code0-tech/hercules"; +import {FibonacciRuntimeFunction} from "./functions/fibonacciRuntimeFunction.js"; +import {FibonacciFunction} from "./functions/fibonacciFunction.js"; +import {UserCreatedRuntimeEvent} from "./events/userCreatedRuntimeEvent.js"; +import {UserCreatedEvent} from "./events/userCreatedEvent.js"; +import {EmailDataType} from "./data_types/emailDataType.js"; + +const action = new Action( + process.env.ACTION_ID ?? "example-action", + process.env.VERSION ?? "0.0.0", + process.env.AQUILA_URL ?? "127.0.0.1:8081", + "code0-tech", + "tabler:bolt", + "A simple example action", + [{code: "en-US", content: "Example Action"}], + [{ + identifier: "EXAMPLE_CONFIG", + type: "string", + name: [{code: "en-US", content: "Example Config"}], + }], +); + +// Runtime function (with OmitFunctionDefinition — no auto-generated function def) +action.registerRuntimeFunction(FibonacciRuntimeFunction); + +// Function: named public variant that extends the runtime function +action.registerFunction(FibonacciFunction); + +// Data type: derived from Zod schema +action.registerDataTypeClass(EmailDataType); + +// Runtime flow type: the internal event definition +action.registerRuntimeEventClass(UserCreatedRuntimeEvent); + +// Flow type: the user-facing event linked to the runtime flow type +action.registerEventClass(UserCreatedEvent); + +action.on(CodeZeroEvent.connected, () => { + console.log("Connected to aquila"); +}); + +action.on(CodeZeroEvent.error, (error: Error) => { + console.error("Stream error:", error.message); +}); + + +action.connect(process.env.AUTH_TOKEN ?? "token").catch((err: unknown) => { + console.error("Failed to connect:", err); + process.exit(1); +}); diff --git a/ts/examples/simple-example-ts/tsconfig.json b/ts/examples/simple-example-ts/tsconfig.json index 7193a07..e9dd4f5 100644 --- a/ts/examples/simple-example-ts/tsconfig.json +++ b/ts/examples/simple-example-ts/tsconfig.json @@ -5,15 +5,20 @@ "moduleResolution": "Bundler", "declaration": true, "outDir": "dist", - "strict": false, + "strict": true, "esModuleInterop": true, "skipLibCheck": true, + "allowImportingTsExtensions": true, + "noEmit": true, "baseUrl": ".", "paths": { - "@code0-tech/hercules": ["../../ts"] - } + "@code0-tech/hercules": ["../../src/index.ts"] + }, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "types": ["node", "vite/client"] }, "include": [ - "index.ts" + "src/**/*" ] } \ No newline at end of file diff --git a/ts/examples/simple-example-ts/vite.config.ts b/ts/examples/simple-example-ts/vite.config.ts new file mode 100644 index 0000000..303b4a4 --- /dev/null +++ b/ts/examples/simple-example-ts/vite.config.ts @@ -0,0 +1,18 @@ +import { defineConfig } from 'vite'; +import { resolve } from 'path'; + +export default defineConfig({ + build: { + target: "node18", + ssr: resolve(__dirname, 'src/index.ts'), + rollupOptions: { + external: (id) => + [ + 'fs', + 'path', + 'typescript', + '@code0-tech/hercules' + ].includes(id) || id.startsWith('node:') + } + } +}); \ No newline at end of file diff --git a/ts/package-lock.json b/ts/package-lock.json index 5f6a676..e358d51 100644 --- a/ts/package-lock.json +++ b/ts/package-lock.json @@ -9,14 +9,19 @@ "version": "0.0.0", "license": "ISC", "dependencies": { - "@code0-tech/tucana": "0.0.67", + "@code0-tech/tucana": "0.0.74", "@grpc/grpc-js": "^1.14.3", "@protobuf-ts/grpc-backend": "^2.11.1", "@protobuf-ts/grpc-transport": "^2.11.1", "@protobuf-ts/runtime": "^2.11.1", "@protobuf-ts/runtime-rpc": "^2.11.1", "pino": "^10.3.1", - "pino-pretty": "^13.1.3" + "pino-pretty": "^13.1.3", + "reflect-metadata": "^0.2.2", + "ts-morph": "^28.0.0", + "ts-to-zod": "^5.1.0", + "zod": "^4.4.3", + "zod-to-ts": "^2.1.0" }, "devDependencies": { "@types/node": "^25.0.10", @@ -77,39 +82,37 @@ "node": ">=6.9.0" } }, - "node_modules/@code0-tech/tucana": { - "version": "0.0.67", - "resolved": "https://registry.npmjs.org/@code0-tech/tucana/-/tucana-0.0.67.tgz", - "integrity": "sha512-3V1h3LB+iWeXnt80nsIQo+TeMgVTgbDxvDsAArbffHyU37ii1tsAAV6Ty7wAdkrCSsObyFRpdiIZgzgYVVKfzw==", - "license": "Apache-2.0" - }, - "node_modules/@emnapi/core": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.1.tgz", - "integrity": "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==", - "dev": true, + "node_modules/@clack/core": { + "version": "1.0.0-alpha.4", + "resolved": "https://registry.npmjs.org/@clack/core/-/core-1.0.0-alpha.4.tgz", + "integrity": "sha512-VCtU+vjyKPMSakVrB9q1bOnXN7QW/w4+YQDQCOF59GrzydW+169i0fVx/qzRRXJgt8KGj/pZZ/JxXroFZIDByg==", "license": "MIT", - "optional": true, "dependencies": { - "@emnapi/wasi-threads": "1.2.0", - "tslib": "^2.4.0" + "picocolors": "^1.0.0", + "sisteransi": "^1.0.5" } }, - "node_modules/@emnapi/runtime": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.1.tgz", - "integrity": "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==", - "dev": true, + "node_modules/@clack/prompts": { + "version": "1.0.0-alpha.4", + "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-1.0.0-alpha.4.tgz", + "integrity": "sha512-KnmtDF2xQGoI5AlBme9akHtvCRV0RKAARUXHBQO2tMwnY8B08/4zPWigT7uLK25UPrMCEqnyQPkKRjNdhPbf8g==", "license": "MIT", - "optional": true, "dependencies": { - "tslib": "^2.4.0" + "@clack/core": "1.0.0-alpha.4", + "picocolors": "^1.0.0", + "sisteransi": "^1.0.5" } }, + "node_modules/@code0-tech/tucana": { + "version": "0.0.74", + "resolved": "https://registry.npmjs.org/@code0-tech/tucana/-/tucana-0.0.74.tgz", + "integrity": "sha512-AgCl812Sn/MyY1+cRG0pdN0Uj7z93hDa4E9bclaf9hS5wc1PrlQSutDgePvJFR/VBWoeYQczne7MNP7RDu9NRg==", + "license": "MIT" + }, "node_modules/@emnapi/wasi-threads": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.0.tgz", - "integrity": "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", + "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", "dev": true, "license": "MIT", "optional": true, @@ -564,6 +567,7 @@ "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.3.tgz", "integrity": "sha512-Iq8QQQ/7X3Sac15oB6p0FmUg/klxQvXLeileoqrTRGJYLV+/9tubbr9ipz0GKHjmXVsgFPo/+W+2cA8eNcR+XA==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@grpc/proto-loader": "^0.8.0", "@js-sdsl/ordered-map": "^4.4.2" @@ -640,11 +644,12 @@ } }, "node_modules/@microsoft/api-extractor": { - "version": "7.58.0", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.58.0.tgz", - "integrity": "sha512-XcHlDylX5GblbGbs1eBoexjVyvdJMioTPuBCgCorE2rqijzTYxi6eudXyez3xACRxtH9aDtahoL9fYM4XTvQmg==", + "version": "7.58.1", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.58.1.tgz", + "integrity": "sha512-kF3GFME4lN22O5zbnXk2RP4y/4PDQdps0xKiYTipMYprkwCmmpsWLZt/N2Fkbil540cSLfJX0BW7LkHzgMVUYg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@microsoft/api-extractor-model": "7.33.5", "@microsoft/tsdoc": "~0.16.0", @@ -654,7 +659,7 @@ "@rushstack/terminal": "0.22.4", "@rushstack/ts-command-line": "5.3.4", "diff": "~8.0.2", - "lodash": "~4.17.23", + "lodash": "~4.18.1", "minimatch": "10.2.3", "resolve": "~1.22.1", "semver": "~7.5.4", @@ -708,26 +713,84 @@ } }, "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.1.tgz", - "integrity": "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.2.tgz", + "integrity": "sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw==", "dev": true, "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" }, "funding": { "type": "github", "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@oclif/core": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@oclif/core/-/core-4.11.6.tgz", + "integrity": "sha512-8OTkBkWA0HJz2bSIQI0AoiIeL7ok4bZhUaJNEzfLu+iAn3liAyj4KmXRdXAUZBCjPEfdBTpyxKDAg1l/BDJKVg==", + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.3.2", + "ansis": "^3.17.0", + "clean-stack": "^3.0.1", + "cli-spinners": "^2.9.2", + "debug": "^4.4.3", + "ejs": "^3.1.10", + "get-package-type": "^0.1.0", + "indent-string": "^4.0.0", + "is-wsl": "^2.2.0", + "lilconfig": "^3.1.3", + "minimatch": "^10.2.5", + "semver": "^7.8.1", + "string-width": "^4.2.3", + "supports-color": "^8", + "tinyglobby": "^0.2.16", + "widest-line": "^3.1.0", + "wordwrap": "^1.0.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@oclif/core/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@oclif/core/node_modules/semver": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", + "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/@oxc-project/types": { - "version": "0.122.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.122.0.tgz", - "integrity": "sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA==", + "version": "0.123.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.123.0.tgz", + "integrity": "sha512-YtECP/y8Mj1lSHiUWGSRzy/C6teUKlS87dEfuVKT09LgQbUsBW1rNg+MiJ4buGu3yuADV60gbIvo9/HplA56Ew==", "dev": true, "license": "MIT", "funding": { @@ -846,9 +909,9 @@ "license": "BSD-3-Clause" }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.12.tgz", - "integrity": "sha512-pv1y2Fv0JybcykuiiD3qBOBdz6RteYojRFY1d+b95WVuzx211CRh+ytI/+9iVyWQ6koTh5dawe4S/yRfOFjgaA==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.13.tgz", + "integrity": "sha512-5ZiiecKH2DXAVJTNN13gNMUcCDg4Jy8ZjbXEsPnqa248wgOVeYRX0iqXXD5Jz4bI9BFHgKsI2qmyJynstbmr+g==", "cpu": [ "arm64" ], @@ -863,9 +926,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.12.tgz", - "integrity": "sha512-cFYr6zTG/3PXXF3pUO+umXxt1wkRK/0AYT8lDwuqvRC+LuKYWSAQAQZjCWDQpAH172ZV6ieYrNnFzVVcnSflAg==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.13.tgz", + "integrity": "sha512-tz/v/8G77seu8zAB3A5sK3UFoOl06zcshEzhUO62sAEtrEuW/H1CcyoupOrD+NbQJytYgA4CppXPzlrmp4JZKA==", "cpu": [ "arm64" ], @@ -880,9 +943,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.12.tgz", - "integrity": "sha512-ZCsYknnHzeXYps0lGBz8JrF37GpE9bFVefrlmDrAQhOEi4IOIlcoU1+FwHEtyXGx2VkYAvhu7dyBf75EJQffBw==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.13.tgz", + "integrity": "sha512-8DakphqOz8JrMYWTJmWA+vDJxut6LijZ8Xcdc4flOlAhU7PNVwo2MaWBF9iXjJAPo5rC/IxEFZDhJ3GC7NHvug==", "cpu": [ "x64" ], @@ -897,9 +960,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.12.tgz", - "integrity": "sha512-dMLeprcVsyJsKolRXyoTH3NL6qtsT0Y2xeuEA8WQJquWFXkEC4bcu1rLZZSnZRMtAqwtrF/Ib9Ddtpa/Gkge9Q==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.13.tgz", + "integrity": "sha512-4wBQFfjDuXYN/SVI8inBF3Aa+isq40rc6VMFbk5jcpolUBTe5cYnMsHZ51nFWsx3PVyyNN3vgoESki0Hmr/4BA==", "cpu": [ "x64" ], @@ -914,9 +977,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.12.tgz", - "integrity": "sha512-YqWjAgGC/9M1lz3GR1r1rP79nMgo3mQiiA+Hfo+pvKFK1fAJ1bCi0ZQVh8noOqNacuY1qIcfyVfP6HoyBRZ85Q==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.13.tgz", + "integrity": "sha512-JW/e4yPIXLms+jmnbwwy5LA/LxVwZUWLN8xug+V200wzaVi5TEGIWQlh8o91gWYFxW609euI98OCCemmWGuPrw==", "cpu": [ "arm" ], @@ -931,9 +994,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.12.tgz", - "integrity": "sha512-/I5AS4cIroLpslsmzXfwbe5OmWvSsrFuEw3mwvbQ1kDxJ822hFHIx+vsN/TAzNVyepI/j/GSzrtCIwQPeKCLIg==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.13.tgz", + "integrity": "sha512-ZfKWpXiUymDnavepCaM6KG/uGydJ4l2nBmMxg60Ci4CbeefpqjPWpfaZM7PThOhk2dssqBAcwLc6rAyr0uTdXg==", "cpu": [ "arm64" ], @@ -948,9 +1011,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.12.tgz", - "integrity": "sha512-V6/wZztnBqlx5hJQqNWwFdxIKN0m38p8Jas+VoSfgH54HSj9tKTt1dZvG6JRHcjh6D7TvrJPWFGaY9UBVOaWPw==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.13.tgz", + "integrity": "sha512-bmRg3O6Z0gq9yodKKWCIpnlH051sEfdVwt+6m5UDffAQMUUqU0xjnQqqAUm+Gu7ofAAly9DqiQDtKu2nPDEABA==", "cpu": [ "arm64" ], @@ -965,9 +1028,9 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.12.tgz", - "integrity": "sha512-AP3E9BpcUYliZCxa3w5Kwj9OtEVDYK6sVoUzy4vTOJsjPOgdaJZKFmN4oOlX0Wp0RPV2ETfmIra9x1xuayFB7g==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.13.tgz", + "integrity": "sha512-8Wtnbw4k7pMYN9B/mOEAsQ8HOiq7AZ31Ig4M9BKn2So4xRaFEhtCSa4ZJaOutOWq50zpgR4N5+L/opnlaCx8wQ==", "cpu": [ "ppc64" ], @@ -982,9 +1045,9 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.12.tgz", - "integrity": "sha512-nWwpvUSPkoFmZo0kQazZYOrT7J5DGOJ/+QHHzjvNlooDZED8oH82Yg67HvehPPLAg5fUff7TfWFHQS8IV1n3og==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.13.tgz", + "integrity": "sha512-D/0Nlo8mQuxSMohNJUF2lDXWRsFDsHldfRRgD9bRgktj+EndGPj4DOV37LqDKPYS+osdyhZEH7fTakTAEcW7qg==", "cpu": [ "s390x" ], @@ -999,9 +1062,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.12.tgz", - "integrity": "sha512-RNrafz5bcwRy+O9e6P8Z/OCAJW/A+qtBczIqVYwTs14pf4iV1/+eKEjdOUta93q2TsT/FI0XYDP3TCky38LMAg==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.13.tgz", + "integrity": "sha512-eRrPvat2YaVQcwwKi/JzOP6MKf1WRnOCr+VaI3cTWz3ZoLcP/654z90lVCJ4dAuMEpPdke0n+qyAqXDZdIC4rA==", "cpu": [ "x64" ], @@ -1016,9 +1079,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.12.tgz", - "integrity": "sha512-Jpw/0iwoKWx3LJ2rc1yjFrj+T7iHZn2JDg1Yny1ma0luviFS4mhAIcd1LFNxK3EYu3DHWCps0ydXQ5i/rrJ2ig==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.13.tgz", + "integrity": "sha512-PsdONiFRp8hR8KgVjTWjZ9s7uA3uueWL0t74/cKHfM4dR5zXYv4AjB8BvA+QDToqxAFg4ZkcVEqeu5F7inoz5w==", "cpu": [ "x64" ], @@ -1033,9 +1096,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.12.tgz", - "integrity": "sha512-vRugONE4yMfVn0+7lUKdKvN4D5YusEiPilaoO2sgUWpCvrncvWgPMzK00ZFFJuiPgLwgFNP5eSiUlv2tfc+lpA==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.13.tgz", + "integrity": "sha512-hCNXgC5dI3TVOLrPT++PKFNZ+1EtS0mLQwfXXXSUD/+rGlB65gZDwN/IDuxLpQP4x8RYYHqGomlUXzpO8aVI2w==", "cpu": [ "arm64" ], @@ -1050,9 +1113,9 @@ } }, "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.12.tgz", - "integrity": "sha512-ykGiLr/6kkiHc0XnBfmFJuCjr5ZYKKofkx+chJWDjitX+KsJuAmrzWhwyOMSHzPhzOHOy7u9HlFoa5MoAOJ/Zg==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.13.tgz", + "integrity": "sha512-viLS5C5et8NFtLWw9Sw3M/w4vvnVkbWkO7wSNh3C+7G1+uCkGpr6PcjNDSFcNtmXY/4trjPBqUfcOL+P3sWy/g==", "cpu": [ "wasm32" ], @@ -1060,16 +1123,52 @@ "license": "MIT", "optional": true, "dependencies": { - "@napi-rs/wasm-runtime": "^1.1.1" + "@emnapi/core": "1.9.1", + "@emnapi/runtime": "1.9.1", + "@napi-rs/wasm-runtime": "^1.1.2" }, "engines": { "node": ">=14.0.0" } }, + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.1.tgz", + "integrity": "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.1.tgz", + "integrity": "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.0.tgz", + "integrity": "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.12.tgz", - "integrity": "sha512-5eOND4duWkwx1AzCxadcOrNeighiLwMInEADT0YM7xeEOOFcovWZCq8dadXgcRHSf3Ulh1kFo/qvzoFiCLOL1Q==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.13.tgz", + "integrity": "sha512-Fqa3Tlt1xL4wzmAYxGNFV36Hb+VfPc9PYU+E25DAnswXv3ODDu/yyWjQDbXMo5AGWkQVjLgQExuVu8I/UaZhPQ==", "cpu": [ "arm64" ], @@ -1084,9 +1183,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.12.tgz", - "integrity": "sha512-PyqoipaswDLAZtot351MLhrlrh6lcZPo2LSYE+VDxbVk24LVKAGOuE4hb8xZQmrPAuEtTZW8E6D2zc5EUZX4Lw==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.13.tgz", + "integrity": "sha512-/pLI5kPkGEi44TDlnbio3St/5gUFeN51YWNAk/Gnv6mEQBOahRBh52qVFVBpmrnU01n2yysvBML9Ynu7K4kGAQ==", "cpu": [ "x64" ], @@ -1101,9 +1200,9 @@ } }, "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.12.tgz", - "integrity": "sha512-HHMwmarRKvoFsJorqYlFeFRzXZqCt2ETQlEDOb9aqssrnVBB1/+xgTGtuTrIk5vzLNX1MjMtTf7W9z3tsSbrxw==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.13.tgz", + "integrity": "sha512-3ngTAv6F/Py35BsYbeeLeecvhMKdsKm4AoOETVhAA+Qc8nrA2I0kF7oa93mE9qnIurngOSpMnQ0x2nQY2FPviA==", "dev": true, "license": "MIT" }, @@ -1578,6 +1677,17 @@ "dev": true, "license": "MIT" }, + "node_modules/@ts-morph/common": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.29.0.tgz", + "integrity": "sha512-35oUmphHbJvQ/+UTwFNme/t2p3FoKiGJ5auTjjpNTop2dyREspirjMy82PLSC1pnDJ8ah1GU98hwpVt64YXQsg==", + "license": "MIT", + "dependencies": { + "minimatch": "^10.0.1", + "path-browserify": "^1.0.1", + "tinyglobby": "^0.2.14" + } + }, "node_modules/@tybys/wasm-util": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", @@ -1630,6 +1740,18 @@ "undici-types": "~7.18.0" } }, + "node_modules/@typescript/vfs": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@typescript/vfs/-/vfs-1.6.4.tgz", + "integrity": "sha512-PJFXFS4ZJKiJ9Qiuix6Dz/OwEIqHD7Dme1UwZhTK11vR+5dqW2ACbdndWQexBzCx+CPuMe5WBYQWCsFyGlQLlQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3" + }, + "peerDependencies": { + "typescript": "*" + } + }, "node_modules/@vitest/expect": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.2.tgz", @@ -1950,6 +2072,21 @@ "dev": true, "license": "MIT" }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -1974,6 +2111,15 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/ansis": { + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-3.17.0.tgz", + "integrity": "sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==", + "license": "ISC", + "engines": { + "node": ">=14" + } + }, "node_modules/any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", @@ -2001,6 +2147,12 @@ "node": ">=12" } }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" + }, "node_modules/atomic-sleep": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", @@ -2014,7 +2166,6 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true, "license": "MIT", "engines": { "node": "18 || 20 || >=22" @@ -2024,7 +2175,6 @@ "version": "5.0.5", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" @@ -2073,7 +2223,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, "license": "MIT", "dependencies": { "readdirp": "^4.0.1" @@ -2085,6 +2234,107 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/clean-stack": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-3.0.1.tgz", + "integrity": "sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.2.0.tgz", + "integrity": "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==", + "license": "MIT", + "dependencies": { + "slice-ansi": "^8.0.0", + "string-width": "^8.2.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.1.tgz", + "integrity": "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==", + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -2099,6 +2349,12 @@ "node": ">=12" } }, + "node_modules/code-block-writer": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.3.tgz", + "integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==", + "license": "MIT" + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2184,7 +2440,6 @@ "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -2218,6 +2473,21 @@ "node": ">=0.3.1" } }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -2246,6 +2516,18 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/es-module-lexer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", @@ -2260,6 +2542,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -2304,6 +2587,18 @@ "node": ">=6" } }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/estree-walker": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", @@ -2314,6 +2609,12 @@ "@types/estree": "^1.0.0" } }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" + }, "node_modules/expect-type": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", @@ -2371,7 +2672,6 @@ "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, "license": "MIT", "engines": { "node": ">=12.0.0" @@ -2385,6 +2685,42 @@ } } }, + "node_modules/filelist": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.6.tgz", + "integrity": "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==", + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", + "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/fix-dts-default-cjs-exports": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/fix-dts-default-cjs-exports/-/fix-dts-default-cjs-exports-1.0.1.tgz", @@ -2446,6 +2782,27 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-east-asian-width": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -2457,7 +2814,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -2502,7 +2858,16 @@ "node": ">=8" } }, - "node_modules/is-core-module": { + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { "version": "2.16.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", @@ -2518,6 +2883,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -2527,6 +2907,35 @@ "node": ">=8" } }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jake": { + "version": "10.9.4", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", + "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.6", + "filelist": "^1.0.4", + "picocolors": "^1.1.1" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/jju": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", @@ -2835,7 +3244,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", - "dev": true, "license": "MIT", "engines": { "node": ">=14" @@ -2851,6 +3259,102 @@ "dev": true, "license": "MIT" }, + "node_modules/listr2": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.5.tgz", + "integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==", + "license": "MIT", + "dependencies": { + "cli-truncate": "^5.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT" + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/load-tsconfig": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", @@ -2899,9 +3403,9 @@ } }, "node_modules/lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "dev": true, "license": "MIT" }, @@ -2911,6 +3415,150 @@ "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", "license": "MIT" }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT" + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/long": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", @@ -2940,11 +3588,22 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimatch": { "version": "10.2.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.3.tgz", "integrity": "sha512-Rwi3pnapEqirPSbWbrZaa6N3nmqq4Xer/2XooiOKyV3q12ML06f7MOuc5DVH8ONZIFhwIYQ3yzPH4nt7iWHaTg==", - "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "brace-expansion": "^5.0.2" @@ -2982,7 +3641,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, "license": "MIT" }, "node_modules/muggle-string": { @@ -3062,11 +3720,25 @@ "wrappy": "1" } }, + "node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/path-browserify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true, "license": "MIT" }, "node_modules/path-parse": { @@ -3087,14 +3759,12 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, "license": "ISC" }, "node_modules/picomatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -3218,6 +3888,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -3347,7 +4018,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 14.18.0" @@ -3366,6 +4036,12 @@ "node": ">= 12.13.0" } }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "license": "Apache-2.0" + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -3416,15 +4092,37 @@ "node": ">=8" } }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "license": "MIT" + }, "node_modules/rolldown": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.12.tgz", - "integrity": "sha512-yP4USLIMYrwpPHEFB5JGH1uxhcslv6/hL0OyvTuY+3qlOSJvZ7ntYnoWpehBxufkgN0cvXxppuTu5hHa/zPh+A==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.13.tgz", + "integrity": "sha512-bvVj8YJmf0rq4pSFmH7laLa6pYrhghv3PRzrCdRAr23g66zOKVJ4wkvFtgohtPLWmthgg8/rkaqRHrpUEh0Zbw==", "dev": true, "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.122.0", - "@rolldown/pluginutils": "1.0.0-rc.12" + "@oxc-project/types": "=0.123.0", + "@rolldown/pluginutils": "1.0.0-rc.13" }, "bin": { "rolldown": "bin/cli.mjs" @@ -3433,21 +4131,21 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.0.0-rc.12", - "@rolldown/binding-darwin-arm64": "1.0.0-rc.12", - "@rolldown/binding-darwin-x64": "1.0.0-rc.12", - "@rolldown/binding-freebsd-x64": "1.0.0-rc.12", - "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.12", - "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.12", - "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.12", - "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.12", - "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.12", - "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.12", - "@rolldown/binding-linux-x64-musl": "1.0.0-rc.12", - "@rolldown/binding-openharmony-arm64": "1.0.0-rc.12", - "@rolldown/binding-wasm32-wasi": "1.0.0-rc.12", - "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.12", - "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.12" + "@rolldown/binding-android-arm64": "1.0.0-rc.13", + "@rolldown/binding-darwin-arm64": "1.0.0-rc.13", + "@rolldown/binding-darwin-x64": "1.0.0-rc.13", + "@rolldown/binding-freebsd-x64": "1.0.0-rc.13", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.13", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.13", + "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.13", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.13", + "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.13", + "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.13", + "@rolldown/binding-linux-x64-musl": "1.0.0-rc.13", + "@rolldown/binding-openharmony-arm64": "1.0.0-rc.13", + "@rolldown/binding-wasm32-wasi": "1.0.0-rc.13", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.13", + "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.13" } }, "node_modules/rollup": { @@ -3543,6 +4241,79 @@ "dev": true, "license": "ISC" }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/slice-ansi": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-8.0.0.tgz", + "integrity": "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.3", + "is-fullwidth-code-point": "^5.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/sonic-boom": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.1.tgz", @@ -3678,7 +4449,6 @@ "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -3703,6 +4473,197 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/text-camel-case": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/text-camel-case/-/text-camel-case-1.2.11.tgz", + "integrity": "sha512-2ZsM/gOlB1tyza+8lGLvs6gtPuZ9qEYuKPa+gwo38m65wkY4k323SK4hT7ku8r5wIKyspUYIWSk1aB9/Jjxr7A==", + "license": "MIT", + "dependencies": { + "text-pascal-case": "^1.2.11" + } + }, + "node_modules/text-capital-case": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/text-capital-case/-/text-capital-case-1.2.11.tgz", + "integrity": "sha512-30A7B7+VUvevEmPE0xWK1Z2z0ncl/JTjSUBLfjpoXrkwuPpmNTVbjHShRTN3cX9GIuZn/P3jvR+TO9JiTZcl8A==", + "license": "MIT", + "dependencies": { + "text-no-case": "^1.2.11", + "text-upper-case-first": "^1.2.11" + } + }, + "node_modules/text-case": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/text-case/-/text-case-1.2.11.tgz", + "integrity": "sha512-LbdWNQeuXWbfav+pxBxvaefkziffMYeSA53BHp52cgJa9rjiC0dkjum9AKrH8iQWoQJ4InGPSGexLeerGFaZ1Q==", + "license": "MIT", + "dependencies": { + "text-camel-case": "^1.2.11", + "text-capital-case": "^1.2.11", + "text-constant-case": "^1.2.11", + "text-dot-case": "^1.2.11", + "text-header-case": "^1.2.11", + "text-is-lower-case": "^1.2.11", + "text-is-upper-case": "^1.2.11", + "text-kebab-case": "^1.2.11", + "text-lower-case": "^1.2.11", + "text-lower-case-first": "^1.2.11", + "text-no-case": "^1.2.11", + "text-param-case": "^1.2.11", + "text-pascal-case": "^1.2.11", + "text-path-case": "^1.2.11", + "text-sentence-case": "^1.2.11", + "text-snake-case": "^1.2.11", + "text-swap-case": "^1.2.11", + "text-title-case": "^1.2.11", + "text-upper-case": "^1.2.11", + "text-upper-case-first": "^1.2.11" + } + }, + "node_modules/text-constant-case": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/text-constant-case/-/text-constant-case-1.2.11.tgz", + "integrity": "sha512-XnTBILsa7UpMWncUCchqIybZlg15FUcrlyNaWIJ8ybPy54qcoN513EXFswueyizuAgyJFXPCwwSFbSji6kw/Uw==", + "license": "MIT", + "dependencies": { + "text-no-case": "^1.2.11", + "text-upper-case": "^1.2.11" + } + }, + "node_modules/text-dot-case": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/text-dot-case/-/text-dot-case-1.2.11.tgz", + "integrity": "sha512-7SLKiT45KZO0qad0+p+GvC0+F+6pZ851HJcTcBJiSF88HsK/e1qErlGLtVBT6hkTHIaAj48WfSyQr4lZRv1xJQ==", + "license": "MIT", + "dependencies": { + "text-no-case": "^1.2.11" + } + }, + "node_modules/text-header-case": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/text-header-case/-/text-header-case-1.2.11.tgz", + "integrity": "sha512-7OBHd2g7X+aH6rXMC3cANFh6yvhXjXkyumw2NaRwJRIk343pP2e1SQCTCfowPDmmi8wkZVqz1fdWNq5LwvcBOQ==", + "license": "MIT", + "dependencies": { + "text-capital-case": "^1.2.11" + } + }, + "node_modules/text-is-lower-case": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/text-is-lower-case/-/text-is-lower-case-1.2.11.tgz", + "integrity": "sha512-dBqPAkNmX7eTM7ZbS3D/UBCQ5i9EXt5tujF2wIGGbZ1+aN8bY7Qda4mDpxgd6Hbzf/z10uQWRNzupl99wFQ8CQ==", + "license": "MIT" + }, + "node_modules/text-is-upper-case": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/text-is-upper-case/-/text-is-upper-case-1.2.11.tgz", + "integrity": "sha512-MZeUIYEYfKZ2FSeg0vnHCH4mHXLgGzes+iz2K+4BYnhnkEa2svKA1nNjQAqTUiVNHOPqPCuzmUr1LsyQZ73uyA==", + "license": "MIT" + }, + "node_modules/text-kebab-case": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/text-kebab-case/-/text-kebab-case-1.2.11.tgz", + "integrity": "sha512-RIg9iN6VwH+JrX9dFdm1nd1efPGR9LjNc0CiQz496sQETeKGkDEzxES/ZzxbkerrAL2DFEMGdLXckzDz1OEDBQ==", + "license": "MIT", + "dependencies": { + "text-no-case": "^1.2.11" + } + }, + "node_modules/text-lower-case": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/text-lower-case/-/text-lower-case-1.2.11.tgz", + "integrity": "sha512-txTy6y0y8M23Lhf0mk8WcvXTqlf4OQ3AGnDsRB6o3uMNfIa0CJDol2s1PdKNa63rt5B2277zkZCCn6Xeq//big==", + "license": "MIT" + }, + "node_modules/text-lower-case-first": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/text-lower-case-first/-/text-lower-case-first-1.2.11.tgz", + "integrity": "sha512-QR483XLyuyIpq8tKu1ds3Q1jfsgfaa/p9rtoQKHe6Rv5ah9ic/SUzTGN0MQ7UIS9APADd8SUPn5TTh1Z2/ACyg==", + "license": "MIT" + }, + "node_modules/text-no-case": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/text-no-case/-/text-no-case-1.2.11.tgz", + "integrity": "sha512-wazS7FEq0Ct3aJzeE8MEMcSs0eW4+/X/fwdotv/rG66bLS+g1T0pa0gUsbBGjjLFs191AIXVIry+bYE0uaaBBQ==", + "license": "MIT", + "dependencies": { + "text-lower-case": "^1.2.11" + } + }, + "node_modules/text-param-case": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/text-param-case/-/text-param-case-1.2.11.tgz", + "integrity": "sha512-3EMMAMLSz/mJXOnATNnrS+dZAvghpq09VhOVYDOkUnbm5zlYc6iU5AZOKVDpiAVVllQ9P1h5IKVZzsEYrdIRGw==", + "license": "MIT", + "dependencies": { + "text-dot-case": "^1.2.11" + } + }, + "node_modules/text-pascal-case": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/text-pascal-case/-/text-pascal-case-1.2.11.tgz", + "integrity": "sha512-BNhQ1O/g/Q4dH5gPyLIJLDLDknl2dipBwV629ScsiZCKJaCLGXYhTXp23rp9Htg3O5OSSsiU3mqDKq+pBmwTSw==", + "license": "MIT", + "dependencies": { + "text-no-case": "^1.2.11" + } + }, + "node_modules/text-path-case": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/text-path-case/-/text-path-case-1.2.11.tgz", + "integrity": "sha512-FsJU4BmMdtLtmnBK/XRJPqTwLF8yFiTEClHjxlQjSAG5Xt9R4p6D1WNaM1CI2dG5Lr4rsFM4jiVC620m0AsRbw==", + "license": "MIT", + "dependencies": { + "text-dot-case": "^1.2.11" + } + }, + "node_modules/text-sentence-case": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/text-sentence-case/-/text-sentence-case-1.2.11.tgz", + "integrity": "sha512-ApiVsvdLy+Wb8x7mZRVuoy8VO12jJ22G2djVM3ZZbUhXVIkqGgHxmiXRwdhRPoWGojK9n53m7jviJgBVNdRn+g==", + "license": "MIT", + "dependencies": { + "text-no-case": "^1.2.11", + "text-upper-case-first": "^1.2.11" + } + }, + "node_modules/text-snake-case": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/text-snake-case/-/text-snake-case-1.2.11.tgz", + "integrity": "sha512-NOEQvjyyVABB41SS8dUx423Y6hWS+Z4TrAAJg1xzCkOD3q9y0JtdJjCvCA1FWI8oDu+HiIOp/N446uDM8j54XQ==", + "license": "MIT", + "dependencies": { + "text-dot-case": "^1.2.11" + } + }, + "node_modules/text-swap-case": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/text-swap-case/-/text-swap-case-1.2.11.tgz", + "integrity": "sha512-PBmC5xvZdDZ4suikydpeXH0s4JV2XHelMj9/OEXEbA3oLpdV2A+B4BspVDWVw7C2Gi5eCareqk/7EE8I1/WwgQ==", + "license": "MIT" + }, + "node_modules/text-title-case": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/text-title-case/-/text-title-case-1.2.11.tgz", + "integrity": "sha512-V1GZy0XlqdkYUQm0tqm1jqtYlXJqFVMreBCTUReOaz8d/JbozTSpZrcakIeV8+1bN7LsvfhPFhA5zREiax6YIA==", + "license": "MIT", + "dependencies": { + "text-no-case": "^1.2.11", + "text-upper-case-first": "^1.2.11" + } + }, + "node_modules/text-upper-case": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/text-upper-case/-/text-upper-case-1.2.11.tgz", + "integrity": "sha512-BfTL7yB1YIRlVGNdZUvno013hOq2cRs07fDR2ApppOXRDuKrEmsLDEY82xXlDzQHELp0jexqkI+NeyPIl6MtMw==", + "license": "MIT" + }, + "node_modules/text-upper-case-first": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/text-upper-case-first/-/text-upper-case-first-1.2.11.tgz", + "integrity": "sha512-vgfbwKo8TEJbRsapR9LWWvIJRnv8u9aXVa6cyYOAQQmurCx54Cnt59x5fKdiq+hFaBJ51AbzCgMpbP3p65/pHQ==", + "license": "MIT" + }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -3753,14 +4714,13 @@ "license": "MIT" }, "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "dev": true, + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", "license": "MIT", "dependencies": { "fdir": "^6.5.0", - "picomatch": "^4.0.3" + "picomatch": "^4.0.4" }, "engines": { "node": ">=12.0.0" @@ -3796,13 +4756,43 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/ts-morph": { + "version": "28.0.0", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-28.0.0.tgz", + "integrity": "sha512-Wp3tnZ2bzwxyTZMtgWVzXDfm7lB1Drz+y9DmmYH/L702PQhPyVrp3pkou3yIz4qjS14GY9kcpmLiOOMvl8oG1g==", + "license": "MIT", + "dependencies": { + "@ts-morph/common": "~0.29.0", + "code-block-writer": "^13.0.3" + } + }, + "node_modules/ts-to-zod": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ts-to-zod/-/ts-to-zod-5.1.0.tgz", + "integrity": "sha512-giqqlvRHunlJqG9tBL/KAO3wWIVZGF//mZiWLKm/fdQnKnz4EN2mtiK5cugN9slytBkdMEXQIaLvMzIScbhhFw==", + "license": "MIT", + "dependencies": { + "@clack/prompts": "1.0.0-alpha.4", + "@oclif/core": "^4.5.4", + "@typescript/vfs": "^1.5.0", + "chokidar": "^4.0.3", + "listr2": "^9.0.4", + "slash": "^5.1.0", + "text-case": "^1.2.4", + "tslib": "^2.3.1", + "tsutils": "^3.21.0", + "typescript": "^5.2.2", + "zod": "^4.1.5" + }, + "bin": { + "ts-to-zod": "bin/run" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, - "license": "0BSD", - "optional": true + "license": "0BSD" }, "node_modules/tsup": { "version": "8.5.1", @@ -3857,12 +4847,45 @@ } } }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "license": "MIT", + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -3895,16 +4918,17 @@ } }, "node_modules/vite": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.3.tgz", - "integrity": "sha512-B9ifbFudT1TFhfltfaIPgjo9Z3mDynBTJSUYxTjOQruf/zHH+ezCQKcoqO+h7a9Pw9Nm/OtlXAiGT1axBgwqrQ==", + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.7.tgz", + "integrity": "sha512-P1PbweD+2/udplnThz3btF4cf6AgPky7kk23RtHUkJIU5BIxwPprhRGmOAHs6FTI7UiGbTNrgNP6jSYD6JaRnw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.8", - "rolldown": "1.0.0-rc.12", + "rolldown": "1.0.0-rc.13", "tinyglobby": "^0.2.15" }, "bin": { @@ -3922,7 +4946,7 @@ "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", - "esbuild": "^0.27.0", + "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", @@ -4115,6 +5139,24 @@ "node": ">=8" } }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "license": "MIT", + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "license": "MIT" + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -4180,6 +5222,26 @@ "engines": { "node": ">=12" } + }, + "node_modules/zod": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", + "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-ts": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/zod-to-ts/-/zod-to-ts-2.1.0.tgz", + "integrity": "sha512-jZP1GokTqR99FLmtGU+B9acjD9u/R++b++Vxe1sWpBQDd82/9/j5LyLZZ7/Oy3h2nxcz5NihikgX4D0hhdu3+g==", + "license": "MIT", + "peerDependencies": { + "typescript": "^5 || ^6", + "zod": "^3.25.0 || ^4.0.0" + } } } } diff --git a/ts/package.json b/ts/package.json index 251652a..61ba0ca 100644 --- a/ts/package.json +++ b/ts/package.json @@ -23,21 +23,27 @@ "build": "vite build", "clean": "rm -rf dist", "typecheck": "tsc --noEmit", - "test": "vitest run" + "test": "vitest run", + "build:definitions": "npx tsx scripts/build-definitions.ts" }, "keywords": [], "author": "", "license": "ISC", "type": "module", "dependencies": { - "@code0-tech/tucana": "0.0.67", + "@code0-tech/tucana": "0.0.74", "@grpc/grpc-js": "^1.14.3", "@protobuf-ts/grpc-backend": "^2.11.1", "@protobuf-ts/grpc-transport": "^2.11.1", "@protobuf-ts/runtime": "^2.11.1", "@protobuf-ts/runtime-rpc": "^2.11.1", "pino": "^10.3.1", - "pino-pretty": "^13.1.3" + "pino-pretty": "^13.1.3", + "reflect-metadata": "^0.2.2", + "ts-morph": "^28.0.0", + "ts-to-zod": "^5.1.0", + "zod": "^4.4.3", + "zod-to-ts": "^2.1.0" }, "devDependencies": { "@types/node": "^25.0.10", diff --git a/ts/scripts/build-definitions.ts b/ts/scripts/build-definitions.ts new file mode 100644 index 0000000..e611999 --- /dev/null +++ b/ts/scripts/build-definitions.ts @@ -0,0 +1,382 @@ +import * as fs from "node:fs"; +import * as path from "node:path"; +import * as os from "node:os"; +import {execSync} from "node:child_process"; +import {generate} from "ts-to-zod"; +import {Project} from "ts-morph"; + +const args = process.argv.slice(2); +const versionIndex = args.indexOf("--version"); +if (versionIndex === -1 || !args[versionIndex + 1]) { + console.error("Usage: npm run build:definitions -- --version "); + process.exit(1); +} +const version = args[versionIndex + 1]; + +const REPO = "code0-tech/code0-definition"; +const OUTPUT_DIR = path.resolve("src/definitions"); + +// ── Helpers ─────────────────────────────────────────────────────────────────── + +function toPascalCase(str: string): string { + return str + .replace(/::/g, "_") + .split(/[_-]/) + .map(p => p.charAt(0).toUpperCase() + p.slice(1).toLowerCase()) + .join(""); +} + +function fileNameToClassName(file: string): string { + return toPascalCase(path.basename(file, ".proto.json")); +} + +function toSchemaName(identifier: string): string { + // HTTP_METHOD → httpMethodSchema + return identifier.toLowerCase().replace(/_([a-z])/g, (_, c) => c.toUpperCase()) + "Schema"; +} + +function srcRelativePath(relModule: string, ...segments: string[]): string { + const depth = relModule.split(path.sep).filter(Boolean).length + 1; + return "../".repeat(depth) + segments.join("/"); +} + +type Translation = { code: string; content: string }; + +function renderTranslations(decorator: string, arr: Translation[]): string[] { + if (!arr?.length) return []; + return [ + `@${decorator}(`, + ...arr.map(t => ` {code: "${t.code}", content: ${JSON.stringify(t.content)}},`), + `)`, + ]; +} + +function renderTranslationsInline(arr: Translation[]): string { + return arr.map(t => `{code: "${t.code}", content: ${JSON.stringify(t.content)}}`).join(", "); +} + +// ── Data type definitions ───────────────────────────────────────────────────── + +interface DataTypeDef { + identifier: string; + type: string; + genericKeys: string[]; + relModule: string; + className: string; + fileName: string; +} + +function buildCombinedSource(defs: DataTypeDef[]): string { + return defs.map(({identifier, type, genericKeys}) => { + let resolved = type; + if (/\[.*in keyof/.test(resolved)) { + // Identity mapped type (e.g. { [K in keyof T]: T[K] }) → Record + resolved = "Record"; + } else { + for (const key of genericKeys) { + resolved = resolved.replace(new RegExp(`\\b${key}\\b`, "g"), "unknown"); + } + } + return `export type ${identifier} = ${resolved};`; + }).join("\n"); +} + +function relativeImport(fromRelModule: string, toDef: DataTypeDef, toFile: string): string { + const from = fromRelModule.split(path.sep).filter(Boolean); + const to = toDef.relModule.split(path.sep).filter(Boolean); + let common = 0; + while (common < from.length && common < to.length && from[common] === to[common]) + common++; + const up = "../".repeat(from.length - common); + const down = [...to.slice(common), toFile].join("/"); + return up ? up + down : "./" + down; +} + +// ── Meta-decorator helpers ──────────────────────────────────────────────────── + +function collectMetaDecorators(json: Record): string[] { + return [ + "Identifier", + ...(json.signature ? ["Signature"] : []), + ...(Array.isArray(json.name) && json.name.length ? ["Name"] : []), + ...(Array.isArray(json.description) && json.description.length ? ["Description"] : []), + ...(Array.isArray(json.documentation) && json.documentation.length ? ["Documentation"] : []), + ...(Array.isArray(json.displayMessage) && json.displayMessage.length ? ["DisplayMessage"] : []), + ...(Array.isArray(json.alias) && json.alias.length ? ["Alias"] : []), + ...(json.displayIcon ? ["DisplayIcon"] : []), + ]; +} + +function buildMetaDecorators(json: Record, identifierKey: string): string[] { + return [ + `@Identifier(${JSON.stringify(json[identifierKey])})`, + ...(json.signature + ? [`@Signature(${JSON.stringify(json.signature)})`] + : []), + ...(Array.isArray(json.name) && json.name.length + ? renderTranslations("Name", json.name as Translation[]) + : []), + ...(Array.isArray(json.description) && json.description.length + ? renderTranslations("Description", json.description as Translation[]) + : []), + ...(Array.isArray(json.documentation) && json.documentation.length + ? renderTranslations("Documentation", json.documentation as Translation[]) + : []), + ...(Array.isArray(json.displayMessage) && json.displayMessage.length + ? renderTranslations("DisplayMessage", json.displayMessage as Translation[]) + : []), + ...(Array.isArray(json.alias) && json.alias.length + ? renderTranslations("Alias", json.alias as Translation[]) + : []), + ...(json.displayIcon + ? [`@DisplayIcon(${JSON.stringify(json.displayIcon)})`] + : []), + ]; +} + +// ── Generators ──────────────────────────────────────────────────────────────── + +function buildSettingDecorators(settings: any[]): string[] { + return settings.flatMap(s => { + const props = [ + `identifier: ${JSON.stringify(s.identifier)},`, + ...(s.unique && s.unique !== "NONE" ? [`unique: ${JSON.stringify(s.unique)} as any,`] : []), + ...(Array.isArray(s.name) && s.name.length ? [`name: [${renderTranslationsInline(s.name)}],`] : []), + ...(Array.isArray(s.description) && s.description.length ? [`description: [${renderTranslationsInline(s.description)}],`] : []), + ...(s.optional ? [`optional: true,`] : []), + ...(s.hidden ? [`hidden: true,`] : []), + ]; + return [`@RuntimeEventSetting({`, ...props.map(p => ` ${p}`), `})`]; + }); +} + +function buildParameterDecorators(params: any[]): string[] { + return params.flatMap(p => { + const props = [ + `runtimeName: ${JSON.stringify(p.runtimeName)},`, + ...(Array.isArray(p.name) && p.name.length ? [`name: [${renderTranslationsInline(p.name)}],`] : []), + ...(Array.isArray(p.description) && p.description.length ? [`description: [${renderTranslationsInline(p.description)}],`] : []), + ...(p.optional ? [`optional: true,`] : []), + ...(p.hidden ? [`hidden: true,`] : []), + ]; + return [`@RuntimeParameter({`, ...props.map(p => ` ${p}`), `})`]; + }); +} + +function generateRuntimeFlowType(json: Record, className: string, relModule: string): string { + const src = (seg: string) => srcRelativePath(relModule, seg); + const linkedIds = json.linkedDataTypeIdentifiers as string[] | undefined; + const settings = json.runtimeSettings as any[] | undefined; + const metaDecorators = collectMetaDecorators(json); + + const imports = [ + `import {RuntimeEventRunnable} from "${src("models/runtime_event.model")}";`, + `import {${metaDecorators.join(", ")}} from "${src("decorators/meta")}";`, + ...(linkedIds?.length ? [`import {LinkedDataTypeIdentifiers} from "${src("decorators/function")}";`] : []), + ...(settings?.length ? [`import {RuntimeEventSetting} from "${src("decorators/runtime-event")}";`] : []), + ]; + + const decorators = [ + ...buildMetaDecorators(json, "identifier"), + ...(linkedIds?.length ? [`@LinkedDataTypeIdentifiers(${linkedIds.map(s => JSON.stringify(s)).join(", ")})`] : []), + ...buildSettingDecorators(settings ?? []), + ]; + + return [ + ...imports, + "", + ...decorators, + `export class ${className} implements RuntimeEventRunnable {}`, + "", + ].join("\n"); +} + +function generateRuntimeFunction(json: Record, className: string, relModule: string): string { + const src = (seg: string) => srcRelativePath(relModule, seg); + const linkedIds = json.linkedDataTypeIdentifiers as string[] | undefined; + const params = json.runtimeParameterDefinitions as any[] | undefined; + const metaDecorators = collectMetaDecorators(json); + const funcDecorators = [ + "OmitFunctionDefinition", + ...(json.throwsError ? ["ThrowsError"] : []), + ...(params?.length ? ["RuntimeParameter"] : []), + ...(linkedIds?.length ? ["LinkedDataTypeIdentifiers"] : []), + ]; + + const imports = [ + `import {RuntimeFunctionRunnable} from "${src("models/runtime_function.model")}";`, + `import {${metaDecorators.join(", ")}} from "${src("decorators/meta")}";`, + `import {${funcDecorators.join(", ")}} from "${src("decorators/function")}";`, + `import type {PlainValue} from "@code0-tech/tucana/helpers";`, + ]; + + const decorators = [ + `@OmitFunctionDefinition()`, + ...buildMetaDecorators(json, "runtimeName"), + ...(json.throwsError ? [`@ThrowsError()`] : []), + ...(linkedIds?.length ? [`@LinkedDataTypeIdentifiers(${linkedIds.map(s => JSON.stringify(s)).join(", ")})`] : []), + ...buildParameterDecorators(params ?? []), + ]; + + return [ + ...imports, + "", + ...decorators, + `export class ${className} implements RuntimeFunctionRunnable {`, + ` run(..._args: (PlainValue | undefined)[]): Promise | PlainValue {`, + ` throw new Error(\`${className}.run() is not implemented\`);`, + ` }`, + `}`, + "", + ].join("\n"); +} + +// ── Directory walker ────────────────────────────────────────────────────────── + +type DefHandler = ( + json: Record, + className: string, + fileName: string, + relModule: string, + typeFolder: string, +) => void; + +function walkDefs(dir: string, relModule: string, handler: DefHandler): void { + for (const entry of fs.readdirSync(dir, {withFileTypes: true})) { + const fullPath = path.join(dir, entry.name); + if (entry.isDirectory()) { + walkDefs(fullPath, path.join(relModule, entry.name), handler); + continue; + } + if (!entry.name.endsWith(".proto.json")) continue; + const json = JSON.parse(fs.readFileSync(fullPath, "utf-8")) as Record; + const typeFolder = relModule.split(path.sep).at(-1) ?? ""; + const className = fileNameToClassName(entry.name); + const fileName = path.basename(entry.name, ".proto.json"); + handler(json, className, fileName, relModule, typeFolder); + } +} + +// ── Main ────────────────────────────────────────────────────────────────────── + +async function main() { + const url = `https://github.com/${REPO}/releases/download/${version}/definitions.zip`; + console.log(`Downloading ${url}...`); + + const response = await fetch(url); + if (!response.ok) throw new Error(`Download failed: ${response.status} ${response.statusText}`); + + const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "hercules-definitions-")); + const zipPath = path.join(tmpDir, "definitions.zip"); + const extractDir = path.join(tmpDir, "extracted"); + + fs.writeFileSync(zipPath, Buffer.from(await response.arrayBuffer())); + fs.mkdirSync(extractDir, {recursive: true}); + execSync(`unzip -q "${zipPath}" -d "${extractDir}"`); + + const defsDir = path.join(extractDir, "definitions"); + + // ── Collect all data type definitions ───────────────────────────────────── + const dataTypeDefs: DataTypeDef[] = []; + walkDefs(defsDir, "", (json, className, fileName, relModule, typeFolder) => { + if (typeFolder !== "data_types" || !json.identifier || !json.type) return; + dataTypeDefs.push({ + identifier: json.identifier as string, + type: json.type as string, + genericKeys: (json.genericKeys as string[]) ?? [], + relModule, + className, + fileName, + }); + }); + + // ── Generate all schemas via ts-to-zod ──────────────────────────────────── + const combinedSource = buildCombinedSource(dataTypeDefs); + const {getZodSchemasFile, errors} = generate({sourceText: combinedSource}); + if (errors.length) console.warn("ts-to-zod warnings:", errors); + const schemasSource = getZodSchemasFile("schemas"); + + // ── Parse ts-to-zod output with ts-morph ────────────────────────────────── + const morphProject = new Project({useInMemoryFileSystem: true}); + const sf = morphProject.createSourceFile("schemas", schemasSource); + + const schemaBodyMap = new Map(); + for (const stmt of sf.getVariableStatements()) { + for (const decl of stmt.getDeclarations()) { + const init = decl.getInitializer()?.getText(); + if (init) schemaBodyMap.set(decl.getName(), init); + } + } + + const schemaToFile = new Map(); + for (const def of dataTypeDefs) { + schemaToFile.set(toSchemaName(def.identifier), def); + } + + // ── Write output ────────────────────────────────────────────────────────── + fs.rmSync(OUTPUT_DIR, {recursive: true, force: true}); + fs.mkdirSync(OUTPUT_DIR, {recursive: true}); + + let count = 0; + const allSchemaNames = new Set(schemaBodyMap.keys()); + const generatedFiles: string[] = []; + + for (const def of dataTypeDefs) { + const schemaName = toSchemaName(def.identifier); + const body = schemaBodyMap.get(schemaName); + if (!body) continue; + + const refs = [ + ...new Set( + [...body.matchAll(/\b(\w+Schema)\b/g)] + .map(m => m[1]) + .filter(n => n !== schemaName && allSchemaNames.has(n)) + ), + ]; + const typeParams = def.genericKeys.length > 0 + ? `<${def.genericKeys.map(k => `${k} = unknown`).join(", ")}>` + : ""; + + const lines = [ + `import {z} from "zod";`, + ...refs.flatMap(ref => { + const refDef = schemaToFile.get(ref); + return refDef ? [`import {${ref}} from "${relativeImport(def.relModule, refDef, refDef.fileName)}";`] : []; + }), + ``, + `export const ${schemaName} = ${body};`, + `export type ${def.className}${typeParams} = z.infer;`, + ``, + ]; + + const outDir = path.join(OUTPUT_DIR, def.relModule); + fs.mkdirSync(outDir, {recursive: true}); + fs.writeFileSync(path.join(outDir, `${def.fileName}.ts`), lines.join("\n")); + generatedFiles.push([def.relModule, def.fileName].filter(Boolean).join("/")); + count++; + } + + walkDefs(defsDir, "", (json, className, fileName, relModule, typeFolder) => { + let content: string | null = null; + if (typeFolder === "runtime_flow_types") content = generateRuntimeFlowType(json, className, relModule); + else if (typeFolder === "runtime_functions") content = generateRuntimeFunction(json, className, relModule); + if (content === null) return; + + const outDir = path.join(OUTPUT_DIR, relModule); + fs.mkdirSync(outDir, {recursive: true}); + fs.writeFileSync(path.join(outDir, `${fileName}.ts`), content); + generatedFiles.push([relModule, fileName].filter(Boolean).join("/")); + count++; + }); + + const indexContent = generatedFiles + .sort() + .map(f => `export * from "./${f}";`) + .join("\n") + "\n"; + fs.writeFileSync(path.join(OUTPUT_DIR, "index.ts"), indexContent); + + fs.rmSync(tmpDir, {recursive: true, force: true}); + console.log(`Generated ${count} definition files in src/definitions/`); +} + +main().catch(err => { console.error(err); process.exit(1); }); diff --git a/ts/src/action.ts b/ts/src/action.ts new file mode 100644 index 0000000..ec8608b --- /dev/null +++ b/ts/src/action.ts @@ -0,0 +1,157 @@ +import {EventEmitter} from "node:events"; +import type {GrpcOptions, GrpcTransport} from "@protobuf-ts/grpc-transport"; +import {ActionTransferRequest, type ActionTransferResponse} from "@code0-tech/tucana/aquila"; +import {constructValue, type PlainValue} from "@code0-tech/tucana/helpers"; +import type {DuplexStreamingCall} from "@protobuf-ts/runtime-rpc"; +import type {FunctionClass} from "./models/function.model"; +import type {RuntimeFunctionClass} from "./models/runtime_function.model"; +import {runtimeFunctionMap} from "./map/runtime_function.map"; +import {functionMap} from "./map/function.map"; +import type {DataTypeClass} from "./models/datatype.model"; +import {dataTypeMap} from "./map/datatype.map"; +import type {EventClass} from "./models/event.model"; +import {eventMap} from "./map/event.map"; +import type {RuntimeEventClass} from "./models/runtime_event.model"; +import {runtimeEventMap} from "./map/runtime_event.map"; +import type {ConfigurationDefinition, Translation} from "./types"; +import {CodeZeroEvent, type CodeZeroEventMap} from "./events"; +import {createConnection} from "./internal/connection"; +import {buildModule} from "./internal/module-builder"; +import {ConfigManager} from "./manager/config-manager"; +import {FunctionManager} from "./manager/FunctionManager"; +import {RuntimeFunctionManager} from "./manager/RuntimeFunctionManager"; +import {DataTypeManager} from "./manager/DataTypeManager"; +import {EventManager} from "./manager/EventManager"; +import {RuntimeEventManager} from "./manager/RuntimeEventManager"; +import {actions} from "./actions"; + +export class Action extends EventEmitter { + private _transport?: GrpcTransport; + private _stream?: DuplexStreamingCall; + private readonly _actions = new Map(actions.map(a => [a.packetType, a.handle])); + + readonly configs = new ConfigManager(); + readonly functions = new FunctionManager(); + readonly runtimeFunctions = new RuntimeFunctionManager(); + readonly dataTypes = new DataTypeManager(); + readonly events = new EventManager(); + readonly runtimeEvents = new RuntimeEventManager(); + + constructor( + private readonly _identifier: string, + private readonly _version: string, + private readonly _aquilaUrl: string | undefined, + private readonly _author: string, + private readonly _icon: string, + private readonly _documentation: string, + private readonly _name: Translation[], + private readonly _configurationDefinitions: ConfigurationDefinition[] = [], + ) { + super(); + } + + get identifier() { return this._identifier; } + get version() { return this._version; } + get stream() { return this._stream; } + + registerFunction(klass: FunctionClass) { + const def = functionMap(klass); + this.functions.set(def.runtimeName, def); + } + + registerRuntimeFunction(klass: RuntimeFunctionClass) { + const omitDefinition = Reflect.getMetadata('hercules:omit_function_definition', klass) || false; + const def = runtimeFunctionMap(klass); + this.runtimeFunctions.set(def.runtimeName, def); + if (!omitDefinition) { + this.functions.set(def.runtimeName, { + ...def, + runtimeDefinitionName: def.runtimeName, + parameters: def.parameters?.map(p => ({...p, runtimeDefinitionName: p.runtimeName})) || [], + }); + } + } + + registerDataTypeClass(klass: DataTypeClass) { + const def = dataTypeMap(klass); + this.dataTypes.set(def.identifier, def); + } + + registerEventClass(klass: EventClass) { + const def = eventMap(klass); + this.events.set(def.identifier, def); + } + + registerRuntimeEventClass(klass: RuntimeEventClass) { + const omitDefinition = Reflect.getMetadata('hercules:omit_event_definition', klass) || false; + const def = runtimeEventMap(klass); + this.runtimeEvents.set(def.identifier, def); + if (!omitDefinition) { + this.events.set(def.identifier, { + ...def, + runtimeIdentifier: def.identifier, + }); + } + } + + async fire(eventClass: EventClass | RuntimeEventClass, projectId: number | bigint, payload: PlainValue) { + if (!this._stream) throw new Error("Not connected. Call connect() first."); + const eventType: string = Reflect.getMetadata('hercules:identifier', eventClass); + if (!eventType) throw new Error(`${eventClass.name} is missing an @Identifier decorator.`); + const request = ActionTransferRequest.create({ + data: { + oneofKind: "event", + event: { + projectId: typeof projectId === "bigint" ? projectId : BigInt(projectId), + eventType, + payload: constructValue(payload ?? null), + }, + }, + }); + await this._stream.requests.send(request); + this.emit(eventType as Extract, projectId, payload); + this.emit(CodeZeroEvent.streamMessageSent, request); + } + + async connect(authToken: string, aquilaUrl?: string, grpcOptions?: GrpcOptions) { + const url = aquilaUrl ?? this._aquilaUrl; + if (!url) throw new Error("aquilaUrl must be provided in the constructor or connect()"); + + try { + const {transport, stream} = await createConnection(this._buildModule(), authToken, url, grpcOptions); + this._transport = transport; + this._stream = stream; + } catch (err) { + this.emit(CodeZeroEvent.error, err as Error); + throw err; + } + + this.emit(CodeZeroEvent.connected, this); + await this._processStream(); + } + + private async _processStream() { + for await (const message of this._stream!.responses) { + this.emit(CodeZeroEvent.streamMessageReceived, message); + const {data} = message; + if (data.oneofKind === undefined) { + this.emit(CodeZeroEvent.error, new Error("Received unknown message type from stream")); + continue; + } + this._actions.get(data.oneofKind)?.(this, (data as Record)[data.oneofKind]); + } + } + + private _buildModule() { + return buildModule({ + identifier: this._identifier, version: this._version, + author: this._author, icon: this._icon, documentation: this._documentation, + name: this._name, configurationDefinitions: this._configurationDefinitions, + dataTypes: this.dataTypes.values(), + events: this.events.values(), + runtimeEvents: this.runtimeEvents.values(), + functions: this.functions.values(), + runtimeFunctions: this.runtimeFunctions.values(), + }); + } +} diff --git a/ts/src/action_sdk.ts b/ts/src/action_sdk.ts deleted file mode 100644 index f8c1137..0000000 --- a/ts/src/action_sdk.ts +++ /dev/null @@ -1,613 +0,0 @@ -import {GrpcTransport} from "@protobuf-ts/grpc-transport"; -import {ChannelCredentials} from "@grpc/grpc-js"; -import {RpcOptions} from "@protobuf-ts/runtime-rpc"; -import { - ActionSdk, HerculesActionConfigurationDefinition, - HerculesActionProjectConfiguration, HerculesFunctionContext, SdkState, RuntimeErrorException, - HerculesRegisterRuntimeFunctionParameter, HerculesRegisterFunctionDefinition -} from "./types.js"; -import { - ActionTransferServiceClient, - DataTypeServiceClient, - DataTypeUpdateRequest, ExecutionRequest, - FlowTypeServiceClient, - FlowTypeUpdateRequest, - FunctionDefinitionServiceClient, - FunctionDefinitionUpdateRequest, RuntimeFunctionDefinitionServiceClient, RuntimeFunctionDefinitionUpdateRequest, - TransferRequest, TransferResponse -} from "@code0-tech/tucana/aquila"; -import { - ActionConfigurations, - FlowTypeSetting, -} from "@code0-tech/tucana/shared"; -import {constructValue, toAllowedValue} from "@code0-tech/tucana/helpers"; -import {logger} from "./logger"; - -const createSdk = (config: ActionSdk["config"], configDefinitions?: HerculesActionConfigurationDefinition[]): ActionSdk => { - const transport = new GrpcTransport( - { - host: config.aquilaUrl, - channelCredentials: ChannelCredentials.createInsecure() - } - ) - const client = new ActionTransferServiceClient(transport); - - const state: SdkState = { - functions: [], - runtimeFunctions: [], - dataTypes: [], - flowTypes: [], - configurationDefinitions: configDefinitions?.map(value => { - return { - identifier: value.identifier, - name: value.name || [], - description: value.description || [], - type: value.type, - linkedDataTypeIdentifiers: value.linkedDataTypes || [], - defaultValue: constructValue(value.defaultValue || null), - } - }) || [], - projectConfigurations: [], - transport: transport, - client: client, - stream: undefined, - fullyConnected: false - } - - const registerFunctionDefinitions = async (...functionDefinitions: Array) => { - for (const functionDefinition of functionDefinitions) { - state.functions.push({ - identifier: functionDefinition.runtimeName, - definition: { - displayMessage: functionDefinition.displayMessage || [], - name: functionDefinition.name || [], - documentation: functionDefinition.documentation || [], - description: functionDefinition.description || [], - deprecationMessage: functionDefinition.deprecationMessage || [], - displayIcon: functionDefinition.displayIcon || "", - alias: functionDefinition.alias || [], - linkedDataTypeIdentifiers: functionDefinition.linkedDataTypes || [], - definitionSource: "action", - version: functionDefinition.version || config.version, - runtimeName: functionDefinition.runtimeName, - parameterDefinitions: (functionDefinition.parameters || []).map(param => ({ - runtimeName: param.runtimeName, - name: param.name || [], - description: param.description || [], - documentation: param.documentation || [], - defaultValue: constructValue(param.defaultValue || null), - hidden: param.hidden || false, - optional: param.hidden || false, - runtimeDefinitionName: param.runtimeDefinitionName || param.runtimeName - })), - signature: functionDefinition.signature, - throwsError: functionDefinition.throwsError || false, - runtimeDefinitionName: functionDefinition.runtimeDefinitionName - } - }); - } - return Promise.resolve() - }; - const registerRuntimeFunctionDefinitions = async (...runtimeFunctionDefinitions: HerculesRegisterRuntimeFunctionParameter[]) => { - for (const registeredFunction of runtimeFunctionDefinitions) { - const handler = registeredFunction.handler; - const functionDefinition = registeredFunction.definition; - state.runtimeFunctions.push({ - identifier: functionDefinition.runtimeName, - definition: { - displayMessage: functionDefinition.displayMessage || [], - name: functionDefinition.name || [], - documentation: functionDefinition.documentation || [], - description: functionDefinition.description || [], - deprecationMessage: functionDefinition.deprecationMessage || [], - displayIcon: functionDefinition.displayIcon || "", - alias: functionDefinition.alias || [], - linkedDataTypeIdentifiers: functionDefinition.linkedDataTypes || [], - definitionSource: "action", - version: functionDefinition.version || config.version, - runtimeName: functionDefinition.runtimeName, - runtimeParameterDefinitions: (functionDefinition.parameters || []).map(param => ({ - runtimeName: param.runtimeName, - name: param.name || [], - description: param.description || [], - documentation: param.documentation || [], - defaultValue: constructValue(param.defaultValue || null), - })), - signature: functionDefinition.signature, - throwsError: functionDefinition.throwsError || false, - }, - handler: handler, - }); - } - return Promise.resolve() - }; - return { - fullyConnected(): boolean { - return state.fullyConnected; - }, - config, - onError: handler => { - state.stream?.responses.onError(handler) - }, - connect: options => { - return connect(state, config, options); - }, - getProjectActionConfigurations: () => { - return state.projectConfigurations.map(value => { - return { - projectId: value.projectId, - configValues: value.actionConfigurations.map(value => { - return { - identifier: value.identifier, - value: toAllowedValue(value.value || constructValue(null)), - } - }), - findConfig: identifier => { - const config = value.actionConfigurations.find(config => config.identifier === identifier); - return config ? toAllowedValue(config.value || constructValue(null)) : undefined; - } - } - }); - }, - registerConfigDefinitions: async (...actionConfigurations) => { - state.configurationDefinitions.push(...(actionConfigurations?.map(value => { - return { - identifier: value.identifier, - name: value.name || [], - description: value.description || [], - type: value.type, - linkedDataTypeIdentifiers: value.linkedDataTypes || [], - defaultValue: constructValue(value.defaultValue || null), - } - }) || [])) - - return Promise.resolve() - }, - registerDataTypes: async (...dataTypes) => { - dataTypes.forEach(dataType => { - state.dataTypes.push({ - identifier: dataType.identifier, - name: dataType.name || [], - alias: dataType.alias || [], - rules: dataType.rules || [], - genericKeys: dataType.genericKeys || [], - type: dataType.type, - linkedDataTypeIdentifiers: dataType.linkedDataTypes || [], - displayMessage: dataType.displayMessage || [], - definitionSource: "action", - version: dataType.version || config.version, - }); - }) - - - return Promise.resolve() - }, - registerFlowTypes: async (...flowTypes) => { - flowTypes.forEach(flowType => { - state.flowTypes.push({ - signature: flowType.signature, - identifier: flowType.identifier, - name: flowType.name || [], - alias: flowType.alias || [], - description: flowType.description || [], - displayIcon: flowType.displayIcon || "", - displayMessage: flowType.displayMessage || [], - documentation: flowType.documentation || [], - definitionSource: "action", - version: flowType.version || config.version, - linkedDataTypeIdentifiers: flowType.linkedDataTypes || [], - settings: (flowType.settings || []).map(setting => ({ - name: setting.name || [], - defaultValue: constructValue(setting.defaultValue || null), - identifier: setting.identifier, - description: setting.description || [], - unique: setting.unique || 1, - linkedDataTypeIdentifiers: setting.linkedDataTypeIdentifiers || [], - } as FlowTypeSetting)), - editable: flowType.editable || false - }); - }) - return Promise.resolve() - }, - registerRuntimeFunctionDefinitionsAndFunctionDefinitions: async (...runtimeFunctionDefinitions) => { - await Promise.all(runtimeFunctionDefinitions.map(async (register) => { - await Promise.all([ - registerRuntimeFunctionDefinitions( - register - ), - registerFunctionDefinitions( - { - ...register.definition, - runtimeDefinitionName: register.definition.runtimeName, - parameters: register.definition.parameters?.map(param => { - return { - ...param, - runtimeDefinitionName: param.runtimeName, - } - }) - } - ) - ]) - })); - }, - registerRuntimeFunctionDefinitions: registerRuntimeFunctionDefinitions, - registerFunctionDefinitions: registerFunctionDefinitions, - dispatchEvent: async (eventType, projectId, payload) => { - if (!state.stream) { - return Promise.reject("SDK is not connected. Call connect() before dispatching events."); - } - const projectIdBigInt = typeof projectId === "bigint" - ? projectId - : BigInt(projectId); - - return state.stream.requests.send( - TransferRequest.create({ - data: { - oneofKind: "event", - event: { - projectId: projectIdBigInt, - eventType: eventType, - payload: constructValue(payload) || constructValue(null), - } - } - }) - ).catch(reason => { - return Promise.reject(reason); - }).then(() => { - return Promise.resolve(); - }) - } - } -} - -async function connect(state: SdkState, config: ActionSdk["config"], options?: RpcOptions): Promise { - const builtOptions: RpcOptions = { - meta: { - "Authorization": config.authToken, - }, - ...options - } - state.stream = state.client.transfer(builtOptions); - - const dataTypeClient = new DataTypeServiceClient(state.transport) - await dataTypeClient.update(DataTypeUpdateRequest.create({ - dataTypes: [ - ...state.dataTypes - ] - }), builtOptions).then(value => { - if (!value.response.success) { - return Promise.reject(value.response); - } - }).catch(reason => { - logger.error({ - err: reason, - config, - }, "Error while updating data types") - return Promise.reject(reason); - }) - logger.debug("Sent data types request") - - await state.stream.requests.send( - TransferRequest.create({ - data: { - oneofKind: "logon", - logon: { - actionIdentifier: config.actionId, - version: config.version, - actionConfigurations: state.configurationDefinitions - } - } - } - ), - ).catch(reason => { - logger.error({ - err: reason, - config, - }, "Failed to send logon request") - return Promise.reject(reason); - }) - - logger.debug("Successfully sent logon request") - - const runtimeFunctionDefinitionClient = new RuntimeFunctionDefinitionServiceClient(state.transport) - await runtimeFunctionDefinitionClient.update( - RuntimeFunctionDefinitionUpdateRequest.create( - { - runtimeFunctions: [ - ...state.runtimeFunctions.map(func => ({ - ...func.definition, - })) - ] - } - ), builtOptions - ).then(value => { - if (!value.response.success) { - logger.error({ - err: value.response, - request: value.request, - config, - }) - return Promise.reject(value.response); - } - }) - logger.debug("Successfully updated runtime function definitions") - - const FunctionDefinitionClient = new FunctionDefinitionServiceClient(state.transport) - try { - const finishedCall = await FunctionDefinitionClient.update( - FunctionDefinitionUpdateRequest.create( - { - functions: [ - ...state.functions.map(func => ({ - ...func.definition, - })) - ] - } - ), builtOptions - ); - - if (!finishedCall.response.success) { - logger.error({ - err: finishedCall.response, - request: finishedCall.request, - config, - }, "Error while updating function definitions") - return Promise.reject(finishedCall.response); - } - } catch (error) { - logger.error({ - err: error, - config, - }, "Error while updating function definitions") - return Promise.reject(error); - } - logger.debug("Updated function definitions") - - const flowTypeClient = new FlowTypeServiceClient(state.transport) - await flowTypeClient.update(FlowTypeUpdateRequest.create({ - flowTypes: [ - ...state.flowTypes - ] - }), builtOptions).then(value => { - if (!value.response.success) { - logger.error({ - err: value.response, - request: value.request, - config, - }) - return Promise.reject(value.response); - } - }) - logger.info("Connected successfully to aquila") - - - return new Promise(async (resolve, reject) => { - try { - for await (let message of state?.stream?.responses || []) { - logger.debug({ - message: message, - config, - }, "Received message from stream") - switch (message?.data.oneofKind) { - case "actionConfigurations": { - logger.info("Received action configurations") - - const configs = message.data.actionConfigurations as ActionConfigurations; - state.projectConfigurations = configs.actionConfigurations - resolve(state.projectConfigurations.map(value => { - return { - projectId: value.projectId, - configValues: value.actionConfigurations.map(value => { - return { - identifier: value.identifier, - value: toAllowedValue(value.value || constructValue(null)), - } - }), - findConfig: identifier => { - const config = value.actionConfigurations.find(config => config.identifier === identifier); - return config ? toAllowedValue(config.value || constructValue(null)) : undefined; - } - } - })); - state.fullyConnected = true - break; - } - case "execution": { - logger.info({ - executionD: message.data.execution.executionIdentifier, - config, - }, "Handling execution request") - - logger.debug({ - message: message, - config, - }, "Handling execution request") - handleExecutionRequest(state, message) - break; - } - } - } - } catch (reason) { - logger.error({ - err: reason, - config - }, "Error occurred in stream") - reject(reason); - } - }) -} - -function handleExecutionRequest(state: SdkState, message: TransferResponse) { - if (!message.data || message.data.oneofKind !== "execution") { - return - } - const execution = message.data.execution as ExecutionRequest; - const func = state.runtimeFunctions.find(value => value.identifier == execution.functionIdentifier); - - if (!func) { - logger.warn({ - message - }, "Received execution request but no matching function found") - return; - } - - const params = Object.entries(execution.parameters!.fields!).map(([key, value]) => { - const param = func.definition.runtimeParameterDefinitions - .find(p => p.runtimeName === key); - - const parameterValue = param ? toAllowedValue(value) : undefined; - if (!parameterValue) return parameterValue - return parameterValue; - }); - - logger.debug({ - message, - BuiltParameter: params - }) - - let conf = state.projectConfigurations.find(config => { - //TODO - return true - }) - - if (!conf) { - logger.error({ - message, - execution - }, "No configuration found") - conf = { - projectId: 0n, - actionConfigurations: [] - } - } - logger.debug({ - message, - conf - }) - - const context: HerculesFunctionContext = { - projectId: execution.projectId, - executionId: execution.executionIdentifier, - matchedConfig: { - projectId: conf.projectId, - configValues: conf.actionConfigurations.map(value => { - return { - identifier: value.identifier, - value: toAllowedValue(value.value || constructValue(null)), - } - }), - findConfig: identifier => { - const config = conf.actionConfigurations.find(config => config.identifier === identifier); - return config ? toAllowedValue(config.value || constructValue(null)) : undefined; - } - } - } - - if (func.handler.length == params.length + 1) { - // handler has context parameter - params.unshift(context) - } else if (func.handler.length > params.length + 1) { - logger.error({ - params, - func, - }, "Handler has more parameters than provided arguments") - return; - } - - const result = new Promise((resolve, reject) => { - try { - resolve(func.handler(...params)) - } catch (e) { - reject(e) - } - }) - result.then((value: any) => { - const request = TransferRequest.create({ - data: { - oneofKind: "result", - result: { - executionIdentifier: execution.executionIdentifier, - result: { - oneofKind: "success", - success: constructValue(value) - }, - } - } - }); - logger.debug({ - request: request - }, "Responding with execution result") - - state.stream!.requests.send(request).catch(reason => { - logger.error({ - err: reason, - request: request, - message, - execution - }, "Responding with execution result lead to error") - }); - }).catch(reason => { - logger.warn({ - err: reason - }, "Executed function lead to error") - let request - if (reason instanceof RuntimeErrorException) { - request = TransferRequest.create({ - data: { - oneofKind: "result", - result: { - executionIdentifier: execution.executionIdentifier, - result: { - oneofKind: "error", - error: { - code: reason.code, - description: reason.description - } - }, - } - } - }); - } else { - request = TransferRequest.create({ - data: { - oneofKind: "result", - result: { - executionIdentifier: execution.executionIdentifier, - result: { - oneofKind: "error", - error: { - code: "UNKNOWN_ERROR", - description: reason.toString() - } - }, - } - } - }); - logger.warn({ - err: reason, - func, - execution - }, "Error occured while executing function, but not an RuntimeErrorException") - } - - logger.debug({ - request: request - }, "Responding with execution error") - - state.stream!.requests.send( - request - ).catch(reason => { - logger.error({ - err: reason, - request: request, - execution, - message - }, "Failed to send execution result error") - }); - }) -} - -export { - createSdk, - connect -} \ No newline at end of file diff --git a/ts/src/actions/Execution.ts b/ts/src/actions/Execution.ts new file mode 100644 index 0000000..0d37da5 --- /dev/null +++ b/ts/src/actions/Execution.ts @@ -0,0 +1,95 @@ +import {constructValue, PlainValue, toAllowedValue} from "@code0-tech/tucana/helpers"; +import {ActionExecutionRequest, ActionExecutionResponse, ActionTransferRequest} from "@code0-tech/tucana/aquila"; +import {NodeExecutionResult, Error as ProtoError} from "@code0-tech/tucana/shared"; +import {FunctionContext, RuntimeError} from "../types"; +import {RuntimeFunctionProps} from "../models/runtime_function.model"; +import {CodeZeroEvent} from "../events"; +import type {Action} from "../action"; + +export const packetType = "execution"; + +function buildParams(execution: ActionExecutionRequest, func: RuntimeFunctionProps): (PlainValue | undefined)[] { + return (func.parameters || []).map(param => { + const field = execution.parameters?.fields?.[param.runtimeName]; + return field ? toAllowedValue(field) : undefined; + }); +} + +export function handle(action: Action, execution: ActionExecutionRequest): void { + action.emit(CodeZeroEvent.executionRequestReceived, execution); + + const func = action.runtimeFunctions.get(execution.functionIdentifier); + if (!func) { + console.error("Received execution request for unknown function:", execution.functionIdentifier); + return; + } + + const params = buildParams(execution, func); + + const conf = action.configs.get(execution.projectId) ?? { + projectId: 0n, + configValues: [], + findConfig: () => undefined, + }; + + const context: FunctionContext = { + projectId: execution.projectId, + executionId: execution.executionIdentifier, + matchedConfig: conf, + }; + + const startedAt = BigInt(Date.now()); + const funcHandler = func.handler; + const allParams: (PlainValue | undefined)[] = + funcHandler.length === params.length + 1 ? [context as PlainValue, ...params] : params; + + Promise.resolve(funcHandler(...allParams)).then((value: PlainValue) => { + const finishedAt = BigInt(Date.now()); + action.stream!.requests.send(ActionTransferRequest.create({ + data: { + oneofKind: "result", + result: ActionExecutionResponse.create({ + executionIdentifier: execution.executionIdentifier, + nodeResult: NodeExecutionResult.create({ + id: {oneofKind: undefined}, + startedAt, + finishedAt, + parameterResults: [], + result: {oneofKind: "success", success: constructValue(value)}, + }), + }), + }, + })).catch(err => console.error("Failed to send execution result:", err)); + + }).catch((error: unknown) => { + const finishedAt = BigInt(Date.now()); + const isRuntimeError = error instanceof RuntimeError; + action.stream!.requests.send(ActionTransferRequest.create({ + data: { + oneofKind: "result", + result: ActionExecutionResponse.create({ + executionIdentifier: execution.executionIdentifier, + nodeResult: NodeExecutionResult.create({ + id: {oneofKind: undefined}, + startedAt, + finishedAt, + parameterResults: [], + result: { + oneofKind: "error", + error: ProtoError.create({ + code: isRuntimeError ? (error as RuntimeError).code : "UNKNOWN_ERROR", + category: "RUNTIME", + message: isRuntimeError + ? ((error as RuntimeError).description || (error as Error).message) + : String(error), + timestamp: finishedAt, + version: action.version, + dependencies: {}, + }), + }, + }), + }), + }, + })).catch(err => console.error("Failed to send execution error:", err)); + }); +} diff --git a/ts/src/actions/ModuleConfigurations.ts b/ts/src/actions/ModuleConfigurations.ts new file mode 100644 index 0000000..cf573e0 --- /dev/null +++ b/ts/src/actions/ModuleConfigurations.ts @@ -0,0 +1,10 @@ +import type {ModuleConfigurations} from "@code0-tech/tucana/shared"; +import {CodeZeroEvent} from "../events"; +import type {Action} from "../action"; + +export const packetType = "moduleConfigurations"; + +export function handle(action: Action, data: ModuleConfigurations): void { + action.configs.update(data.moduleConfigurations); + action.emit(CodeZeroEvent.moduleUpdated, data); +} diff --git a/ts/src/actions/index.ts b/ts/src/actions/index.ts new file mode 100644 index 0000000..d531f3b --- /dev/null +++ b/ts/src/actions/index.ts @@ -0,0 +1,13 @@ +import type {Action} from "../action"; +import * as ModuleConfigurations from "./ModuleConfigurations"; +import * as Execution from "./Execution"; + +export interface ActionHandler { + packetType: string; + handle(action: Action, data: unknown): void; +} + +export const actions: ActionHandler[] = [ + ModuleConfigurations, + Execution, +]; diff --git a/ts/src/decorators/datatype.dec.ts b/ts/src/decorators/datatype.dec.ts new file mode 100644 index 0000000..35aac7d --- /dev/null +++ b/ts/src/decorators/datatype.dec.ts @@ -0,0 +1,7 @@ +import type {ZodTypeAny} from "zod"; + +export const Schema = (schema: ZodTypeAny): ClassDecorator => + (target) => Reflect.defineMetadata('hercules:schema', schema, target) + +export const GenericKeys = (...keys: string[]): ClassDecorator => + (target) => Reflect.defineMetadata('hercules:generic_keys', keys, target) diff --git a/ts/src/decorators/event.dec.ts b/ts/src/decorators/event.dec.ts new file mode 100644 index 0000000..d8847e8 --- /dev/null +++ b/ts/src/decorators/event.dec.ts @@ -0,0 +1,8 @@ +import {EventSettingProps} from "../models/event.model"; + +export const EventSetting = (setting: EventSettingProps): ClassDecorator => + (target) => { + const settings = Reflect.getMetadata('hercules:flow_settings', target) || []; + settings.push(setting); + Reflect.defineMetadata('hercules:flow_settings', settings, target); + } diff --git a/ts/src/decorators/function.dec.ts b/ts/src/decorators/function.dec.ts new file mode 100644 index 0000000..92191eb --- /dev/null +++ b/ts/src/decorators/function.dec.ts @@ -0,0 +1,17 @@ +import {FunctionParameterProps} from "../models/function.model"; + +export const OmitFunctionDefinition = (): ClassDecorator => + (target) => Reflect.defineMetadata('hercules:omit_function_definition', true, target) + +export const ThrowsError = (throwsError: boolean = true): ClassDecorator => + (target) => Reflect.defineMetadata('hercules:throws_error', throwsError, target) + +export const LinkedDataTypeIdentifiers = (...linkedDataTypeIdentifiers: string[]): ClassDecorator => + (target) => Reflect.defineMetadata('hercules:linked_data_type_identifiers', linkedDataTypeIdentifiers, target) + +export const FunctionParameter = (parameter: FunctionParameterProps): ClassDecorator => + (target) => { + const parameters = Reflect.getMetadata('hercules:function_parameters', target) || []; + parameters.push(parameter); + Reflect.defineMetadata('hercules:function_parameters', parameters, target); + } diff --git a/ts/src/decorators/meta.dec.ts b/ts/src/decorators/meta.dec.ts new file mode 100644 index 0000000..01e1e24 --- /dev/null +++ b/ts/src/decorators/meta.dec.ts @@ -0,0 +1,31 @@ +import {Translation} from "../types"; + +export const Identifier = (id: string): ClassDecorator => + (target) => Reflect.defineMetadata('hercules:identifier', id, target) + +export const Name = (...translation: Translation[]): ClassDecorator => + (target) => Reflect.defineMetadata('hercules:name', translation, target) + +export const Description = (...translation: Translation[]): ClassDecorator => + (target) => Reflect.defineMetadata('hercules:description', translation, target) + +export const Documentation = (...translation: Translation[]): ClassDecorator => + (target) => Reflect.defineMetadata('hercules:documentation', translation, target) + +export const DisplayMessage = (...translation: Translation[]): ClassDecorator => + (target) => Reflect.defineMetadata('hercules:display_message', translation, target) + +export const Alias = (...translation: Translation[]): ClassDecorator => + (target) => Reflect.defineMetadata('hercules:alias', translation, target) + +export const DeprecationMessage = (...translation: Translation[]): ClassDecorator => + (target) => Reflect.defineMetadata('hercules:deprecation_message', translation, target) + +export const Signature = (signature: string): ClassDecorator => + (target) => Reflect.defineMetadata('hercules:signature', signature, target) + +export const DisplayIcon = (displayIcon: string): ClassDecorator => + (target) => Reflect.defineMetadata('hercules:display_icon', displayIcon, target) + +export const Editable = (editable: boolean = true): ClassDecorator => + (target) => Reflect.defineMetadata('hercules:editable', editable, target) diff --git a/ts/src/decorators/runtime_event.dec.ts b/ts/src/decorators/runtime_event.dec.ts new file mode 100644 index 0000000..3b90fc5 --- /dev/null +++ b/ts/src/decorators/runtime_event.dec.ts @@ -0,0 +1,2 @@ +export const OmitEventDefinition = (): ClassDecorator => + (target) => Reflect.defineMetadata('hercules:omit_event_definition', true, target) diff --git a/ts/src/events.ts b/ts/src/events.ts new file mode 100644 index 0000000..8c06e82 --- /dev/null +++ b/ts/src/events.ts @@ -0,0 +1,22 @@ +import type {ActionExecutionRequest, ActionTransferRequest, ActionTransferResponse} from "@code0-tech/tucana/aquila"; +import type {ModuleConfigurations} from "@code0-tech/tucana/shared"; +import type {Action} from "./action.ts"; + +export enum CodeZeroEvent { + error = "error", + connected = "connected", + streamMessageReceived = "streamMessageReceived", + streamMessageSent = "streamMessageSent", + moduleUpdated = "moduleUpdated", + executionRequestReceived = "executionRequestReceived", +} + +export interface CodeZeroEventMap { + [CodeZeroEvent.error]: [Error] + [CodeZeroEvent.connected]: [Action] + [CodeZeroEvent.streamMessageReceived]: [ActionTransferResponse] + [CodeZeroEvent.streamMessageSent]: [ActionTransferRequest] + [CodeZeroEvent.moduleUpdated]: [ModuleConfigurations] + [CodeZeroEvent.executionRequestReceived]: [ActionExecutionRequest] + [key: string]: unknown[] +} diff --git a/ts/src/index.ts b/ts/src/index.ts index 169c718..108e51d 100644 --- a/ts/src/index.ts +++ b/ts/src/index.ts @@ -1,2 +1,21 @@ -export * from "./action_sdk.js" -export * from "./types.js" \ No newline at end of file +export * from "./types" +export * from "./events" +export * from "./decorators/meta.dec" +export * from "./decorators/function.dec" +export * from "./decorators/datatype.dec" +export * from "./decorators/event.dec" +export * from "./decorators/runtime_event.dec" +export * from "./definitions" +export * from "./manager/BaseManager" +export * from "./manager/config-manager" +export * from "./manager/FunctionManager" +export * from "./manager/RuntimeFunctionManager" +export * from "./manager/DataTypeManager" +export * from "./manager/EventManager" +export * from "./manager/RuntimeEventManager" +export * from "./models/function.model" +export * from "./models/runtime_function.model" +export * from "./models/datatype.model" +export * from "./models/event.model" +export * from "./models/runtime_event.model" +export * from "./action" diff --git a/ts/src/internal/connection.ts b/ts/src/internal/connection.ts new file mode 100644 index 0000000..7a22e43 --- /dev/null +++ b/ts/src/internal/connection.ts @@ -0,0 +1,39 @@ +import {GrpcOptions, GrpcTransport} from "@protobuf-ts/grpc-transport"; +import {ActionTransferRequest, ActionTransferResponse, ActionTransferServiceClient, ModuleServiceClient, ModuleUpdateRequest} from "@code0-tech/tucana/aquila"; +import type {Module} from "@code0-tech/tucana/shared"; +import {ChannelCredentials} from "@grpc/grpc-js"; +import {type RpcOptions} from "@protobuf-ts/runtime-rpc"; +import type {DuplexStreamingCall} from "@protobuf-ts/runtime-rpc"; + +export interface Connection { + transport: GrpcTransport; + stream: DuplexStreamingCall; +} + +export async function createConnection( + module: Module, + authToken: string, + aquilaUrl: string, + grpcOptions?: GrpcOptions, +): Promise { + const transport = new GrpcTransport({ + host: aquilaUrl, + channelCredentials: ChannelCredentials.createInsecure(), + ...grpcOptions, + }); + + const rpcOptions: RpcOptions = {meta: {"authorization": authToken}}; + + const response = await new ModuleServiceClient(transport).update( + ModuleUpdateRequest.create({modules: [module]}), + rpcOptions, + ); + + if (!response.response.success) { + throw new Error("Module update failed"); + } + + const stream = new ActionTransferServiceClient(transport).transfer(rpcOptions); + + return {transport, stream}; +} diff --git a/ts/src/internal/module-builder.ts b/ts/src/internal/module-builder.ts new file mode 100644 index 0000000..3520756 --- /dev/null +++ b/ts/src/internal/module-builder.ts @@ -0,0 +1,156 @@ +import {constructValue} from "@code0-tech/tucana/helpers"; +import {DefinitionDataType, FlowType, FlowTypeSetting, Module, ModuleConfigurationDefinition, RuntimeFlowType, RuntimeFlowTypeSetting} from "@code0-tech/tucana/shared"; +import type {FunctionProps} from "../models/function.model"; +import type {RuntimeFunctionProps} from "../models/runtime_function.model"; +import type {ConfigurationDefinition, Translation} from "../types"; +import {DataTypeProps} from "../models/datatype.model"; +import {EventModel} from "../models/event.model"; +import {RuntimeEventProps} from "../models/runtime_event.model"; + +export interface ModuleBuildData { + identifier: string; + version: string; + author: string; + icon: string; + documentation: string; + name: Translation[]; + configurationDefinitions: ConfigurationDefinition[]; + dataTypes: DataTypeProps[]; + events: EventModel[]; + runtimeEvents: RuntimeEventProps[]; + functions: FunctionProps[]; + runtimeFunctions: RuntimeFunctionProps[]; +} + +export function buildModule(data: ModuleBuildData): Module { + return { + identifier: data.identifier, + version: data.version, + author: data.author, + icon: data.icon, + documentation: data.documentation, + name: data.name, + description: [], + configurations: data.configurationDefinitions.map(def => ({ + identifier: def.identifier, + name: def.name ?? [], + description: def.description ?? [], + type: def.type, + linkedDataTypeIdentifiers: def.linkedDataTypes ?? [], + defaultValue: def.defaultValue != null ? constructValue(def.defaultValue) : undefined, + optional: def.optional ?? false, + hidden: def.hidden ?? false, + } as ModuleConfigurationDefinition)), + definitionDataTypes: data.dataTypes.map(dt => ({ + identifier: dt.identifier, + name: dt.name ?? [], + alias: dt.alias ?? [], + rules: dt.rules ?? [], + genericKeys: dt.genericKeys ?? [], + type: dt.type, + linkedDataTypeIdentifiers: dt.linkedDataTypes ?? [], + displayMessage: dt.displayMessage ?? [], + version: data.version, + definitionSource: "action", + } as DefinitionDataType)), + flowTypes: data.events.map(ft => ({ + identifier: ft.identifier, + settings: (ft.settings ?? []).map(s => ({ + identifier: s.identifier, + unique: s.unique ?? 1, + linkedDataTypeIdentifiers: s.linkedDataTypeIdentifiers ?? [], + defaultValue: s.defaultValue != null ? constructValue(s.defaultValue) : undefined, + name: s.name ?? [], + description: s.description ?? [], + optional: s.optional ?? false, + hidden: s.hidden ?? false, + } as FlowTypeSetting)), + editable: ft.editable ?? false, + name: ft.name ?? [], + description: ft.description ?? [], + documentation: ft.documentation ?? [], + displayMessage: ft.displayMessage ?? [], + alias: ft.alias ?? [], + version: data.version, + displayIcon: ft.displayIcon ?? "tabler:note", + definitionSource: "action", + linkedDataTypeIdentifiers: ft.linkedDataTypes ?? [], + signature: ft.signature, + runtimeIdentifier: ft.runtimeIdentifier ?? ft.identifier, + } as FlowType)), + runtimeFlowTypes: data.runtimeEvents.map(rft => ({ + identifier: rft.identifier, + runtimeSettings: (rft.settings ?? []).map(s => ({ + identifier: s.identifier, + unique: s.unique ?? 0, + defaultValue: s.defaultValue != null ? constructValue(s.defaultValue) : undefined, + name: s.name ?? [], + description: s.description ?? [], + optional: s.optional ?? false, + hidden: s.hidden ?? false, + } as RuntimeFlowTypeSetting)), + editable: rft.editable ?? false, + name: rft.name ?? [], + description: rft.description ?? [], + documentation: rft.documentation ?? [], + displayMessage: rft.displayMessage ?? [], + alias: rft.alias ?? [], + version: data.version, + displayIcon: rft.displayIcon ?? "tabler:note", + definitionSource: "action", + linkedDataTypeIdentifiers: rft.linkedDataTypes ?? [], + signature: rft.signature, + } as RuntimeFlowType)), + functionDefinitions: data.functions.map(f => ({ + runtimeName: f.runtimeName, + runtimeDefinitionName: f.runtimeDefinitionName, + signature: f.signature, + throwsError: f.throwsError ?? false, + name: f.name ?? [], + description: f.description ?? [], + documentation: f.documentation ?? [], + deprecationMessage: f.deprecationMessage ?? [], + displayMessage: f.displayMessage ?? [], + alias: f.alias ?? [], + linkedDataTypeIdentifiers: f.linkedDataTypes ?? [], + displayIcon: f.displayIcon ?? "tabler:note", + version: data.version, + definitionSource: "action", + parameterDefinitions: (f.parameters ?? []).map(p => ({ + runtimeName: p.runtimeName, + runtimeDefinitionName: p.runtimeDefinitionName ?? p.runtimeName, + name: p.name ?? [], + description: p.description ?? [], + documentation: p.documentation ?? [], + hidden: p.hidden ?? false, + optional: p.optional ?? false, + defaultValue: p.defaultValue != null ? constructValue(p.defaultValue) : undefined, + })), + })), + runtimeFunctionDefinitions: data.runtimeFunctions.map(f => ({ + runtimeName: f.runtimeName, + signature: f.signature, + throwsError: f.throwsError ?? false, + name: f.name ?? [], + description: f.description ?? [], + documentation: f.documentation ?? [], + deprecationMessage: f.deprecationMessage ?? [], + displayMessage: f.displayMessage ?? [], + alias: f.alias ?? [], + linkedDataTypeIdentifiers: f.linkedDataTypes ?? [], + displayIcon: f.displayIcon ?? "tabler:note", + version: data.version, + definitionSource: "action", + runtimeParameterDefinitions: (f.parameters ?? []).map(p => ({ + runtimeName: p.runtimeName, + name: p.name ?? [], + description: p.description ?? [], + documentation: p.documentation ?? [], + hidden: p.hidden ?? false, + optional: p.optional ?? false, + defaultValue: p.defaultValue != null ? constructValue(p.defaultValue) : undefined, + })), + })), + definitions: [], + }; +} diff --git a/ts/src/internal/zod-schema.ts b/ts/src/internal/zod-schema.ts new file mode 100644 index 0000000..3ef32a7 --- /dev/null +++ b/ts/src/internal/zod-schema.ts @@ -0,0 +1,26 @@ +import {toJSONSchema, type ZodTypeAny} from "zod"; +import {zodToTs, printNode, createAuxiliaryTypeStore} from "zod-to-ts"; +import type {DefinitionDataTypeRule} from "@code0-tech/tucana/shared"; + +type JsonSchema = { + pattern?: string; + minimum?: number; + maximum?: number; +}; + +export function zodToTypeString(schema: ZodTypeAny): string { + const {node} = zodToTs(schema, {auxiliaryTypeStore: createAuxiliaryTypeStore()}); + return printNode(node); +} + +export function zodToRules(schema: ZodTypeAny): DefinitionDataTypeRule[] { + const json = toJSONSchema(schema) as JsonSchema; + const rules: DefinitionDataTypeRule[] = []; + if (json.pattern) { + rules.push({config: {oneofKind: "regex", regex: {pattern: json.pattern}}}); + } + if (json.minimum !== undefined && json.maximum !== undefined) { + rules.push({config: {oneofKind: "numberRange", numberRange: {from: BigInt(json.minimum), to: BigInt(json.maximum)}}}); + } + return rules; +} diff --git a/ts/src/logger.ts b/ts/src/logger.ts deleted file mode 100644 index a196c63..0000000 --- a/ts/src/logger.ts +++ /dev/null @@ -1,12 +0,0 @@ -import pino from 'pino'; - -export const logger = pino({ - redact: ["config.authToken"], - level: process.env.LOG_LEVEL || "debug", - transport: { - target: 'pino-pretty', - options: { - colorize: true - } - } -}); \ No newline at end of file diff --git a/ts/src/manager/BaseManager.ts b/ts/src/manager/BaseManager.ts new file mode 100644 index 0000000..e716100 --- /dev/null +++ b/ts/src/manager/BaseManager.ts @@ -0,0 +1,85 @@ +export abstract class BaseManager { + readonly cache = new Map(); + + get size(): number { + return this.cache.size; + } + + get(key: K): V | undefined { + return this.cache.get(key); + } + + has(key: K): boolean { + return this.cache.has(key); + } + + set(key: K, value: V): this { + this.cache.set(key, value); + return this; + } + + delete(key: K): boolean { + return this.cache.delete(key); + } + + clear(): void { + this.cache.clear(); + } + + values(): V[] { + return [...this.cache.values()]; + } + + keys(): K[] { + return [...this.cache.keys()]; + } + + entries(): [K, V][] { + return [...this.cache.entries()]; + } + + find(predicate: (value: V, key: K) => boolean): V | undefined { + for (const [key, value] of this.cache) { + if (predicate(value, key)) return value; + } + return undefined; + } + + filter(predicate: (value: V, key: K) => boolean): V[] { + const result: V[] = []; + for (const [key, value] of this.cache) { + if (predicate(value, key)) result.push(value); + } + return result; + } + + map(fn: (value: V, key: K) => T): T[] { + const result: T[] = []; + for (const [key, value] of this.cache) { + result.push(fn(value, key)); + } + return result; + } + + some(predicate: (value: V, key: K) => boolean): boolean { + for (const [key, value] of this.cache) { + if (predicate(value, key)) return true; + } + return false; + } + + every(predicate: (value: V, key: K) => boolean): boolean { + for (const [key, value] of this.cache) { + if (!predicate(value, key)) return false; + } + return true; + } + + forEach(fn: (value: V, key: K) => void): void { + this.cache.forEach((value, key) => fn(value, key)); + } + + [Symbol.iterator](): IterableIterator<[K, V]> { + return this.cache[Symbol.iterator](); + } +} diff --git a/ts/src/manager/DataTypeManager.ts b/ts/src/manager/DataTypeManager.ts new file mode 100644 index 0000000..aa79083 --- /dev/null +++ b/ts/src/manager/DataTypeManager.ts @@ -0,0 +1,4 @@ +import {BaseManager} from "./BaseManager"; +import {DataTypeProps} from "../models/datatype.model"; + +export class DataTypeManager extends BaseManager {} diff --git a/ts/src/manager/EventManager.ts b/ts/src/manager/EventManager.ts new file mode 100644 index 0000000..a9b25c1 --- /dev/null +++ b/ts/src/manager/EventManager.ts @@ -0,0 +1,4 @@ +import {BaseManager} from "./BaseManager"; +import {EventModel} from "../models/event.model"; + +export class EventManager extends BaseManager {} diff --git a/ts/src/manager/FunctionManager.ts b/ts/src/manager/FunctionManager.ts new file mode 100644 index 0000000..af7f5df --- /dev/null +++ b/ts/src/manager/FunctionManager.ts @@ -0,0 +1,4 @@ +import {BaseManager} from "./BaseManager"; +import type {FunctionProps} from "../models/function.model"; + +export class FunctionManager extends BaseManager {} diff --git a/ts/src/manager/RuntimeEventManager.ts b/ts/src/manager/RuntimeEventManager.ts new file mode 100644 index 0000000..e55e9f2 --- /dev/null +++ b/ts/src/manager/RuntimeEventManager.ts @@ -0,0 +1,4 @@ +import {BaseManager} from "./BaseManager"; +import {RuntimeEventProps} from "../models/runtime_event.model"; + +export class RuntimeEventManager extends BaseManager {} diff --git a/ts/src/manager/RuntimeFunctionManager.ts b/ts/src/manager/RuntimeFunctionManager.ts new file mode 100644 index 0000000..facb8a3 --- /dev/null +++ b/ts/src/manager/RuntimeFunctionManager.ts @@ -0,0 +1,4 @@ +import {BaseManager} from "./BaseManager"; +import type {RuntimeFunctionProps} from "../models/runtime_function.model"; + +export class RuntimeFunctionManager extends BaseManager {} diff --git a/ts/src/manager/config-manager.ts b/ts/src/manager/config-manager.ts new file mode 100644 index 0000000..5d5b4b4 --- /dev/null +++ b/ts/src/manager/config-manager.ts @@ -0,0 +1,23 @@ +import {constructValue, toAllowedValue} from "@code0-tech/tucana/helpers"; +import type {ModuleProjectConfigurations} from "@code0-tech/tucana/shared"; +import type {ProjectConfiguration} from "../types"; +import {BaseManager} from "./BaseManager"; + +export class ConfigManager extends BaseManager { + update(configs: ModuleProjectConfigurations[]): void { + this.clear(); + for (const config of configs) { + this.set(config.projectId, { + projectId: config.projectId, + configValues: config.moduleConfigurations.map(mc => ({ + identifier: mc.identifier, + value: toAllowedValue(mc.value || constructValue(null)), + })), + findConfig: identifier => { + const mc = config.moduleConfigurations.find(c => c.identifier === identifier); + return mc ? toAllowedValue(mc.value || constructValue(null)) : undefined; + }, + }); + } + } +} diff --git a/ts/src/map/datatype.map.ts b/ts/src/map/datatype.map.ts new file mode 100644 index 0000000..1e61a9f --- /dev/null +++ b/ts/src/map/datatype.map.ts @@ -0,0 +1,28 @@ +import {zodToRules, zodToTypeString} from "../internal/zod-schema"; +import type {Translation} from "../types"; +import type {DataTypeClass, DataTypeProps} from "../models/datatype.model"; + +export const dataTypeMap = (klass: DataTypeClass): DataTypeProps => { + const identifier: string = Reflect.getMetadata('hercules:identifier', klass); + const name: Translation[] = Reflect.getMetadata('hercules:name', klass) || []; + const displayMessage: Translation[] = Reflect.getMetadata('hercules:display_message', klass) || []; + const alias: Translation[] = Reflect.getMetadata('hercules:alias', klass) || []; + const linkedDataTypes: string[] = Reflect.getMetadata('hercules:linked_data_type_identifiers', klass) || []; + const genericKeys: string[] = Reflect.getMetadata('hercules:generic_keys', klass) || []; + + if (!identifier) throw new Error(`Data type class ${klass.name} is missing an identifier. Add @Identifier("your_identifier") to the class.`); + + const schema = Reflect.getMetadata('hercules:schema', klass); + if (!schema) throw new Error(`Data type class ${klass.name} is missing a schema. Add @Schema(z.string()) to the class.`); + + return { + identifier, + type: zodToTypeString(schema), + rules: zodToRules(schema), + name, + displayMessage, + alias, + linkedDataTypes, + genericKeys, + }; +}; diff --git a/ts/src/map/event.map.ts b/ts/src/map/event.map.ts new file mode 100644 index 0000000..27f746d --- /dev/null +++ b/ts/src/map/event.map.ts @@ -0,0 +1,51 @@ +import type {Translation} from "../types"; +import type {EventClass, EventModel, EventSettingProps} from "../models/event.model"; +import type {RuntimeEventClass} from "../models/runtime_event.model"; +import {runtimeEventMap} from "./runtime_event.map"; + +export const eventMap = (klass: EventClass): EventModel => { + const parentClass = Object.getPrototypeOf(klass); + const runtimeEvent = runtimeEventMap(parentClass); + + const identifier: string = Reflect.getMetadata('hercules:identifier', klass); + const signature: string = Reflect.getMetadata('hercules:signature', klass); + const settings: EventSettingProps[] = Reflect.getMetadata('hercules:flow_settings', klass) || []; + const name: Translation[] = Reflect.getMetadata('hercules:name', klass); + const description: Translation[] = Reflect.getMetadata('hercules:description', klass); + const documentation: Translation[] = Reflect.getMetadata('hercules:documentation', klass); + const displayMessage: Translation[] = Reflect.getMetadata('hercules:display_message', klass); + const alias: Translation[] = Reflect.getMetadata('hercules:alias', klass); + const linkedDataTypes: string[] = Reflect.getMetadata('hercules:linked_data_type_identifiers', klass); + const displayIcon: string | undefined = Reflect.getMetadata('hercules:display_icon', klass); + const editable: boolean = Reflect.getMetadata('hercules:editable', klass) ?? false; + + if (!identifier) throw new Error(`Event class ${klass.name} is missing an identifier. Add @Identifier("your_identifier") to the class.`); + + for (const es of settings) { + if (!runtimeEvent.settings?.find(s => s.identifier === es.identifier)) { + throw new Error(`Event class ${klass.name} has a setting "${es.identifier}" that does not exist in its runtime event.`); + } + } + + const mergedSettings: EventSettingProps[] = [...settings]; + for (const rs of runtimeEvent.settings ?? []) { + if (!mergedSettings.find(s => s.identifier === rs.identifier)) { + mergedSettings.push({...rs}); + } + } + + return { + runtimeIdentifier: runtimeEvent.identifier, + identifier, + signature: signature || runtimeEvent.signature, + settings: mergedSettings, + name: name || runtimeEvent.name, + description: description || runtimeEvent.description, + documentation: documentation || runtimeEvent.documentation, + displayMessage: displayMessage || runtimeEvent.displayMessage, + alias: alias || runtimeEvent.alias, + linkedDataTypes: linkedDataTypes || runtimeEvent.linkedDataTypes, + displayIcon: displayIcon || runtimeEvent.displayIcon, + editable, + }; +}; diff --git a/ts/src/map/function.map.ts b/ts/src/map/function.map.ts new file mode 100644 index 0000000..a550f6d --- /dev/null +++ b/ts/src/map/function.map.ts @@ -0,0 +1,62 @@ +import {FunctionClass, FunctionProps, FunctionParameterProps} from "../models/function.model"; +import {RuntimeFunctionClass} from "../models/runtime_function.model"; +import {runtimeFunctionMap} from "./runtime_function.map"; + +export const functionMap = (klass: FunctionClass): FunctionProps => { + const parentClass = Object.getPrototypeOf(klass); + const runtimeFunction = runtimeFunctionMap(parentClass); + + const identifier: string = Reflect.getMetadata('hercules:identifier', klass); + const functionParameters: FunctionParameterProps[] = Reflect.getMetadata('hercules:function_parameters', klass) || []; + const name: FunctionProps["name"] = Reflect.getMetadata('hercules:name', klass); + const displayMessage: FunctionProps["displayMessage"] = Reflect.getMetadata('hercules:display_message', klass); + const description: FunctionProps["description"] = Reflect.getMetadata('hercules:description', klass); + const deprecationMessage: FunctionProps["deprecationMessage"] = Reflect.getMetadata('hercules:deprecation_message', klass); + const alias: FunctionProps["alias"] = Reflect.getMetadata('hercules:alias', klass); + const documentation: FunctionProps["documentation"] = Reflect.getMetadata('hercules:documentation', klass); + const signature: FunctionProps["signature"] = Reflect.getMetadata('hercules:signature', klass); + const linkedDataTypes: FunctionProps["linkedDataTypes"] = Reflect.getMetadata('hercules:linked_data_type_identifiers', klass); + const displayIcon: FunctionProps["displayIcon"] = Reflect.getMetadata('hercules:display_icon', klass); + const throwsError: FunctionProps["throwsError"] = Reflect.getMetadata('hercules:throws_error', klass); + + if (functionParameters.length > (runtimeFunction.parameters?.length ?? 0)) { + throw new Error(`Function definition class ${klass.name} has more function parameters than its runtime function.`); + } + + for (const fp of functionParameters) { + if (!runtimeFunction.parameters?.find(p => p.runtimeName === fp.runtimeName)) { + throw new Error(`Function definition class ${klass.name} has a function parameter "${fp.runtimeName}" that does not exist in its runtime function.`); + } + } + + const mergedParameters: FunctionParameterProps[] = [...functionParameters]; + for (const rp of runtimeFunction.parameters ?? []) { + if (!mergedParameters.find(p => p.runtimeName === rp.runtimeName)) { + mergedParameters.push({...rp, runtimeDefinitionName: rp.runtimeName}); + } + } + + return { + runtimeDefinitionName: runtimeFunction.runtimeName, + runtimeName: identifier || runtimeFunction.runtimeName, + signature: signature || runtimeFunction.signature, + throwsError: throwsError ?? runtimeFunction.throwsError, + alias: alias || runtimeFunction.alias, + description: description || runtimeFunction.description, + name: name || runtimeFunction.name, + documentation: documentation || runtimeFunction.documentation, + deprecationMessage: deprecationMessage || runtimeFunction.deprecationMessage, + displayMessage: displayMessage || runtimeFunction.displayMessage, + displayIcon: displayIcon || runtimeFunction.displayIcon, + linkedDataTypes: linkedDataTypes || runtimeFunction.linkedDataTypes, + parameters: mergedParameters.map(p => ({ + ...p, + runtimeDefinitionName: p.runtimeDefinitionName || p.runtimeName, + name: p.name || [], + description: p.description || [], + documentation: p.documentation || [], + hidden: p.hidden || false, + optional: p.optional || false, + })), + }; +}; diff --git a/ts/src/map/runtime_event.map.ts b/ts/src/map/runtime_event.map.ts new file mode 100644 index 0000000..b991c4f --- /dev/null +++ b/ts/src/map/runtime_event.map.ts @@ -0,0 +1,22 @@ +import type {Translation} from "../types"; +import type {RuntimeEventProps, RuntimeEventClass} from "../models/runtime_event.model"; +import type {EventSettingProps} from "../models/event.model"; + +export const runtimeEventMap = (klass: RuntimeEventClass): RuntimeEventProps => { + const identifier: string = Reflect.getMetadata('hercules:identifier', klass); + const signature: string = Reflect.getMetadata('hercules:signature', klass); + const settings: EventSettingProps[] = Reflect.getMetadata('hercules:flow_settings', klass) || []; + const name: Translation[] = Reflect.getMetadata('hercules:name', klass) || []; + const description: Translation[] = Reflect.getMetadata('hercules:description', klass) || []; + const documentation: Translation[] = Reflect.getMetadata('hercules:documentation', klass) || []; + const displayMessage: Translation[] = Reflect.getMetadata('hercules:display_message', klass) || []; + const alias: Translation[] = Reflect.getMetadata('hercules:alias', klass) || []; + const linkedDataTypes: string[] = Reflect.getMetadata('hercules:linked_data_type_identifiers', klass) || []; + const displayIcon: string | undefined = Reflect.getMetadata('hercules:display_icon', klass); + const editable: boolean = Reflect.getMetadata('hercules:editable', klass) ?? false; + + if (!identifier) throw new Error(`Runtime event class ${klass.name} is missing an identifier. Add @Identifier("your_identifier") to the class.`); + if (!signature) throw new Error(`Runtime event class ${klass.name} is missing a signature. Add @Signature("(): RETURN_TYPE") to the class.`); + + return {identifier, signature, settings, name, description, documentation, displayMessage, alias, linkedDataTypes, displayIcon, editable}; +}; diff --git a/ts/src/map/runtime_function.map.ts b/ts/src/map/runtime_function.map.ts new file mode 100644 index 0000000..6c3d243 --- /dev/null +++ b/ts/src/map/runtime_function.map.ts @@ -0,0 +1,47 @@ +import type {PlainValue} from "@code0-tech/tucana/helpers"; +import {RuntimeFunctionProps, RuntimeFunctionClass} from "../models/runtime_function.model"; +import {FunctionParameterProps} from "../models/function.model"; + +export const runtimeFunctionMap = (klass: RuntimeFunctionClass): RuntimeFunctionProps => { + const identifier: string = Reflect.getMetadata('hercules:identifier', klass); + const runtimeParameters: FunctionParameterProps[] = Reflect.getMetadata('hercules:function_parameters', klass) || []; + const name: RuntimeFunctionProps["name"] = Reflect.getMetadata('hercules:name', klass) || []; + const displayMessage: RuntimeFunctionProps["displayMessage"] = Reflect.getMetadata('hercules:display_message', klass) || []; + const description: RuntimeFunctionProps["description"] = Reflect.getMetadata('hercules:description', klass) || []; + const deprecationMessage: RuntimeFunctionProps["deprecationMessage"] = Reflect.getMetadata('hercules:deprecation_message', klass) || []; + const alias: RuntimeFunctionProps["alias"] = Reflect.getMetadata('hercules:alias', klass) || []; + const documentation: RuntimeFunctionProps["documentation"] = Reflect.getMetadata('hercules:documentation', klass) || []; + const signature: RuntimeFunctionProps["signature"] = Reflect.getMetadata('hercules:signature', klass); + const linkedDataTypes: RuntimeFunctionProps["linkedDataTypes"] = Reflect.getMetadata('hercules:linked_data_type_identifiers', klass) || []; + const displayIcon: RuntimeFunctionProps["displayIcon"] = Reflect.getMetadata('hercules:display_icon', klass) || ""; + const throwsError: RuntimeFunctionProps["throwsError"] = Reflect.getMetadata('hercules:throws_error', klass) || false; + + if (!identifier) throw new Error(`Runtime function class ${klass.name} is missing an identifier. Add @Identifier("your_identifier") to the class.`); + if (!signature) throw new Error(`Runtime function class ${klass.name} is missing a signature. Add @Signature("(param1: TYPE_1): RETURN_TYPE") to the class.`); + + const instance = new klass(); + const handler = instance.run.bind(instance) as (...args: (PlainValue | undefined)[]) => Promise | PlainValue; + + return { + runtimeName: identifier, + signature, + throwsError, + name, + description, + documentation, + deprecationMessage, + displayMessage, + alias, + linkedDataTypes, + displayIcon: displayIcon || "tabler:note", + parameters: runtimeParameters.map(param => ({ + ...param, + name: param.name || [], + description: param.description || [], + documentation: param.documentation || [], + hidden: param.hidden || false, + optional: param.optional || false, + })), + handler, + }; +}; diff --git a/ts/src/models/datatype.model.ts b/ts/src/models/datatype.model.ts new file mode 100644 index 0000000..70cd6f8 --- /dev/null +++ b/ts/src/models/datatype.model.ts @@ -0,0 +1,17 @@ +import {DefinitionDataTypeRule} from "@code0-tech/tucana/shared"; +import {Translation} from "../types"; + +export interface DataTypeProps { + identifier: string, + name?: Translation[], + displayMessage?: Translation[], + alias?: Translation[], + rules?: DefinitionDataTypeRule[], + genericKeys?: string[], + type: string, + linkedDataTypes?: string[], +} + +export interface DataTypeRunnable {} + +export type DataTypeClass = new () => DataTypeRunnable; diff --git a/ts/src/models/event.model.ts b/ts/src/models/event.model.ts new file mode 100644 index 0000000..fcbb4d3 --- /dev/null +++ b/ts/src/models/event.model.ts @@ -0,0 +1,31 @@ +import {PlainValue} from "@code0-tech/tucana/helpers"; +import {Translation} from "../types"; +import {FlowTypeSetting_UniquenessScope} from "@code0-tech/tucana/shared"; +import {RuntimeEventClass} from "./runtime_event.model"; + +export interface EventSettingProps { + identifier: string, + unique?: FlowTypeSetting_UniquenessScope, + linkedDataTypeIdentifiers?: string[], + defaultValue?: PlainValue, + name?: Translation[], + description?: Translation[], + optional?: boolean, + hidden?: boolean, +} + +export interface EventModel { + identifier: string, + settings?: EventSettingProps[], + signature: string, + linkedDataTypes?: string[], + editable?: boolean, + name?: Translation[], + description?: Translation[], + documentation?: Translation[], + displayMessage?: Translation[], + alias?: Translation[], + displayIcon?: string, + runtimeIdentifier?: string, +} +export type EventClass = new () => InstanceType; diff --git a/ts/src/models/function.model.ts b/ts/src/models/function.model.ts new file mode 100644 index 0000000..c7fde99 --- /dev/null +++ b/ts/src/models/function.model.ts @@ -0,0 +1,32 @@ +import {Translation} from "../types"; +import {PlainValue} from "@code0-tech/tucana/helpers"; +import {RuntimeFunctionClass} from "./runtime_function.model"; + +export interface FunctionParameterProps { + runtimeName: string, + defaultValue?: PlainValue, + name?: Translation[], + description?: Translation[], + documentation?: Translation[], + hidden?: boolean, + optional?: boolean, + runtimeDefinitionName?: string, +} + +export interface FunctionProps { + runtimeDefinitionName: string, + runtimeName: string, + parameters?: FunctionParameterProps[], + signature: string, + throwsError?: boolean, + name?: Translation[], + description?: Translation[], + documentation?: Translation[], + deprecationMessage?: Translation[], + displayMessage?: Translation[], + alias?: Translation[], + linkedDataTypes?: string[], + displayIcon?: string, +} + +export type FunctionClass = new () => InstanceType; diff --git a/ts/src/models/runtime_event.model.ts b/ts/src/models/runtime_event.model.ts new file mode 100644 index 0000000..be11d4d --- /dev/null +++ b/ts/src/models/runtime_event.model.ts @@ -0,0 +1,20 @@ +import {Translation} from "../types"; +import {EventSettingProps} from "./event.model"; + +export interface RuntimeEventRunnable {} + +export interface RuntimeEventProps { + identifier: string, + settings?: EventSettingProps[], + signature: string, + linkedDataTypes?: string[], + editable?: boolean, + name?: Translation[], + description?: Translation[], + documentation?: Translation[], + displayMessage?: Translation[], + alias?: Translation[], + displayIcon?: string, +} + +export type RuntimeEventClass = new () => RuntimeEventRunnable; diff --git a/ts/src/models/runtime_function.model.ts b/ts/src/models/runtime_function.model.ts new file mode 100644 index 0000000..aed60ea --- /dev/null +++ b/ts/src/models/runtime_function.model.ts @@ -0,0 +1,26 @@ +import {PlainValue} from "@code0-tech/tucana/helpers"; +import {Translation} from "../types"; +import {FunctionParameterProps} from "./function.model"; + +export interface RuntimeFunctionProps { + runtimeName: string, + parameters?: FunctionParameterProps[], + signature: string, + throwsError?: boolean, + name?: Translation[], + description?: Translation[], + documentation?: Translation[], + deprecationMessage?: Translation[], + displayMessage?: Translation[], + alias?: Translation[], + linkedDataTypes?: string[], + displayIcon?: string, + handler: (...args: (PlainValue | undefined)[]) => Promise | PlainValue, +} + +export interface RuntimeFunctionRunnable { + run(...args: (PlainValue | undefined)[]): Promise | PlainValue; +} + +export type RuntimeFunctionClass = + new () => T; diff --git a/ts/src/types.ts b/ts/src/types.ts index 7215e86..2f2453f 100644 --- a/ts/src/types.ts +++ b/ts/src/types.ts @@ -1,157 +1,38 @@ -import {GrpcOptions, GrpcTransport} from "@protobuf-ts/grpc-transport"; -import {DuplexStreamingCall} from "@protobuf-ts/runtime-rpc"; -import { - ActionConfigurationDefinition, ActionProjectConfiguration, - DefinitionDataType, - DefinitionDataTypeRule, FlowType, - FlowTypeSetting_UniquenessScope, FunctionDefinition, - RuntimeFunctionDefinition, - Translation -} from "@code0-tech/tucana/shared"; +import {FlowTypeSetting_UniquenessScope, RuntimeFlowTypeSetting_UniquenessScope} from "@code0-tech/tucana/shared"; import {PlainValue} from "@code0-tech/tucana/helpers"; -import {ActionTransferServiceClient, TransferRequest, TransferResponse} from "@code0-tech/tucana/aquila"; +import 'reflect-metadata'; +export {FlowTypeSetting_UniquenessScope, RuntimeFlowTypeSetting_UniquenessScope}; -export interface HerculesFunctionContext { - projectId: number | bigint, - executionId: string, - matchedConfig: HerculesActionProjectConfiguration -} - -export interface HerculesDataType { - identifier: string, - name?: Translation[], - displayMessage?: Translation[], - alias?: Translation[], - rules?: DefinitionDataTypeRule[], - genericKeys?: string[], - type: string, - linkedDataTypes?: string[], - // Will default to sdk version - version?: string -} - -export interface HerculesFlowTypeSetting { - identifier: string, - unique?: FlowTypeSetting_UniquenessScope, - linkedDataTypeIdentifiers?: string[], - defaultValue?: PlainValue, - name?: Translation[], - description?: Translation[], -} - -export interface HerculesFlowType { - identifier: string, - settings?: HerculesFlowTypeSetting[], - signature: string, - linkedDataTypes?: string[], - editable: boolean, - name?: Translation[], - description?: Translation[], - documentation?: Translation[], - displayMessage?: Translation[], - alias?: Translation[], - version?: string, - displayIcon?: string, -} - - -export interface HerculesRuntimeFunctionDefinition { - runtimeName: string, - parameters?: { - runtimeName: string, - defaultValue?: PlainValue, - name?: Translation[], - description?: Translation[], - documentation?: Translation[], - hidden?: boolean, - optional?: boolean - }[], - signature: string, - throwsError?: boolean, - name?: Translation[], - description?: Translation[], - documentation?: Translation[], - deprecationMessage?: Translation[], - displayMessage?: Translation[], - alias?: Translation[], - linkedDataTypes?: string[], - version?: string, - displayIcon?: string, +export interface Translation { + code: "en-US" | "de-DE" | string, + content: string } -export interface HerculesRegisterFunctionDefinition { - runtimeDefinitionName: string, - runtimeName: string, - parameters?: { - runtimeName: string, - defaultValue?: PlainValue, - name?: Translation[], - description?: Translation[], - documentation?: Translation[], - hidden?: boolean, - optional?: boolean, - runtimeDefinitionName?: string - }[], - signature: string, - throwsError?: boolean, - name?: Translation[], - description?: Translation[], - documentation?: Translation[], - deprecationMessage?: Translation[], - displayMessage?: Translation[], - alias?: Translation[], - linkedDataTypes?: string[], - version?: string, - displayIcon?: string, +export interface FunctionContext { + projectId: number | bigint, + executionId: string, + matchedConfig: ProjectConfiguration } -export interface HerculesActionProjectConfiguration { +export interface ProjectConfiguration { projectId: number | bigint, - configValues: { - identifier: string, - value: PlainValue - }[], + configValues: { identifier: string, value: PlainValue }[], findConfig: (identifier: string) => PlainValue | undefined } -export interface HerculesActionConfigurationDefinition { +export interface ConfigurationDefinition { name?: Translation[], description?: Translation[], type: string, + hidden?: boolean, + optional?: boolean, linkedDataTypes?: string[], defaultValue?: PlainValue, identifier: string, } -export type HerculesRegisterRuntimeFunctionParameter = { - definition: HerculesRuntimeFunctionDefinition, - handler: (...args: any[]) => Promise | PlainValue, -} - -export interface ActionSdk { - config: { - authToken: string, - aquilaUrl: string, - actionId: string, - version: string, - }, - fullyConnected: () => boolean, // indicates whether the SDK is fully connected and ready to send/receive messages. Becomes true after connect() resolves successfully - connect: (options?: GrpcOptions) => Promise, // after registering the functions and events - onError: (handler: (error: Error) => void) => void, - - getProjectActionConfigurations(): HerculesActionProjectConfiguration[], - - registerConfigDefinitions: (...actionConfigurations: Array) => Promise, - registerDataTypes: (...dataType: Array) => Promise, - registerFlowTypes: (...flowTypes: Array) => Promise, - registerRuntimeFunctionDefinitionsAndFunctionDefinitions: (...runtimeFunctionDefinitions: Array) => Promise, - registerFunctionDefinitions: (...functionDefinitions: Array) => Promise, - registerRuntimeFunctionDefinitions: (...runtimeFunctionDefinitions: Array) => Promise, - dispatchEvent: (eventType: string, projectId: number | bigint, payload: PlainValue) => Promise, -} - -export class RuntimeErrorException extends Error { +export class RuntimeError extends Error { code: string description?: string @@ -162,27 +43,3 @@ export class RuntimeErrorException extends Error { this.description = description } } - -export interface RegisteredFunction { - identifier: string, - definition: FunctionDefinition -} - -export interface RegisteredRuntimeFunction { - identifier: string, - definition: RuntimeFunctionDefinition, - handler: (...args: any[]) => Promise | PlainValue, -} - -export interface SdkState { - functions: RegisteredFunction[], - runtimeFunctions: RegisteredRuntimeFunction[], - dataTypes: DefinitionDataType[], - flowTypes: FlowType[], - configurationDefinitions: ActionConfigurationDefinition[], - projectConfigurations: ActionProjectConfiguration[], - transport: GrpcTransport, - client: ActionTransferServiceClient, - stream: DuplexStreamingCall | undefined, - fullyConnected: boolean, -} \ No newline at end of file diff --git a/ts/src/index.test.ts b/ts/test/index.test.ts similarity index 100% rename from ts/src/index.test.ts rename to ts/test/index.test.ts diff --git a/ts/tsconfig.json b/ts/tsconfig.json index afd60b6..4a59bc5 100644 --- a/ts/tsconfig.json +++ b/ts/tsconfig.json @@ -1,12 +1,21 @@ { "compilerOptions": { "esModuleInterop": true, - "module": "commonjs", "moduleResolution": "bundler", + "module": "commonjs", "target": "es2020", - "lib": ["es2020", "dom"], + "lib": ["ESNext", "dom"], "strict": true, - "skipLibCheck": true + "skipLibCheck": true, + "rootDir": "src", + "baseUrl": "src/" }, - "include": ["src/**/*"] + "exclude": [ + "node_modules", + "dist", + "examples" + ], + "types": [ + "typePatches" + ] } \ No newline at end of file diff --git a/ts/vite.config.ts b/ts/vite.config.ts index e0a8c6b..6dd196c 100644 --- a/ts/vite.config.ts +++ b/ts/vite.config.ts @@ -4,17 +4,24 @@ import { resolve } from 'path'; export default defineConfig({ build: { - target: "node18", - ssr: true, lib: { entry: resolve(__dirname, 'src/index.ts'), - name: 'hercules', - fileName: 'hercules', + name: 'triangulum', + fileName: (format) => `hercules.${format}.js`, formats: ['es', 'cjs'] }, rollupOptions: { - external: (id) => - ['fs', 'path', 'typescript'].includes(id) || id.startsWith('node:') + external: [ + 'typescript', + '@code0-tech/tucana', + 'path', + 'fs' + ], + output: { + globals: { + typescript: 'ts' + } + } } }, plugins: [ @@ -28,4 +35,5 @@ export default defineConfig({ } }) ] -}); \ No newline at end of file +}); + diff --git a/ts/vitest.config.ts b/ts/vitest.config.ts index 39e458a..2e7a0ac 100644 --- a/ts/vitest.config.ts +++ b/ts/vitest.config.ts @@ -2,6 +2,7 @@ import { defineConfig } from 'vitest/config' export default defineConfig({ test: { - exclude: ['**/dist/**', "node_modules"], + include: ['src/**/*.test.ts'], + exclude: ['**/dist/**', '**/node_modules/**', '**/examples/**'], }, })