From 2fd3fb0d0931e50ff2acac7330dc82b3a9b3f479 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2026 19:49:49 +0000 Subject: [PATCH 01/11] Update dependency @code0-tech/tucana to v0.0.67 --- entrypoint/package-lock.json | 22 +++++++++++----------- entrypoint/package.json | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/entrypoint/package-lock.json b/entrypoint/package-lock.json index 3ef2b25..4e8560b 100644 --- a/entrypoint/package-lock.json +++ b/entrypoint/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.0", "dependencies": { "@code0-tech/triangulum": "file:../", - "@code0-tech/tucana": "0.0.62", + "@code0-tech/tucana": "0.0.67", "@protobuf-ts/runtime": "^2.11.1" }, "devDependencies": { @@ -20,18 +20,18 @@ "name": "@code0-tech/triangulum", "version": "0.1.0", "devDependencies": { - "@code0-tech/sagittarius-graphql-types": "0.0.0-experimental-2385560645-52d09772ef7058a833cf32edc393ce95668b8404", - "@types/node": "^25.3.2", + "@code0-tech/sagittarius-graphql-types": "0.0.0-experimental-2430052572-f89aa9d01636e56a17463920775d073b09dd132b", + "@types/node": "^25.5.0", "@typescript/vfs": "^1.6.4", - "typescript": "^5.9.3", - "vite": "^7.3.1", + "typescript": "^6.0.2", + "vite": "^8.0.3", "vite-plugin-dts": "^4.5.4", - "vitest": "^4.0.18" + "vitest": "^4.1.2" }, "peerDependencies": { - "@code0-tech/sagittarius-graphql-types": "0.0.0-experimental-2385560645-52d09772ef7058a833cf32edc393ce95668b8404", + "@code0-tech/sagittarius-graphql-types": "0.0.0-experimental-2430052572-f89aa9d01636e56a17463920775d073b09dd132b", "@typescript/vfs": "^1.6.4", - "typescript": "^5.9.3" + "typescript": "^5.9.3 || ^6.0.2" } }, "node_modules/@code0-tech/triangulum": { @@ -39,9 +39,9 @@ "link": true }, "node_modules/@code0-tech/tucana": { - "version": "0.0.62", - "resolved": "https://registry.npmjs.org/@code0-tech/tucana/-/tucana-0.0.62.tgz", - "integrity": "sha512-OLdGT0FSGxzlaGxVKnnvioaDovNZf1wdwofCoSx8nsT8fe7z24/IQLKSOkEYEF9ds3F8JXim7fiB+k3T2qky8Q==", + "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/@protobuf-ts/runtime": { diff --git a/entrypoint/package.json b/entrypoint/package.json index 3f37dcc..7901a46 100644 --- a/entrypoint/package.json +++ b/entrypoint/package.json @@ -4,7 +4,7 @@ "private": true, "dependencies": { "@code0-tech/triangulum": "file:../", - "@code0-tech/tucana": "0.0.62", + "@code0-tech/tucana": "0.0.67", "@protobuf-ts/runtime": "^2.11.1" }, "devDependencies": { From 7c64f284d947d429b9ed81565b98d2ae130f36de Mon Sep 17 00:00:00 2001 From: Niklas van Schrick Date: Sun, 5 Apr 2026 22:46:55 +0200 Subject: [PATCH 02/11] Update ruby tucana to 0.0.67 and switch to function definitions --- entrypoint/mapper.ts | 17 +++++++++-------- entrypoint/readSingle.ts | 6 +++--- gem/Gemfile.lock | 4 ++-- gem/README.md | 8 ++++---- gem/lib/triangulum/validation.rb | 6 +++--- gem/spec/support/protobuf_factories.rb | 8 ++++---- gem/triangulum.gemspec | 2 +- 7 files changed, 26 insertions(+), 25 deletions(-) diff --git a/entrypoint/mapper.ts b/entrypoint/mapper.ts index 45a5ee8..c1766fd 100644 --- a/entrypoint/mapper.ts +++ b/entrypoint/mapper.ts @@ -3,15 +3,17 @@ import { DataType, Flow, FunctionDefinition, - LiteralValue, NodeFunction, NodeParameter, - NodeParameterValue, ParameterDefinition, + NodeParameterValue, + ParameterDefinition, } from "@code0-tech/sagittarius-graphql-types"; import { DefinitionDataType, NodeFunction as TucanaNodeFunction, - NodeParameter as TucanaNodeParameter, RuntimeFunctionDefinition, RuntimeParameterDefinition, + NodeParameter as TucanaNodeParameter, + FunctionDefinition as TucanaFunctionDefinition, + ParameterDefinition as TucanaParameterDefinition, ValidationFlow, } from "@code0-tech/tucana/shared"; import {toAllowedValue} from "@code0-tech/tucana/helpers"; @@ -38,8 +40,7 @@ function mapFlow(flow: ValidationFlow): Flow { return { __typename: "Flow", id: gid('Flow', flow.flowId) as Flow['id'], - inputType: flow.inputType, - returnType: flow.returnType, + signature: flow.signature, startingNodeId: gid('NodeFunction', flow.startingNodeId) as NodeFunction['id'], nodes: { nodes: flow.nodeFunctions.map(mapNodeFunction) @@ -101,17 +102,17 @@ function mapNodeParameter(nodeParameter: TucanaNodeParameter): NodeParameter { } } -function mapFunctionDefinition(functionDefinition: RuntimeFunctionDefinition): FunctionDefinition { +function mapFunctionDefinition(functionDefinition: TucanaFunctionDefinition): FunctionDefinition { return { identifier: functionDefinition.runtimeName, signature: functionDefinition.signature, parameterDefinitions: { - nodes: functionDefinition.runtimeParameterDefinitions.map(mapParameterDefinition) + nodes: functionDefinition.parameterDefinitions.map(mapParameterDefinition) } } } -function mapParameterDefinition(parameterDefinition: RuntimeParameterDefinition): ParameterDefinition { +function mapParameterDefinition(parameterDefinition: TucanaParameterDefinition): ParameterDefinition { return { identifier: parameterDefinition.runtimeName, } diff --git a/entrypoint/readSingle.ts b/entrypoint/readSingle.ts index 9eeb867..1a331a0 100644 --- a/entrypoint/readSingle.ts +++ b/entrypoint/readSingle.ts @@ -1,12 +1,12 @@ import { DefinitionDataType, - RuntimeFunctionDefinition, + FunctionDefinition, ValidationFlow } from "@code0-tech/tucana/shared"; export type SingleValidationInputData = { flow?: ValidationFlow, - functions: RuntimeFunctionDefinition[], + functions: FunctionDefinition[], dataTypes: DefinitionDataType[] }; @@ -28,7 +28,7 @@ export async function readSingleValidation(input: AsyncIterable) { if(parsingState === 0) { data.flow = ValidationFlow.fromBinary(message); } else if(parsingState === 1) { - data.functions.push(RuntimeFunctionDefinition.fromBinary(message)); + data.functions.push(FunctionDefinition.fromBinary(message)); } else if(parsingState === 2) { data.dataTypes.push(DefinitionDataType.fromBinary(message)); } diff --git a/gem/Gemfile.lock b/gem/Gemfile.lock index c23f0b4..701d864 100644 --- a/gem/Gemfile.lock +++ b/gem/Gemfile.lock @@ -5,7 +5,7 @@ PATH base64 (~> 0.3) json (~> 2.19) open3 (~> 0.2) - tucana (~> 0.0, >= 0.0.62) + tucana (~> 0.0, >= 0.0.67) GEM remote: https://rubygems.org/ @@ -101,7 +101,7 @@ GEM rubyzip (2.4.1) stringio (3.2.0) tsort (0.2.0) - tucana (0.0.62) + tucana (0.0.67) grpc (~> 1.64) unicode-display_width (3.2.0) unicode-emoji (~> 4.1) diff --git a/gem/README.md b/gem/README.md index ac29362..f8116f0 100644 --- a/gem/README.md +++ b/gem/README.md @@ -28,11 +28,11 @@ bundle lock --add-platform x86_64-linux-gnu ## Usage ```ruby -result = Triangulum::Validation.new(flow, runtime_function_definitions, data_types).validate +result = Triangulum::Validation.new(flow, function_definitions, data_types).validate -result.valid? # => true / false -result.return_type # => "void" -result.diagnostics # => [Triangulum::Validation::Diagnostic, ...] +result.valid? # => true / false +result.return_type # => "void" +result.diagnostics # => [Triangulum::Validation::Diagnostic, ...] ``` The arguments are [Tucana](https://github.com/code0-tech/tucana) protobuf objects: diff --git a/gem/lib/triangulum/validation.rb b/gem/lib/triangulum/validation.rb index 2eec868..c7b417f 100644 --- a/gem/lib/triangulum/validation.rb +++ b/gem/lib/triangulum/validation.rb @@ -21,11 +21,11 @@ class BunNotFound < Triangulum::Error IS_RUBY_PLATFORM_GEM = Dir.glob(File.expand_path('../../exe/*/bun', __dir__)).empty? - attr_reader :flow, :runtime_function_definitions, :data_types + attr_reader :flow, :function_definitions, :data_types def initialize(flow, runtime_function_definitions, data_types) @flow = flow - @runtime_function_definitions = runtime_function_definitions + @function_definitions = runtime_function_definitions @data_types = data_types end @@ -56,7 +56,7 @@ def serialize_input input << Base64.strict_encode64(flow.to_proto) input << '' - runtime_function_definitions.each do |rfd| + function_definitions.each do |rfd| input << Base64.strict_encode64(rfd.to_proto) end diff --git a/gem/spec/support/protobuf_factories.rb b/gem/spec/support/protobuf_factories.rb index 808a51b..cbe3ac3 100644 --- a/gem/spec/support/protobuf_factories.rb +++ b/gem/spec/support/protobuf_factories.rb @@ -61,19 +61,19 @@ def default_data_types def default_functions [ - Tucana::Shared::RuntimeFunctionDefinition.new( + Tucana::Shared::FunctionDefinition.new( runtime_name: 'std::math::add', signature: '(a: NUMBER, b: NUMBER): NUMBER' ), - Tucana::Shared::RuntimeFunctionDefinition.new( + Tucana::Shared::FunctionDefinition.new( runtime_name: 'std::list::at', signature: '(list: LIST, index: NUMBER): R' ), - Tucana::Shared::RuntimeFunctionDefinition.new( + Tucana::Shared::FunctionDefinition.new( runtime_name: 'std::control::for_each', signature: '(list: LIST, consumer: CONSUMER): void' ), - Tucana::Shared::RuntimeFunctionDefinition.new( + Tucana::Shared::FunctionDefinition.new( runtime_name: 'std::control::return', signature: '(value: R): R' ) diff --git a/gem/triangulum.gemspec b/gem/triangulum.gemspec index 2db7f51..fd63697 100644 --- a/gem/triangulum.gemspec +++ b/gem/triangulum.gemspec @@ -24,7 +24,7 @@ Gem::Specification.new do |spec| spec.add_dependency 'base64', '~> 0.3' spec.add_dependency 'json', '~> 2.19' spec.add_dependency 'open3', '~> 0.2' - spec.add_dependency 'tucana', '~> 0.0', '>= 0.0.62' + spec.add_dependency 'tucana', '~> 0.0', '>= 0.0.67' spec.add_development_dependency 'irb', '~> 1.17' spec.add_development_dependency 'rake', '~> 13.0' From 0573bd74c78c4211572e913c2e267b2cb44cddd2 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sun, 5 Apr 2026 22:49:57 +0200 Subject: [PATCH 03/11] feat: update JSON serialization for LiteralValue to handle bigint values --- src/extraction/getTypeFromValue.ts | 6 +++++- src/utils.ts | 14 ++++++++++++-- src/validation/getValueValidation.ts | 8 ++++++-- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/extraction/getTypeFromValue.ts b/src/extraction/getTypeFromValue.ts index 0402ec1..be65e00 100644 --- a/src/extraction/getTypeFromValue.ts +++ b/src/extraction/getTypeFromValue.ts @@ -9,8 +9,12 @@ export const getTypeFromValue = ( value?: LiteralValue | null, dataTypes?: DataType[] ): string => { + + // 1. Serialize value to a JSON string for embedding in source code. - const literal = JSON.stringify(value?.value); + const literal = JSON.stringify(value?.value, (key, val) => + typeof val === 'bigint' ? val.toString() : val + ) if (!literal) return "any" diff --git a/src/utils.ts b/src/utils.ts index 6322497..1cd4220 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -125,7 +125,12 @@ export function generateFlowSourceCode( }); return `/* @pos ${nodeId} ${paramIdx} */ ${refCode}`; } - if (val.__typename === "LiteralValue") return `/* @pos ${nodeId} ${paramIdx} */ ${JSON.stringify(val.value)}`; + if (val.__typename === "LiteralValue") { + const jsonString = JSON.stringify(val?.value, (key, val) => + typeof val === 'bigint' ? val.toString() : val + ) + return `/* @pos ${nodeId} ${paramIdx} */ ${jsonString}`; + } if (val.__typename === "NodeFunctionIdWrapper") { const wrapper = val as NodeFunctionIdWrapper; return generateNodeCall(wrapper.id!, nodeId, paramIdx); @@ -172,7 +177,12 @@ export function generateFlowSourceCode( }); return `/* @pos ${nodeId} ${index} */ ${refCode}`; } - if (val.__typename === "LiteralValue") return `/* @pos ${nodeId} ${index} */ ${JSON.stringify(val.value)}`; + if (val.__typename === "LiteralValue") { + const jsonString = JSON.stringify(val?.value, (key, val) => + typeof val === 'bigint' ? val.toString() : val + ) + return `/* @pos ${nodeId} ${index} */ ${jsonString}`; + } if (val.__typename === "NodeFunctionIdWrapper") { const wrapper = val as NodeFunctionIdWrapper; diff --git a/src/validation/getValueValidation.ts b/src/validation/getValueValidation.ts index aba72b6..bf48281 100644 --- a/src/validation/getValueValidation.ts +++ b/src/validation/getValueValidation.ts @@ -2,17 +2,21 @@ import ts from "typescript"; import {DataType, LiteralValue} from "@code0-tech/sagittarius-graphql-types"; import {createCompilerHost, getSharedTypeDeclarations, ValidationResult} from "../utils"; + export const getValueValidation = ( type?: string, value?: LiteralValue, dataTypes?: DataType[] ): ValidationResult => { - const valueAsCode = JSON.stringify(value?.value); + + const jsonString = JSON.stringify(value?.value, (key, val) => + typeof val === 'bigint' ? val.toString() : val + ) // 1. Construct the source code for validation. const sourceCode = ` ${getSharedTypeDeclarations(dataTypes)} - const testValue: ${type} = ${valueAsCode}; + const testValue: ${type} = ${jsonString}; `; const fileName = "index.ts"; From fb054d6d604e8e3f468c490732bc8f23f7b5b72c Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sun, 5 Apr 2026 23:05:35 +0200 Subject: [PATCH 04/11] feat: add lossless-json dependency and update package configurations --- package-lock.json | 9 +++++++++ package.json | 11 +++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 670f696..04870a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,9 @@ "": { "name": "@code0-tech/triangulum", "version": "0.1.0", + "dependencies": { + "lossless-json": "^4.3.0" + }, "devDependencies": { "@code0-tech/sagittarius-graphql-types": "0.0.0-experimental-2430052572-f89aa9d01636e56a17463920775d073b09dd132b", "@types/node": "^25.5.0", @@ -2457,6 +2460,12 @@ "dev": true, "license": "MIT" }, + "node_modules/lossless-json": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lossless-json/-/lossless-json-4.3.0.tgz", + "integrity": "sha512-ToxOC+SsduRmdSuoLZLYAr5zy1Qu7l5XhmPWM3zefCZ5IcrzW/h108qbJUKfOlDlhvhjUK84+8PSVX0kxnit0g==", + "license": "MIT" + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", diff --git a/package.json b/package.json index 421ad79..e2a546d 100644 --- a/package.json +++ b/package.json @@ -25,15 +25,18 @@ "devDependencies": { "@code0-tech/sagittarius-graphql-types": "0.0.0-experimental-2430052572-f89aa9d01636e56a17463920775d073b09dd132b", "@types/node": "^25.5.0", + "@typescript/vfs": "^1.6.4", "typescript": "^6.0.2", "vite": "^8.0.3", "vite-plugin-dts": "^4.5.4", - "vitest": "^4.1.2", - "@typescript/vfs": "^1.6.4" + "vitest": "^4.1.2" }, "peerDependencies": { "@code0-tech/sagittarius-graphql-types": "0.0.0-experimental-2430052572-f89aa9d01636e56a17463920775d073b09dd132b", - "typescript": "^5.9.3 || ^6.0.2", - "@typescript/vfs": "^1.6.4" + "@typescript/vfs": "^1.6.4", + "typescript": "^5.9.3 || ^6.0.2" + }, + "dependencies": { + "lossless-json": "^4.3.0" } } From 2ddcfada05adf810a5601e8d81fba6272f5e4a65 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sun, 5 Apr 2026 23:05:41 +0200 Subject: [PATCH 05/11] test: remove console.log from valueFromType test --- test/valueFromType.test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/valueFromType.test.ts b/test/valueFromType.test.ts index fbcc220..48f77b0 100644 --- a/test/valueFromType.test.ts +++ b/test/valueFromType.test.ts @@ -79,8 +79,6 @@ describe('getValueFromType', () => { `; const result = getValueFromType(type, DATA_TYPES); - console.log(result) - expect(result.value).toEqual({ body: { userNames: [''] From 48e49eb4e8d9288e92ef78a4c56cb64bc7d6a2c3 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sun, 5 Apr 2026 23:05:46 +0200 Subject: [PATCH 06/11] test: add validation for BigInt values in valueValidation tests --- test/valueValidation.test.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/valueValidation.test.ts b/test/valueValidation.test.ts index e6c3975..23845bd 100644 --- a/test/valueValidation.test.ts +++ b/test/valueValidation.test.ts @@ -49,6 +49,10 @@ describe('getValueValidation', () => { __typename: 'LiteralValue', value: 42 }, DATA_TYPES).isValid).toBe(true); + expect(getValueValidation('NUMBER', { + __typename: 'LiteralValue', + value: BigInt(42) + }, DATA_TYPES).isValid).toBe(true); expect(getValueValidation('NUMBER', { __typename: 'LiteralValue', value: 'not a number' From ba5a5889492b05b35102959581cffe92f3c9cd77 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sun, 5 Apr 2026 23:05:52 +0200 Subject: [PATCH 07/11] refactor: replace JSON.stringify with lossless-json.stringify for BigInt handling --- src/extraction/getTypeFromValue.ts | 5 ++--- src/utils.ts | 5 ++--- src/validation/getValueValidation.ts | 5 ++--- test/getReferenceSuggestions.test.ts | 2 -- 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/extraction/getTypeFromValue.ts b/src/extraction/getTypeFromValue.ts index be65e00..7baa159 100644 --- a/src/extraction/getTypeFromValue.ts +++ b/src/extraction/getTypeFromValue.ts @@ -1,6 +1,7 @@ import ts from "typescript"; import {createCompilerHost, getSharedTypeDeclarations} from "../utils"; import {DataType, LiteralValue} from "@code0-tech/sagittarius-graphql-types"; +import {stringify} from "lossless-json"; /** * Uses the TypeScript compiler to generate a precise type string from any runtime value. @@ -12,9 +13,7 @@ export const getTypeFromValue = ( // 1. Serialize value to a JSON string for embedding in source code. - const literal = JSON.stringify(value?.value, (key, val) => - typeof val === 'bigint' ? val.toString() : val - ) + const literal = stringify(value?.value) if (!literal) return "any" diff --git a/src/utils.ts b/src/utils.ts index 1cd4220..8f1634e 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -12,6 +12,7 @@ import ts from "typescript"; import {createSystem, createVirtualTypeScriptEnvironment, VirtualTypeScriptEnvironment} from "@typescript/vfs" import {DataTypeVariant, getTypeVariant} from "./extraction/getTypeVariant"; import {getTypesFromFunction} from "./extraction/getTypesFromFunction"; +import {stringify} from "lossless-json"; /** * Result of a node or flow validation. @@ -126,9 +127,7 @@ export function generateFlowSourceCode( return `/* @pos ${nodeId} ${paramIdx} */ ${refCode}`; } if (val.__typename === "LiteralValue") { - const jsonString = JSON.stringify(val?.value, (key, val) => - typeof val === 'bigint' ? val.toString() : val - ) + const jsonString = stringify(val?.value) return `/* @pos ${nodeId} ${paramIdx} */ ${jsonString}`; } if (val.__typename === "NodeFunctionIdWrapper") { diff --git a/src/validation/getValueValidation.ts b/src/validation/getValueValidation.ts index bf48281..21ecddc 100644 --- a/src/validation/getValueValidation.ts +++ b/src/validation/getValueValidation.ts @@ -1,6 +1,7 @@ import ts from "typescript"; import {DataType, LiteralValue} from "@code0-tech/sagittarius-graphql-types"; import {createCompilerHost, getSharedTypeDeclarations, ValidationResult} from "../utils"; +import { stringify } from 'lossless-json' export const getValueValidation = ( @@ -9,9 +10,7 @@ export const getValueValidation = ( dataTypes?: DataType[] ): ValidationResult => { - const jsonString = JSON.stringify(value?.value, (key, val) => - typeof val === 'bigint' ? val.toString() : val - ) + const jsonString = stringify(value?.value) // 1. Construct the source code for validation. const sourceCode = ` diff --git a/test/getReferenceSuggestions.test.ts b/test/getReferenceSuggestions.test.ts index 3a16782..4e30b75 100644 --- a/test/getReferenceSuggestions.test.ts +++ b/test/getReferenceSuggestions.test.ts @@ -125,8 +125,6 @@ describe('getReferenceSuggestions', () => { const suggestions = getReferenceSuggestions(flow, "gid://sagittarius/NodeFunction/4", 0, FUNCTION_SIGNATURES, DATA_TYPES); - console.log(suggestions) - //expect(suggestions.some(s => !s.nodeFunctionId)).toBe(true); }); From e9220a75f1a317de5cb542bb521f320b5f6e03e6 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sun, 5 Apr 2026 23:06:22 +0200 Subject: [PATCH 08/11] feat: add lossless-json to package dependencies --- package-lock.json | 6 +++--- package.json | 7 +++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 04870a5..a1af8c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,13 +7,11 @@ "": { "name": "@code0-tech/triangulum", "version": "0.1.0", - "dependencies": { - "lossless-json": "^4.3.0" - }, "devDependencies": { "@code0-tech/sagittarius-graphql-types": "0.0.0-experimental-2430052572-f89aa9d01636e56a17463920775d073b09dd132b", "@types/node": "^25.5.0", "@typescript/vfs": "^1.6.4", + "lossless-json": "^4.3.0", "typescript": "^6.0.2", "vite": "^8.0.3", "vite-plugin-dts": "^4.5.4", @@ -22,6 +20,7 @@ "peerDependencies": { "@code0-tech/sagittarius-graphql-types": "0.0.0-experimental-2430052572-f89aa9d01636e56a17463920775d073b09dd132b", "@typescript/vfs": "^1.6.4", + "lossless-json": "^4.3.0", "typescript": "^5.9.3 || ^6.0.2" } }, @@ -2464,6 +2463,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/lossless-json/-/lossless-json-4.3.0.tgz", "integrity": "sha512-ToxOC+SsduRmdSuoLZLYAr5zy1Qu7l5XhmPWM3zefCZ5IcrzW/h108qbJUKfOlDlhvhjUK84+8PSVX0kxnit0g==", + "dev": true, "license": "MIT" }, "node_modules/lru-cache": { diff --git a/package.json b/package.json index e2a546d..dc3c027 100644 --- a/package.json +++ b/package.json @@ -29,14 +29,13 @@ "typescript": "^6.0.2", "vite": "^8.0.3", "vite-plugin-dts": "^4.5.4", - "vitest": "^4.1.2" + "vitest": "^4.1.2", + "lossless-json": "^4.3.0" }, "peerDependencies": { "@code0-tech/sagittarius-graphql-types": "0.0.0-experimental-2430052572-f89aa9d01636e56a17463920775d073b09dd132b", "@typescript/vfs": "^1.6.4", - "typescript": "^5.9.3 || ^6.0.2" - }, - "dependencies": { + "typescript": "^5.9.3 || ^6.0.2", "lossless-json": "^4.3.0" } } From 2804f61caddcbe86602c13628efcc8b6066ab475 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sun, 5 Apr 2026 23:22:35 +0200 Subject: [PATCH 09/11] refactor: replace JSON.stringify with lossless-json.stringify in utils.ts --- src/utils.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 8f1634e..143cfdf 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -177,9 +177,7 @@ export function generateFlowSourceCode( return `/* @pos ${nodeId} ${index} */ ${refCode}`; } if (val.__typename === "LiteralValue") { - const jsonString = JSON.stringify(val?.value, (key, val) => - typeof val === 'bigint' ? val.toString() : val - ) + const jsonString = stringify(val?.value) return `/* @pos ${nodeId} ${index} */ ${jsonString}`; } if (val.__typename === "NodeFunctionIdWrapper") { @@ -227,7 +225,7 @@ export function generateFlowSourceCode( if (p?.value?.__typename === "NodeFunctionIdWrapper" && p.value.id) subTreeIds.add(p.value.id); })); - const flowCode = flow ? `const flow_${sanitizeId(flow.id ?? "")} = flow(${flow.settings?.nodes?.map((setting, index) => `/* @pos undefined ${index} */ ${JSON.stringify(setting?.value)}`).join(", ") ?? ""});` : "" + const flowCode = flow ? `const flow_${sanitizeId(flow.id ?? "")} = flow(${flow.settings?.nodes?.map((setting, index) => `/* @pos undefined ${index} */ ${stringify(setting?.value)}`).join(", ") ?? ""});` : "" const executionCode = nodes .filter(n => n?.id && !nextNodeIds.has(n.id) && !subTreeIds.has(n.id)) From db6ae55dcf5bb6c558ed86be292c316f78a84e19 Mon Sep 17 00:00:00 2001 From: Niklas van Schrick Date: Sun, 5 Apr 2026 23:10:10 +0200 Subject: [PATCH 10/11] Aggregate rspec failures --- gem/spec/spec_helper.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gem/spec/spec_helper.rb b/gem/spec/spec_helper.rb index 31056e4..249edee 100644 --- a/gem/spec/spec_helper.rb +++ b/gem/spec/spec_helper.rb @@ -12,6 +12,10 @@ config.disable_monkey_patching! config.include ProtobufFactories + config.define_derived_metadata do |metadata| + metadata[:aggregate_failures] = true + end + config.expect_with :rspec do |c| c.syntax = :expect end From ed818b365d21e6741f00c7ac95d81af1e5ea4259 Mon Sep 17 00:00:00 2001 From: Niklas van Schrick Date: Sun, 5 Apr 2026 23:15:28 +0200 Subject: [PATCH 11/11] Add signature to test flow --- gem/spec/support/protobuf_factories.rb | 3 ++- gem/spec/triangulum/validation_spec.rb | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/gem/spec/support/protobuf_factories.rb b/gem/spec/support/protobuf_factories.rb index cbe3ac3..fa7f247 100644 --- a/gem/spec/support/protobuf_factories.rb +++ b/gem/spec/support/protobuf_factories.rb @@ -8,7 +8,8 @@ def build_flow(node_functions:, starting_node_id: 1) type: 'test', starting_node_id: starting_node_id, node_functions: node_functions, - project_slug: 'test' + project_slug: 'test', + signature: '(): void' ) end diff --git a/gem/spec/triangulum/validation_spec.rb b/gem/spec/triangulum/validation_spec.rb index 18155c8..1a02ef9 100644 --- a/gem/spec/triangulum/validation_spec.rb +++ b/gem/spec/triangulum/validation_spec.rb @@ -100,6 +100,7 @@ result = described_class.new(flow, functions, data_types).validate expect(result.valid?).to be true + expect(result.diagnostics).to be_empty end it 'returns diagnostics with node_id and parameter_index' do