@code0-tech/triangulum 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -0
- package/dist/src/extraction/getTypeFromValue.d.ts +5 -0
- package/dist/src/extraction/getTypeVariant.d.ts +11 -0
- package/dist/src/extraction/getTypesFromNode.d.ts +10 -0
- package/dist/src/extraction/getValueFromType.d.ts +6 -0
- package/dist/src/index.d.ts +10 -0
- package/dist/src/suggestion/getNodeSuggestions.d.ts +7 -0
- package/dist/src/suggestion/getReferenceSuggestions.d.ts +7 -0
- package/dist/src/suggestion/getValueSuggestions.d.ts +5 -0
- package/dist/src/utils.d.ts +56 -0
- package/dist/src/validation/getFlowValidation.d.ts +6 -0
- package/dist/src/validation/getNodeValidation.d.ts +6 -0
- package/dist/src/validation/getValueValidation.d.ts +10 -0
- package/dist/triangulum.cjs.js +68 -0
- package/dist/triangulum.es.js +584 -0
- package/package.json +42 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ExtendedDataType } from '../utils';
|
|
2
|
+
export declare enum DataTypeVariant {
|
|
3
|
+
PRIMITIVE = 0,
|
|
4
|
+
TYPE = 1,
|
|
5
|
+
ARRAY = 2,
|
|
6
|
+
OBJECT = 3
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Determines the variant of a given TypeScript type string using the TS compiler.
|
|
10
|
+
*/
|
|
11
|
+
export declare const getTypeVariant: (type: string, dataTypes: ExtendedDataType[]) => DataTypeVariant;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { NodeFunction } from '@code0-tech/sagittarius-graphql-types';
|
|
2
|
+
import { ExtendedDataType, ExtendedFunction } from '../utils';
|
|
3
|
+
export interface NodeTypes {
|
|
4
|
+
parameters: string[];
|
|
5
|
+
returnType: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Resolves the types of the parameters and the return type of a NodeFunction.
|
|
9
|
+
*/
|
|
10
|
+
export declare const getTypesFromNode: (node: NodeFunction, functions: ExtendedFunction[], dataTypes: ExtendedDataType[]) => NodeTypes;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { LiteralValue } from '@code0-tech/sagittarius-graphql-types';
|
|
2
|
+
import { ExtendedDataType } from '../utils';
|
|
3
|
+
/**
|
|
4
|
+
* Generates a sample LiteralValue from a TypeScript type string.
|
|
5
|
+
*/
|
|
6
|
+
export declare const getValueFromType: (type: string, dataTypes: ExtendedDataType[]) => LiteralValue;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './validation/getFlowValidation';
|
|
2
|
+
export * from './suggestion/getNodeSuggestions';
|
|
3
|
+
export * from './validation/getNodeValidation';
|
|
4
|
+
export * from './suggestion/getReferenceSuggestions';
|
|
5
|
+
export * from './extraction/getTypeFromValue';
|
|
6
|
+
export * from './extraction/getTypeVariant';
|
|
7
|
+
export * from './extraction/getValueFromType';
|
|
8
|
+
export * from './suggestion/getValueSuggestions';
|
|
9
|
+
export * from './validation/getValueValidation';
|
|
10
|
+
export * from './extraction/getTypesFromNode';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { NodeFunction } from '@code0-tech/sagittarius-graphql-types';
|
|
2
|
+
import { ExtendedFunction } from '../utils';
|
|
3
|
+
/**
|
|
4
|
+
* Suggests NodeFunctions based on a given type and a list of available FunctionDefinitions.
|
|
5
|
+
* Returns functions whose return type is compatible with the target type.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getNodeSuggestions(type: string, functions: ExtendedFunction[]): NodeFunction[];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Flow, NodeFunction, ReferenceValue } from '@code0-tech/sagittarius-graphql-types';
|
|
2
|
+
import { ExtendedDataType, ExtendedFunction } from '../utils';
|
|
3
|
+
/**
|
|
4
|
+
* Calculates all available reference suggestions for a specific target node in a flow
|
|
5
|
+
* and filters them by a required type.
|
|
6
|
+
*/
|
|
7
|
+
export declare const getReferenceSuggestions: (flow: Flow, nodeId: NodeFunction["id"], type: string, functions: ExtendedFunction[], dataTypes: ExtendedDataType[]) => ReferenceValue[];
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { DataType, Flow, FunctionDefinition, NodeFunction, NodeParameter, ReferencePath, ReferenceValue } from '@code0-tech/sagittarius-graphql-types';
|
|
2
|
+
import { default as ts } from 'typescript';
|
|
3
|
+
/**
|
|
4
|
+
* Result of a node or flow validation.
|
|
5
|
+
*/
|
|
6
|
+
export interface ValidationResult {
|
|
7
|
+
isValid: boolean;
|
|
8
|
+
inferredType: string;
|
|
9
|
+
errors: Array<{
|
|
10
|
+
message: string;
|
|
11
|
+
code: number;
|
|
12
|
+
severity: "error" | "warning";
|
|
13
|
+
}>;
|
|
14
|
+
}
|
|
15
|
+
export interface ExtendedDataType extends DataType {
|
|
16
|
+
type: string;
|
|
17
|
+
linkedDataTypeIdentifiers?: string[];
|
|
18
|
+
}
|
|
19
|
+
export interface ExtendedFunction extends Omit<FunctionDefinition, 'returnType'> {
|
|
20
|
+
signature: string;
|
|
21
|
+
linkedDataTypeIdentifiers?: string[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Minimal TypeScript library definitions for the virtual compiler environment.
|
|
25
|
+
*/
|
|
26
|
+
export declare const MINIMAL_LIB = "\n interface Array<T> { \n [n: number]: T; \n length: number; \n }\n interface String { readonly length: number; }\n interface Number { }\n interface Boolean { }\n interface Object { }\n interface Function { }\n interface CallableFunction extends Function {}\n interface NewableFunction extends Function {}\n interface IArguments { }\n interface RegExp { }\n type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;\n";
|
|
27
|
+
/**
|
|
28
|
+
* Common configuration for the TypeScript compiler host across different validation/inference tasks.
|
|
29
|
+
*/
|
|
30
|
+
export declare function createCompilerHost(fileName: string, sourceCode: string, sourceFile: ts.SourceFile): ts.CompilerHost;
|
|
31
|
+
/**
|
|
32
|
+
* Common TypeScript compiler options used for validation and type inference.
|
|
33
|
+
*/
|
|
34
|
+
export declare const DEFAULT_COMPILER_OPTIONS: ts.CompilerOptions;
|
|
35
|
+
/**
|
|
36
|
+
* Extracts and returns common type and generic declarations from DATA_TYPES.
|
|
37
|
+
*/
|
|
38
|
+
export declare function getSharedTypeDeclarations(dataTypes: ExtendedDataType[]): string;
|
|
39
|
+
/**
|
|
40
|
+
* Determines the type along a reference path for objects.
|
|
41
|
+
* @param value The base value to traverse.
|
|
42
|
+
* @param referencePath The path of properties to follow.
|
|
43
|
+
* @returns The typeof the final value or 'unknown' if path is broken.
|
|
44
|
+
*/
|
|
45
|
+
export declare function getTypeFromReferencePath(value: any, referencePath: ReferencePath[]): string;
|
|
46
|
+
/**
|
|
47
|
+
* Extracts and returns the TypeScript code representation for a NodeParameter.
|
|
48
|
+
*/
|
|
49
|
+
export declare function getParameterCode(param: NodeParameter, flow: Flow, getNodeValidation: (flow: Flow, node: NodeFunction) => ValidationResult): string;
|
|
50
|
+
/**
|
|
51
|
+
* Validates if a reference is accessible from the current node's scope.
|
|
52
|
+
*/
|
|
53
|
+
export declare const validateReference: (flow: Flow, currentNode: NodeFunction, ref: ReferenceValue) => {
|
|
54
|
+
isValid: boolean;
|
|
55
|
+
error?: string;
|
|
56
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Flow } from '@code0-tech/sagittarius-graphql-types';
|
|
2
|
+
import { ExtendedDataType, ExtendedFunction, ValidationResult } from '../utils';
|
|
3
|
+
/**
|
|
4
|
+
* Validates a flow by generating virtual TypeScript code and running it through the TS compiler.
|
|
5
|
+
*/
|
|
6
|
+
export declare const getFlowValidation: (flow: Flow, functions: ExtendedFunction[], dataTypes: ExtendedDataType[]) => ValidationResult;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Flow, NodeFunction } from '@code0-tech/sagittarius-graphql-types';
|
|
2
|
+
import { ExtendedDataType, ExtendedFunction, ValidationResult } from '../utils';
|
|
3
|
+
/**
|
|
4
|
+
* Validates a single node's parameters and scope, then infers its return type.
|
|
5
|
+
*/
|
|
6
|
+
export declare const getNodeValidation: (flow: Flow, node: NodeFunction, functions: ExtendedFunction[], dataTypes: ExtendedDataType[]) => ValidationResult;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { LiteralValue } from '@code0-tech/sagittarius-graphql-types';
|
|
2
|
+
import { ExtendedDataType } from '../utils';
|
|
3
|
+
/**
|
|
4
|
+
* Validates whether a literal value conforms to a specific TypeScript type string.
|
|
5
|
+
*/
|
|
6
|
+
export interface ValueValidationResult {
|
|
7
|
+
isValid: boolean;
|
|
8
|
+
error?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare const getValueValidation: (type: string, value: LiteralValue, dataTypes: ExtendedDataType[]) => ValueValidationResult;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("typescript"),W=`
|
|
2
|
+
interface Array<T> {
|
|
3
|
+
[n: number]: T;
|
|
4
|
+
length: number;
|
|
5
|
+
}
|
|
6
|
+
interface String { readonly length: number; }
|
|
7
|
+
interface Number { }
|
|
8
|
+
interface Boolean { }
|
|
9
|
+
interface Object { }
|
|
10
|
+
interface Function { }
|
|
11
|
+
interface CallableFunction extends Function {}
|
|
12
|
+
interface NewableFunction extends Function {}
|
|
13
|
+
interface IArguments { }
|
|
14
|
+
interface RegExp { }
|
|
15
|
+
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
|
|
16
|
+
`;function I(n,s,r){return{getSourceFile:e=>{if(e===n)return r;if(e.includes("lib.")||e.endsWith(".d.ts"))return t.createSourceFile(e,W,t.ScriptTarget.Latest)},writeFile:()=>{},getDefaultLibFileName:()=>"lib.d.ts",useCaseSensitiveFileNames:()=>!0,getCanonicalFileName:e=>e,getCurrentDirectory:()=>"/",getNewLine:()=>`
|
|
17
|
+
`,fileExists:e=>e===n||e.includes("lib.")||e.endsWith(".d.ts"),readFile:e=>e===n?s:e.includes("lib.")||e.endsWith(".d.ts")?W:void 0,directoryExists:()=>!0,getDirectories:()=>[]}}const V={target:t.ScriptTarget.Latest,lib:["lib.esnext.d.ts"],noEmit:!0,strictNullChecks:!0};function A(n){const s=Array.from(new Set(n.flatMap(e=>e.genericKeys||[]))).map(e=>`type ${e} = any;`).join(`
|
|
18
|
+
`),r=n.map(e=>`type ${e.identifier}${e.genericKeys?`<${e.genericKeys.join(",")}>`:""} = ${e.type};`).join(`
|
|
19
|
+
`);return`${s}
|
|
20
|
+
${r}`}function z(n,s){let r=n;for(const e of s){if(r==null)return"unknown";typeof e.path=="string"&&(r=r[e.path])}return typeof r}function B(n,s){const r=n.nodes;if(r)return Array.isArray(r)?r.find(e=>e.id===s):r.nodes?.find(e=>e.id===s)}function K(n,s,r){const e=n?.value;if(!e)return"undefined";if(e.__typename==="ReferenceValue"){const o=e,c=B(s,o.nodeFunctionId);if(!c)return"undefined";let u=r(s,c).inferredType;if(o.referencePath&&o.referencePath.length>0){let d;const m=c.parameters?.nodes;if(m&&m.length>0){const p=m[0];p?.value?.__typename==="LiteralValue"&&(d=p.value.value)}u=z(d,o.referencePath)}return`({} as ${u})`}if(e.__typename==="NodeFunctionIdWrapper"){const o=e.id,c=B(s,o);if(!c)return"(() => undefined)";const u=p=>{if(p.functionDefinition?.identifier==="std::control::return")return p;const y=p.nextNodeId?B(s,p.nextNodeId):void 0;return y?u(y):void 0},d=u(c);return d?`(() => ({} as ${r(s,d).inferredType}))`:"(() => undefined)"}return e.__typename==="LiteralValue"?JSON.stringify(e.value):"undefined"}const U=(n,s)=>{const r=n.nodes?.nodes;if(r)return r.find(e=>e?.parameters?.nodes?.some(o=>o?.value?.__typename==="NodeFunctionIdWrapper"&&o.value.id===s))},J=(n,s,r,e=new Set)=>{const o=s.id;if(!o||e.has(o))return!1;e.add(o);const c=d=>{const m=n.nodes?.nodes?.find(p=>p?.nextNodeId===d);return m?m.id===r?!0:c(m.id):!1};if(c(o))return!0;const u=U(n,o);return u?u.id===r?!0:J(n,u,r,e):!1},G=(n,s,r)=>{if(!r.nodeFunctionId)return{isValid:!0};if(r.parameterIndex!==void 0&&r.inputIndex!==void 0){if(s.id===r.nodeFunctionId)return{isValid:!0};let e=U(n,s.id);for(;e;){if(e.id===r.nodeFunctionId)return{isValid:!0};e=U(n,e.id)}return{isValid:!1,error:`Invalid input reference: Node ${s.id} is not in the scope of Node ${r.nodeFunctionId}.`}}return J(n,s,r.nodeFunctionId)?{isValid:!0}:{isValid:!1,error:`Node ${r.nodeFunctionId} has not been executed yet or is not visible in this scope.`}},M=n=>n.replace(/[^a-zA-Z0-9]/g,"_"),H=(n,s,r)=>{const e=new Set,o=n.nodes?.nodes||[],c=new Map(s.map(f=>[f.identifier,f])),u=(f,N="")=>{if(e.has(f))return"";const l=o.find(E=>E?.id===f);if(!l||!l.functionDefinition)return"";e.add(f);const _=c.get(l.functionDefinition?.identifier);if(!_)return`${N}// Error: Function ${l.functionDefinition.identifier} not found
|
|
21
|
+
`;const S=(l.parameters?.nodes||[]).map((E,R)=>{const C=E.value;if(!C)return"undefined";if(C.__typename==="ReferenceValue"){const L=C;if(!L.nodeFunctionId)return"undefined";let b=L.parameterIndex!==void 0?`p_${M(L.nodeFunctionId)}_${L.parameterIndex}`:`node_${M(L.nodeFunctionId)}`;return L.referencePath?.forEach(j=>{b+=`?.${j.path}`}),b}if(C.__typename==="LiteralValue")return JSON.stringify(C.value);if(C.__typename==="NodeFunctionIdWrapper"){const L=C,b=`p_${M(l.id)}_${R}`,j=u(L.id,N+" ");return`(${b}) => {
|
|
22
|
+
${j}${N}}`}return"undefined"}).join(", "),$=`node_${M(l.id)}`,P=`fn_${_.identifier?.replace(/::/g,"_")}`,x=S.includes("undefined")||(_.genericKeys?.length??0)>0;let D=`${N}const ${$} = ${P}(${S})${x?" as any":""} ;
|
|
23
|
+
`;return l.nextNodeId&&(D+=u(l.nextNodeId,N)),D},d=A(r),m=s.map(f=>`declare function fn_${f.identifier?.replace(/::/g,"_")}${f.signature}`).join(`
|
|
24
|
+
`),p=o.map(f=>f?.id?u(f.id):"").filter(f=>f!=="").join(`
|
|
25
|
+
`),y=`${d}
|
|
26
|
+
${m}
|
|
27
|
+
|
|
28
|
+
// --- Flow ---
|
|
29
|
+
${p}`,a="flow_virtual.ts",i=t.createSourceFile(a,y,t.ScriptTarget.Latest),g=I(a,y,i),h=t.createProgram([a],V,g).getSemanticDiagnostics(i).map(f=>{const N=t.flattenDiagnosticMessageText(f.messageText,`
|
|
30
|
+
`);return N.includes("Argument of type 'undefined'")||N.includes("not assignable to type 'undefined'")?null:{message:N,code:f.code,severity:"error"}}).filter(f=>f!==null);return{isValid:h.length===0,inferredType:"void",errors:h}},q=[{identifier:"LIST",type:"T[]",genericKeys:["T"]},{identifier:"NUMBER",type:"number"},{identifier:"HTTP_METHOD",type:'"GET" | "POST" | "PUT" | "DELETE"'},{identifier:"STRING",type:"string"},{identifier:"CONSUMER",type:"(item:R) => void",genericKeys:["R"]},{identifier:"PREDICATE",type:"(item:R) => T",genericKeys:["R","T"]},{identifier:"NUMBER_ARRAY",type:"LIST<NUMBER>",linkedDataTypeIdentifiers:["LIST","NUMBER"]}];function Q(n,s){if(!n||!s||s.length===0)return[];const r="suggestions.ts",e=A(q);function o(a){const i=a.match(/<([^>]+)>/);return i?i[1].split(",").map(g=>g.trim()).filter(Boolean).length:0}const c=`
|
|
31
|
+
${e}
|
|
32
|
+
type TargetType = ${n};
|
|
33
|
+
${s.map((a,i)=>`
|
|
34
|
+
declare function Fu${i}${a.signature};
|
|
35
|
+
type F${i} = ReturnType<typeof Fu${i}${o(a.signature)>0?`<${Array(o(a.signature)).fill("any").join(", ")}>`:""}>;
|
|
36
|
+
`).join(`
|
|
37
|
+
`)}
|
|
38
|
+
${s.map((a,i)=>`const check${i}: TargetType = {} as F${i};`).join(`
|
|
39
|
+
`)}
|
|
40
|
+
`;console.log(c);const u=t.createSourceFile(r,c,t.ScriptTarget.Latest),d=I(r,c,u),p=t.createProgram([r],{...V},d).getSemanticDiagnostics(),y=new Set;return p.forEach(a=>{a.file===u&&a.start!==void 0&&y.add(u.getLineAndCharacterOfPosition(a.start).line)}),s.map((a,i)=>{const g=`const check${i}: TargetType = {} as F${i};`,T=c.split(`
|
|
41
|
+
`).findIndex(h=>h.includes(g));return T!==-1&&y.has(T)?null:{__typename:"NodeFunction",id:"gid://sagittarius/NodeFunction/1",functionDefinition:{__typename:"FunctionDefinition",id:a.identifier,identifier:a.identifier},parameters:{__typename:"NodeParameterConnection",nodes:(a.parameterDefinitions?.nodes||[]).map(h=>({__typename:"NodeParameter",parameterDefinition:{__typename:"ParameterDefinition",id:h?.identifier,identifier:h?.identifier},value:null}))}}}).filter(a=>a!==null)}const O=(n,s,r,e)=>{const c=new Map(r.map(F=>[F.identifier,F])).get(s.functionDefinition?.identifier);if(!c)return{isValid:!1,inferredType:"any",errors:[{message:`Function ${s.id} not found`,code:404,severity:"error"}]};const u=s.parameters?.nodes||[],d=[];for(const F of u){const S=F.value;if(S?.__typename==="ReferenceValue"){const $=G(n,s,S);$.isValid||d.push({message:$.error||"Scope error",code:403,severity:"error"})}}if(d.length>0)return{isValid:!1,inferredType:"any",errors:d};const p=u.map(F=>K(F,n,(S,$)=>O(S,$,r,e))).map(F=>F==="undefined"?"({} as any)":F).join(", ");let y=c.signature;const a=`
|
|
42
|
+
${A(e)}
|
|
43
|
+
declare function testFunc${y};
|
|
44
|
+
const result = testFunc(${p});
|
|
45
|
+
`,i="node_virtual.ts",g=t.createSourceFile(i,a,t.ScriptTarget.Latest),v=I(i,a,g),T=t.createProgram([i],V,v),h=T.getTypeChecker(),f=T.getSemanticDiagnostics(g);let N="any";const l=F=>{if(t.isVariableDeclaration(F)&&F.name.getText()==="result"){const S=h.getTypeAtLocation(F);N=h.typeToString(S,F,t.TypeFormatFlags.NoTruncation|t.TypeFormatFlags.UseFullyQualifiedType)}t.forEachChild(F,l)};l(g);const _=f.map(F=>{const S=t.flattenDiagnosticMessageText(F.messageText,`
|
|
46
|
+
`),$=/\b([TRKV])\b/.test(S),P=S.includes("not assignable to parameter of type")&&(S.includes("'{}'")||S.includes("undefined"))||S.includes("not assignable to type 'undefined'")||S.includes("not assignable to type 'void'")||S.includes("may be a mistake because neither type sufficiently overlaps");return{message:S,code:F.code,severity:$||P?"warning":"error"}});return{isValid:!_.some(F=>F.severity==="error"),inferredType:N,errors:_}},Z=(n,s,r,e,o)=>{const c=[],u=n.nodes?.nodes||[],d=u.find(i=>i?.id===s);if(!d)return[];const m=A(o),p=(i,g)=>{if(!r||r==="any"||i==="any")return!0;const v=`suggestion_check_${Math.random().toString(36).substring(7)}.ts`,T=`
|
|
47
|
+
${m}
|
|
48
|
+
const val: ${i} = {} as any;
|
|
49
|
+
const test: ${r} = val${g?`.${g}`:""};
|
|
50
|
+
`,h=t.createSourceFile(v,T,t.ScriptTarget.Latest),f=I(v,T,h);return!t.createProgram([v],V,f).getSemanticDiagnostics(h).some(_=>_.category===t.DiagnosticCategory.Error)},y=(i,g)=>{const v=[],T=`probing_${Math.random().toString(36).substring(7)}.ts`,h=`
|
|
51
|
+
${m}
|
|
52
|
+
const val: ${i} = {} as any;
|
|
53
|
+
`,f=t.createSourceFile(T,h,t.ScriptTarget.Latest),N=I(T,h,f),l=t.createProgram([T],V,N),_=l.getTypeChecker();p(i)&&v.push({...g,referencePath:[]});const F=($,P=[])=>{if(P.length>3)return;const x=$.getProperties();for(const D of x){const E=D.getName();let R;if(_.getPropertyOfType){const b=_.getPropertyOfType($,E);b&&(R=_.getTypeOfSymbolAtLocation(b,f))}else{const b=$.getProperty(E);b&&(R=_.getTypeOfSymbolAtLocation(b,f))}if(!R)continue;const C=[...P,E],L=C.join(".");p(i,L)&&v.push({...g,referencePath:C.map(b=>({__typename:"ReferencePath",path:b}))}),F(R,C)}};if(l.getSemanticDiagnostics(f).length===0){let $;const P=x=>{t.isVariableDeclaration(x)&&x.name.getText()==="val"&&($=_.getTypeAtLocation(x)),t.forEachChild(x,P)};P(f),$&&F($)}return v};if(n.inputType){const i=n.inputType.identifier||"any";c.push(...y(i,{__typename:"ReferenceValue",nodeFunctionId:null,parameterIndex:0,referencePath:[]}))}u.forEach(i=>{if(!(!i||i.id===s)&&X(n,i,d)){const g=O(n,i,e,o);c.push(...y(g.inferredType,{__typename:"ReferenceValue",nodeFunctionId:i.id,referencePath:[]}))}});let a=k(n,s);for(;a;){if(e.find(g=>g.identifier===a.functionDefinition?.identifier)){const g=a.parameters?.nodes?.findIndex(v=>{const T=v?.value;if(T?.__typename==="NodeFunctionIdWrapper"){const h=T;return h.id===s||w(n,h.id||void 0,s)}return!1});g!==void 0&&g!==-1&&c.push(...y("any",{__typename:"ReferenceValue",nodeFunctionId:a.id,parameterIndex:g,inputIndex:0,referencePath:[]}))}a=k(n,a.id)}return c};function X(n,s,r){const e=n.nodes?.nodes||[];let o=s.nextNodeId;const c=new Set;for(;o;){if(o===r.id)return!0;if(c.has(o))break;c.add(o),o=e.find(m=>m?.id===o)?.nextNodeId}let u=k(n,r.id);for(;u;){if(u.id===s.id)return!0;u=k(n,u.id)}return!1}function k(n,s){return n.nodes?.nodes?.find(e=>e?.parameters?.nodes?.some(o=>o?.value?.__typename==="NodeFunctionIdWrapper"&&o.value.id===s))||void 0}function w(n,s,r){if(!s)return!1;if(s===r)return!0;const o=(n.nodes?.nodes||[]).find(u=>u?.id===s);return o?o.nextNodeId&&w(n,o.nextNodeId||void 0,r)?!0:!!o.parameters?.nodes?.some(u=>{const d=u?.value;return d?.__typename==="NodeFunctionIdWrapper"?w(n,d.id||void 0,r):!1}):!1}const ee=n=>{const r=`const tempValue = ${JSON.stringify(n.value)};`,e="temp_value.ts",o=t.createSourceFile(e,r,t.ScriptTarget.Latest),c=I(e,r,o),d=t.createProgram([e],{target:t.ScriptTarget.Latest,noEmit:!0},c).getTypeChecker();let m="any";const p=y=>{if(t.isVariableDeclaration(y)&&y.name.getText()==="tempValue"){const a=d.getTypeAtLocation(y);m=d.typeToString(a,y,t.TypeFormatFlags.NoTruncation|t.TypeFormatFlags.UseFullyQualifiedType)}t.forEachChild(y,p)};return p(o),m};var Y=(n=>(n[n.PRIMITIVE=0]="PRIMITIVE",n[n.TYPE=1]="TYPE",n[n.ARRAY=2]="ARRAY",n[n.OBJECT=3]="OBJECT",n))(Y||{});const te=(n,s)=>{const r=A(s),e=`type_probe_${Math.random().toString(36).substring(7)}.ts`,o=`
|
|
54
|
+
${r}
|
|
55
|
+
type TargetType = ${n};
|
|
56
|
+
const val: TargetType = {} as any;
|
|
57
|
+
`,c=t.createSourceFile(e,o,t.ScriptTarget.Latest),u=I(e,o,c),m=t.createProgram([e],V,u).getTypeChecker();let p=1;const y=a=>{if(t.isVariableDeclaration(a)&&a.name.getText()==="val"){const i=m.getTypeAtLocation(a);m.isArrayType(i)?p=2:i.isStringLiteral()||i.isNumberLiteral()||(i.getFlags()&(t.TypeFlags.String|t.TypeFlags.Number|t.TypeFlags.Boolean|t.TypeFlags.EnumLiteral|t.TypeFlags.BigInt|t.TypeFlags.ESSymbol))!==0?p=0:(i.isClassOrInterface()||(i.getFlags()&t.TypeFlags.Object)!==0)&&i.getProperties().length>0?p=3:p=1}t.forEachChild(a,y)};return y(c),p},ne=(n,s)=>{const r=`
|
|
58
|
+
${A(s)}
|
|
59
|
+
type Target = ${n};
|
|
60
|
+
`,e="temp_type_to_value.ts",o=t.createSourceFile(e,r,t.ScriptTarget.Latest,!0),c=I(e,r,o),d=t.createProgram([e],V,c).getTypeChecker(),m=o.statements.find(i=>t.isTypeAliasDeclaration(i)&&i.name.text==="Target");if(!m)return{__typename:"LiteralValue",value:null};const p=d.getTypeAtLocation(m.type),y=(i,g,v=new Set)=>{if(v.has(i))return null;v.add(i);const T=i.getFlags();if(i.isUnion()){if(g.type,t.isTypeAliasDeclaration(g)&&g.type&&t.isUnionTypeNode(g.type)){const N=d.getTypeFromTypeNode(g.type.types[0]);return y(N,g,v)}const h=i.types.filter(N=>{const l=N.getFlags();return!(l&t.TypeFlags.Undefined)&&!(l&t.TypeFlags.Null)}),f=h.length>0?h[0]:i.types[0];return y(f,g,v)}if(T&t.TypeFlags.StringLiteral)return i.value;if(T&t.TypeFlags.String)return"sample";if(T&t.TypeFlags.NumberLiteral)return i.value;if(T&t.TypeFlags.Number)return 1;if(T&t.TypeFlags.BooleanLiteral)return i.intrinsicName==="true";if(T&t.TypeFlags.Boolean)return!1;if(d.isArrayType(i)){const f=i.typeArguments?.[0]||d.getAnyType();return[y(f,g,v)]}if(i.isClassOrInterface()||T&t.TypeFlags.Object||i.getProperties().length>0){const h={};return i.getProperties().forEach(N=>{const l=d.getTypeOfSymbolAtLocation(N,g);l&&(h[N.getName()]=y(l,g,v))}),h}return null};return{value:y(p,m)}},re=n=>{if(!n)return[];const s=`type T = ${n}; const val: T = {} as any;`,r="suggestions_virtual.ts",e=t.createSourceFile(r,s,t.ScriptTarget.Latest),o=I(r,s,e),u=t.createProgram([r],{...V,noLib:!0},o).getTypeChecker(),d=e.statements.find(t.isTypeAliasDeclaration);if(!d)return[];const m=u.getTypeAtLocation(d),p=a=>a.isUnion()?a.types.flatMap(p):a.isStringLiteral()?[a.value]:a.isNumberLiteral()?[a.value.toString()]:a.intrinsicName==="true"?["true"]:a.intrinsicName==="false"?["false"]:[];return Array.from(new Set(p(m))).map(a=>({__typename:"LiteralValue",value:a}))},ie=(n,s,r)=>{const e=JSON.stringify(s.value),o=`
|
|
61
|
+
${A(r)}
|
|
62
|
+
const testValue: ${n} = ${e};
|
|
63
|
+
`,c="value_check.ts",u=t.createSourceFile(c,o,t.ScriptTarget.Latest),d=I(c,o,u),p=t.createProgram([c],V,d).getSemanticDiagnostics(u);return p.length>0?{isValid:!1,error:t.flattenDiagnosticMessageText(p[0].messageText,`
|
|
64
|
+
`)}:{isValid:!0}},se=(n,s,r)=>{const o=new Map(s.map(l=>[l.identifier,l])).get(n.functionDefinition?.identifier);if(!o)return{parameters:[],returnType:"any"};const c={id:"gid://sagittarius/Flow/0",nodes:{__typename:"NodeFunctionConnection",nodes:[n]}},m=(n.parameters?.nodes||[]).map(l=>K(l,c,(_,F)=>O(_,F,s,r))).map(l=>l==="undefined"?"({} as any)":l).join(", "),p=o.signature,y=`
|
|
65
|
+
${A(r)}
|
|
66
|
+
declare function testFunc${p};
|
|
67
|
+
const result = testFunc(${m});
|
|
68
|
+
`,a="node_types_virtual.ts",i=t.createSourceFile(a,y,t.ScriptTarget.Latest),g=I(a,y,i),T=t.createProgram([a],V,g).getTypeChecker();let h="any",f=[];const N=l=>{if(t.isVariableDeclaration(l)&&l.name.getText()==="result"){const _=T.getTypeAtLocation(l);if(h=T.typeToString(_,l,t.TypeFormatFlags.NoTruncation),t.isCallExpression(l.initializer)){const F=l.initializer,S=T.getResolvedSignature(F);S&&(f=S.getParameters().map($=>{const P=T.getTypeOfSymbolAtLocation($,F);return T.typeToString(P,F,t.TypeFormatFlags.NoTruncation)}))}}t.forEachChild(l,N)};return N(i),{parameters:f,returnType:h}};exports.DataTypeVariant=Y;exports.getFlowValidation=H;exports.getNodeSuggestions=Q;exports.getNodeValidation=O;exports.getReferenceSuggestions=Z;exports.getTypeFromValue=ee;exports.getTypeVariant=te;exports.getTypesFromNode=se;exports.getValueFromType=ne;exports.getValueSuggestions=re;exports.getValueValidation=ie;
|
|
@@ -0,0 +1,584 @@
|
|
|
1
|
+
import t from "typescript";
|
|
2
|
+
const w = `
|
|
3
|
+
interface Array<T> {
|
|
4
|
+
[n: number]: T;
|
|
5
|
+
length: number;
|
|
6
|
+
}
|
|
7
|
+
interface String { readonly length: number; }
|
|
8
|
+
interface Number { }
|
|
9
|
+
interface Boolean { }
|
|
10
|
+
interface Object { }
|
|
11
|
+
interface Function { }
|
|
12
|
+
interface CallableFunction extends Function {}
|
|
13
|
+
interface NewableFunction extends Function {}
|
|
14
|
+
interface IArguments { }
|
|
15
|
+
interface RegExp { }
|
|
16
|
+
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
|
|
17
|
+
`;
|
|
18
|
+
function I(n, s, r) {
|
|
19
|
+
return {
|
|
20
|
+
getSourceFile: (e) => {
|
|
21
|
+
if (e === n) return r;
|
|
22
|
+
if (e.includes("lib.") || e.endsWith(".d.ts")) return t.createSourceFile(e, w, t.ScriptTarget.Latest);
|
|
23
|
+
},
|
|
24
|
+
writeFile: () => {
|
|
25
|
+
},
|
|
26
|
+
getDefaultLibFileName: () => "lib.d.ts",
|
|
27
|
+
useCaseSensitiveFileNames: () => !0,
|
|
28
|
+
getCanonicalFileName: (e) => e,
|
|
29
|
+
getCurrentDirectory: () => "/",
|
|
30
|
+
getNewLine: () => `
|
|
31
|
+
`,
|
|
32
|
+
fileExists: (e) => e === n || e.includes("lib.") || e.endsWith(".d.ts"),
|
|
33
|
+
readFile: (e) => e === n ? s : e.includes("lib.") || e.endsWith(".d.ts") ? w : void 0,
|
|
34
|
+
directoryExists: () => !0,
|
|
35
|
+
getDirectories: () => []
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const x = {
|
|
39
|
+
target: t.ScriptTarget.Latest,
|
|
40
|
+
lib: ["lib.esnext.d.ts"],
|
|
41
|
+
noEmit: !0,
|
|
42
|
+
strictNullChecks: !0
|
|
43
|
+
};
|
|
44
|
+
function E(n) {
|
|
45
|
+
const s = Array.from(new Set(n.flatMap((e) => e.genericKeys || []))).map((e) => `type ${e} = any;`).join(`
|
|
46
|
+
`), r = n.map(
|
|
47
|
+
(e) => `type ${e.identifier}${e.genericKeys ? `<${e.genericKeys.join(",")}>` : ""} = ${e.type};`
|
|
48
|
+
).join(`
|
|
49
|
+
`);
|
|
50
|
+
return `${s}
|
|
51
|
+
${r}`;
|
|
52
|
+
}
|
|
53
|
+
function Y(n, s) {
|
|
54
|
+
let r = n;
|
|
55
|
+
for (const e of s) {
|
|
56
|
+
if (r == null) return "unknown";
|
|
57
|
+
typeof e.path == "string" && (r = r[e.path]);
|
|
58
|
+
}
|
|
59
|
+
return typeof r;
|
|
60
|
+
}
|
|
61
|
+
function j(n, s) {
|
|
62
|
+
const r = n.nodes;
|
|
63
|
+
if (r)
|
|
64
|
+
return Array.isArray(r) ? r.find((e) => e.id === s) : r.nodes?.find((e) => e.id === s);
|
|
65
|
+
}
|
|
66
|
+
function K(n, s, r) {
|
|
67
|
+
const e = n?.value;
|
|
68
|
+
if (!e) return "undefined";
|
|
69
|
+
if (e.__typename === "ReferenceValue") {
|
|
70
|
+
const o = e, c = j(s, o.nodeFunctionId);
|
|
71
|
+
if (!c) return "undefined";
|
|
72
|
+
let u = r(s, c).inferredType;
|
|
73
|
+
if (o.referencePath && o.referencePath.length > 0) {
|
|
74
|
+
let d;
|
|
75
|
+
const y = c.parameters?.nodes;
|
|
76
|
+
if (y && y.length > 0) {
|
|
77
|
+
const p = y[0];
|
|
78
|
+
p?.value?.__typename === "LiteralValue" && (d = p.value.value);
|
|
79
|
+
}
|
|
80
|
+
u = Y(d, o.referencePath);
|
|
81
|
+
}
|
|
82
|
+
return `({} as ${u})`;
|
|
83
|
+
}
|
|
84
|
+
if (e.__typename === "NodeFunctionIdWrapper") {
|
|
85
|
+
const o = e.id, c = j(s, o);
|
|
86
|
+
if (!c) return "(() => undefined)";
|
|
87
|
+
const u = (p) => {
|
|
88
|
+
if (p.functionDefinition?.identifier === "std::control::return")
|
|
89
|
+
return p;
|
|
90
|
+
const m = p.nextNodeId ? j(s, p.nextNodeId) : void 0;
|
|
91
|
+
return m ? u(m) : void 0;
|
|
92
|
+
}, d = u(c);
|
|
93
|
+
return d ? `(() => ({} as ${r(s, d).inferredType}))` : "(() => undefined)";
|
|
94
|
+
}
|
|
95
|
+
return e.__typename === "LiteralValue" ? JSON.stringify(e.value) : "undefined";
|
|
96
|
+
}
|
|
97
|
+
const B = (n, s) => {
|
|
98
|
+
const r = n.nodes?.nodes;
|
|
99
|
+
if (r)
|
|
100
|
+
return r.find(
|
|
101
|
+
(e) => e?.parameters?.nodes?.some(
|
|
102
|
+
(o) => o?.value?.__typename === "NodeFunctionIdWrapper" && o.value.id === s
|
|
103
|
+
)
|
|
104
|
+
);
|
|
105
|
+
}, J = (n, s, r, e = /* @__PURE__ */ new Set()) => {
|
|
106
|
+
const o = s.id;
|
|
107
|
+
if (!o || e.has(o)) return !1;
|
|
108
|
+
e.add(o);
|
|
109
|
+
const c = (d) => {
|
|
110
|
+
const y = n.nodes?.nodes?.find((p) => p?.nextNodeId === d);
|
|
111
|
+
return y ? y.id === r ? !0 : c(y.id) : !1;
|
|
112
|
+
};
|
|
113
|
+
if (c(o)) return !0;
|
|
114
|
+
const u = B(n, o);
|
|
115
|
+
return u ? u.id === r ? !0 : J(n, u, r, e) : !1;
|
|
116
|
+
}, z = (n, s, r) => {
|
|
117
|
+
if (!r.nodeFunctionId)
|
|
118
|
+
return { isValid: !0 };
|
|
119
|
+
if (r.parameterIndex !== void 0 && r.inputIndex !== void 0) {
|
|
120
|
+
if (s.id === r.nodeFunctionId) return { isValid: !0 };
|
|
121
|
+
let e = B(n, s.id);
|
|
122
|
+
for (; e; ) {
|
|
123
|
+
if (e.id === r.nodeFunctionId) return { isValid: !0 };
|
|
124
|
+
e = B(n, e.id);
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
isValid: !1,
|
|
128
|
+
error: `Invalid input reference: Node ${s.id} is not in the scope of Node ${r.nodeFunctionId}.`
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
return J(n, s, r.nodeFunctionId) ? { isValid: !0 } : {
|
|
132
|
+
isValid: !1,
|
|
133
|
+
error: `Node ${r.nodeFunctionId} has not been executed yet or is not visible in this scope.`
|
|
134
|
+
};
|
|
135
|
+
}, M = (n) => n.replace(/[^a-zA-Z0-9]/g, "_"), Z = (n, s, r) => {
|
|
136
|
+
const e = /* @__PURE__ */ new Set(), o = n.nodes?.nodes || [], c = new Map(s.map((f) => [f.identifier, f])), u = (f, N = "") => {
|
|
137
|
+
if (e.has(f)) return "";
|
|
138
|
+
const l = o.find((R) => R?.id === f);
|
|
139
|
+
if (!l || !l.functionDefinition) return "";
|
|
140
|
+
e.add(f);
|
|
141
|
+
const v = c.get(l.functionDefinition?.identifier);
|
|
142
|
+
if (!v) return `${N}// Error: Function ${l.functionDefinition.identifier} not found
|
|
143
|
+
`;
|
|
144
|
+
const S = (l.parameters?.nodes || []).map((R, D) => {
|
|
145
|
+
const P = R.value;
|
|
146
|
+
if (!P) return "undefined";
|
|
147
|
+
if (P.__typename === "ReferenceValue") {
|
|
148
|
+
const L = P;
|
|
149
|
+
if (!L.nodeFunctionId) return "undefined";
|
|
150
|
+
let b = L.parameterIndex !== void 0 ? `p_${M(L.nodeFunctionId)}_${L.parameterIndex}` : `node_${M(L.nodeFunctionId)}`;
|
|
151
|
+
return L.referencePath?.forEach((O) => {
|
|
152
|
+
b += `?.${O.path}`;
|
|
153
|
+
}), b;
|
|
154
|
+
}
|
|
155
|
+
if (P.__typename === "LiteralValue")
|
|
156
|
+
return JSON.stringify(P.value);
|
|
157
|
+
if (P.__typename === "NodeFunctionIdWrapper") {
|
|
158
|
+
const L = P, b = `p_${M(l.id)}_${D}`, O = u(L.id, N + " ");
|
|
159
|
+
return `(${b}) => {
|
|
160
|
+
${O}${N}}`;
|
|
161
|
+
}
|
|
162
|
+
return "undefined";
|
|
163
|
+
}).join(", "), $ = `node_${M(l.id)}`, C = `fn_${v.identifier?.replace(/::/g, "_")}`, A = S.includes("undefined") || (v.genericKeys?.length ?? 0) > 0;
|
|
164
|
+
let V = `${N}const ${$} = ${C}(${S})${A ? " as any" : ""} ;
|
|
165
|
+
`;
|
|
166
|
+
return l.nextNodeId && (V += u(l.nextNodeId, N)), V;
|
|
167
|
+
}, d = E(r), y = s.map((f) => `declare function fn_${f.identifier?.replace(/::/g, "_")}${f.signature}`).join(`
|
|
168
|
+
`), p = o.map((f) => f?.id ? u(f.id) : "").filter((f) => f !== "").join(`
|
|
169
|
+
`), m = `${d}
|
|
170
|
+
${y}
|
|
171
|
+
|
|
172
|
+
// --- Flow ---
|
|
173
|
+
${p}`, a = "flow_virtual.ts", i = t.createSourceFile(a, m, t.ScriptTarget.Latest), g = I(a, m, i), h = t.createProgram([a], x, g).getSemanticDiagnostics(i).map((f) => {
|
|
174
|
+
const N = t.flattenDiagnosticMessageText(f.messageText, `
|
|
175
|
+
`);
|
|
176
|
+
return N.includes("Argument of type 'undefined'") || N.includes("not assignable to type 'undefined'") ? null : {
|
|
177
|
+
message: N,
|
|
178
|
+
code: f.code,
|
|
179
|
+
severity: "error"
|
|
180
|
+
};
|
|
181
|
+
}).filter((f) => f !== null);
|
|
182
|
+
return {
|
|
183
|
+
isValid: h.length === 0,
|
|
184
|
+
inferredType: "void",
|
|
185
|
+
errors: h
|
|
186
|
+
};
|
|
187
|
+
}, G = [
|
|
188
|
+
{ identifier: "LIST", type: "T[]", genericKeys: ["T"] },
|
|
189
|
+
{ identifier: "NUMBER", type: "number" },
|
|
190
|
+
{ identifier: "HTTP_METHOD", type: '"GET" | "POST" | "PUT" | "DELETE"' },
|
|
191
|
+
{ identifier: "STRING", type: "string" },
|
|
192
|
+
{ identifier: "CONSUMER", type: "(item:R) => void", genericKeys: ["R"] },
|
|
193
|
+
{ identifier: "PREDICATE", type: "(item:R) => T", genericKeys: ["R", "T"] },
|
|
194
|
+
{ identifier: "NUMBER_ARRAY", type: "LIST<NUMBER>", linkedDataTypeIdentifiers: ["LIST", "NUMBER"] }
|
|
195
|
+
];
|
|
196
|
+
function X(n, s) {
|
|
197
|
+
if (!n || !s || s.length === 0)
|
|
198
|
+
return [];
|
|
199
|
+
const r = "suggestions.ts", e = E(G);
|
|
200
|
+
function o(a) {
|
|
201
|
+
const i = a.match(/<([^>]+)>/);
|
|
202
|
+
return i ? i[1].split(",").map((g) => g.trim()).filter(Boolean).length : 0;
|
|
203
|
+
}
|
|
204
|
+
const c = `
|
|
205
|
+
${e}
|
|
206
|
+
type TargetType = ${n};
|
|
207
|
+
${s.map((a, i) => `
|
|
208
|
+
declare function Fu${i}${a.signature};
|
|
209
|
+
type F${i} = ReturnType<typeof Fu${i}${o(a.signature) > 0 ? `<${Array(o(a.signature)).fill("any").join(", ")}>` : ""}>;
|
|
210
|
+
`).join(`
|
|
211
|
+
`)}
|
|
212
|
+
${s.map((a, i) => `const check${i}: TargetType = {} as F${i};`).join(`
|
|
213
|
+
`)}
|
|
214
|
+
`;
|
|
215
|
+
console.log(c);
|
|
216
|
+
const u = t.createSourceFile(r, c, t.ScriptTarget.Latest), d = I(r, c, u), p = t.createProgram([r], {
|
|
217
|
+
...x
|
|
218
|
+
}, d).getSemanticDiagnostics(), m = /* @__PURE__ */ new Set();
|
|
219
|
+
return p.forEach((a) => {
|
|
220
|
+
a.file === u && a.start !== void 0 && m.add(u.getLineAndCharacterOfPosition(a.start).line);
|
|
221
|
+
}), s.map((a, i) => {
|
|
222
|
+
const g = `const check${i}: TargetType = {} as F${i};`, T = c.split(`
|
|
223
|
+
`).findIndex((h) => h.includes(g));
|
|
224
|
+
return T !== -1 && m.has(T) ? null : {
|
|
225
|
+
__typename: "NodeFunction",
|
|
226
|
+
id: "gid://sagittarius/NodeFunction/1",
|
|
227
|
+
functionDefinition: {
|
|
228
|
+
__typename: "FunctionDefinition",
|
|
229
|
+
id: a.identifier,
|
|
230
|
+
identifier: a.identifier
|
|
231
|
+
},
|
|
232
|
+
parameters: {
|
|
233
|
+
__typename: "NodeParameterConnection",
|
|
234
|
+
nodes: (a.parameterDefinitions?.nodes || []).map((h) => ({
|
|
235
|
+
__typename: "NodeParameter",
|
|
236
|
+
parameterDefinition: {
|
|
237
|
+
__typename: "ParameterDefinition",
|
|
238
|
+
id: h?.identifier,
|
|
239
|
+
identifier: h?.identifier
|
|
240
|
+
},
|
|
241
|
+
value: null
|
|
242
|
+
}))
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
}).filter((a) => a !== null);
|
|
246
|
+
}
|
|
247
|
+
const W = (n, s, r, e) => {
|
|
248
|
+
const c = new Map(r.map((F) => [F.identifier, F])).get(s.functionDefinition?.identifier);
|
|
249
|
+
if (!c)
|
|
250
|
+
return {
|
|
251
|
+
isValid: !1,
|
|
252
|
+
inferredType: "any",
|
|
253
|
+
errors: [{ message: `Function ${s.id} not found`, code: 404, severity: "error" }]
|
|
254
|
+
};
|
|
255
|
+
const u = s.parameters?.nodes || [], d = [];
|
|
256
|
+
for (const F of u) {
|
|
257
|
+
const S = F.value;
|
|
258
|
+
if (S?.__typename === "ReferenceValue") {
|
|
259
|
+
const $ = z(n, s, S);
|
|
260
|
+
$.isValid || d.push({
|
|
261
|
+
message: $.error || "Scope error",
|
|
262
|
+
code: 403,
|
|
263
|
+
severity: "error"
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (d.length > 0)
|
|
268
|
+
return {
|
|
269
|
+
isValid: !1,
|
|
270
|
+
inferredType: "any",
|
|
271
|
+
errors: d
|
|
272
|
+
};
|
|
273
|
+
const p = u.map((F) => K(F, n, (S, $) => W(S, $, r, e))).map(
|
|
274
|
+
(F) => F === "undefined" ? "({} as any)" : F
|
|
275
|
+
).join(", ");
|
|
276
|
+
let m = c.signature;
|
|
277
|
+
const a = `
|
|
278
|
+
${E(e)}
|
|
279
|
+
declare function testFunc${m};
|
|
280
|
+
const result = testFunc(${p});
|
|
281
|
+
`, i = "node_virtual.ts", g = t.createSourceFile(i, a, t.ScriptTarget.Latest), _ = I(i, a, g), T = t.createProgram([i], x, _), h = T.getTypeChecker(), f = T.getSemanticDiagnostics(g);
|
|
282
|
+
let N = "any";
|
|
283
|
+
const l = (F) => {
|
|
284
|
+
if (t.isVariableDeclaration(F) && F.name.getText() === "result") {
|
|
285
|
+
const S = h.getTypeAtLocation(F);
|
|
286
|
+
N = h.typeToString(
|
|
287
|
+
S,
|
|
288
|
+
F,
|
|
289
|
+
t.TypeFormatFlags.NoTruncation | t.TypeFormatFlags.UseFullyQualifiedType
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
t.forEachChild(F, l);
|
|
293
|
+
};
|
|
294
|
+
l(g);
|
|
295
|
+
const v = f.map((F) => {
|
|
296
|
+
const S = t.flattenDiagnosticMessageText(F.messageText, `
|
|
297
|
+
`), $ = /\b([TRKV])\b/.test(S), C = S.includes("not assignable to parameter of type") && (S.includes("'{}'") || S.includes("undefined")) || S.includes("not assignable to type 'undefined'") || S.includes("not assignable to type 'void'") || S.includes("may be a mistake because neither type sufficiently overlaps");
|
|
298
|
+
return {
|
|
299
|
+
message: S,
|
|
300
|
+
code: F.code,
|
|
301
|
+
severity: $ || C ? "warning" : "error"
|
|
302
|
+
};
|
|
303
|
+
});
|
|
304
|
+
return {
|
|
305
|
+
isValid: !v.some((F) => F.severity === "error"),
|
|
306
|
+
inferredType: N,
|
|
307
|
+
errors: v
|
|
308
|
+
};
|
|
309
|
+
}, ee = (n, s, r, e, o) => {
|
|
310
|
+
const c = [], u = n.nodes?.nodes || [], d = u.find((i) => i?.id === s);
|
|
311
|
+
if (!d) return [];
|
|
312
|
+
const y = E(o), p = (i, g) => {
|
|
313
|
+
if (!r || r === "any" || i === "any") return !0;
|
|
314
|
+
const _ = `suggestion_check_${Math.random().toString(36).substring(7)}.ts`, T = `
|
|
315
|
+
${y}
|
|
316
|
+
const val: ${i} = {} as any;
|
|
317
|
+
const test: ${r} = val${g ? `.${g}` : ""};
|
|
318
|
+
`, h = t.createSourceFile(_, T, t.ScriptTarget.Latest), f = I(_, T, h);
|
|
319
|
+
return !t.createProgram([_], x, f).getSemanticDiagnostics(h).some((v) => v.category === t.DiagnosticCategory.Error);
|
|
320
|
+
}, m = (i, g) => {
|
|
321
|
+
const _ = [], T = `probing_${Math.random().toString(36).substring(7)}.ts`, h = `
|
|
322
|
+
${y}
|
|
323
|
+
const val: ${i} = {} as any;
|
|
324
|
+
`, f = t.createSourceFile(T, h, t.ScriptTarget.Latest), N = I(T, h, f), l = t.createProgram([T], x, N), v = l.getTypeChecker();
|
|
325
|
+
p(i) && _.push({ ...g, referencePath: [] });
|
|
326
|
+
const F = ($, C = []) => {
|
|
327
|
+
if (C.length > 3) return;
|
|
328
|
+
const A = $.getProperties();
|
|
329
|
+
for (const V of A) {
|
|
330
|
+
const R = V.getName();
|
|
331
|
+
let D;
|
|
332
|
+
if (v.getPropertyOfType) {
|
|
333
|
+
const b = v.getPropertyOfType($, R);
|
|
334
|
+
b && (D = v.getTypeOfSymbolAtLocation(b, f));
|
|
335
|
+
} else {
|
|
336
|
+
const b = $.getProperty(R);
|
|
337
|
+
b && (D = v.getTypeOfSymbolAtLocation(b, f));
|
|
338
|
+
}
|
|
339
|
+
if (!D) continue;
|
|
340
|
+
const P = [...C, R], L = P.join(".");
|
|
341
|
+
p(i, L) && _.push({
|
|
342
|
+
...g,
|
|
343
|
+
referencePath: P.map((b) => ({
|
|
344
|
+
__typename: "ReferencePath",
|
|
345
|
+
path: b
|
|
346
|
+
}))
|
|
347
|
+
}), F(D, P);
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
if (l.getSemanticDiagnostics(f).length === 0) {
|
|
351
|
+
let $;
|
|
352
|
+
const C = (A) => {
|
|
353
|
+
t.isVariableDeclaration(A) && A.name.getText() === "val" && ($ = v.getTypeAtLocation(A)), t.forEachChild(A, C);
|
|
354
|
+
};
|
|
355
|
+
C(f), $ && F($);
|
|
356
|
+
}
|
|
357
|
+
return _;
|
|
358
|
+
};
|
|
359
|
+
if (n.inputType) {
|
|
360
|
+
const i = n.inputType.identifier || "any";
|
|
361
|
+
c.push(...m(i, {
|
|
362
|
+
__typename: "ReferenceValue",
|
|
363
|
+
nodeFunctionId: null,
|
|
364
|
+
parameterIndex: 0,
|
|
365
|
+
referencePath: []
|
|
366
|
+
}));
|
|
367
|
+
}
|
|
368
|
+
u.forEach((i) => {
|
|
369
|
+
if (!(!i || i.id === s) && H(n, i, d)) {
|
|
370
|
+
const g = W(n, i, e, o);
|
|
371
|
+
c.push(...m(g.inferredType, {
|
|
372
|
+
__typename: "ReferenceValue",
|
|
373
|
+
nodeFunctionId: i.id,
|
|
374
|
+
referencePath: []
|
|
375
|
+
}));
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
let a = k(n, s);
|
|
379
|
+
for (; a; ) {
|
|
380
|
+
if (e.find((g) => g.identifier === a.functionDefinition?.identifier)) {
|
|
381
|
+
const g = a.parameters?.nodes?.findIndex((_) => {
|
|
382
|
+
const T = _?.value;
|
|
383
|
+
if (T?.__typename === "NodeFunctionIdWrapper") {
|
|
384
|
+
const h = T;
|
|
385
|
+
return h.id === s || U(n, h.id || void 0, s);
|
|
386
|
+
}
|
|
387
|
+
return !1;
|
|
388
|
+
});
|
|
389
|
+
g !== void 0 && g !== -1 && c.push(...m("any", {
|
|
390
|
+
__typename: "ReferenceValue",
|
|
391
|
+
nodeFunctionId: a.id,
|
|
392
|
+
parameterIndex: g,
|
|
393
|
+
inputIndex: 0,
|
|
394
|
+
referencePath: []
|
|
395
|
+
}));
|
|
396
|
+
}
|
|
397
|
+
a = k(n, a.id);
|
|
398
|
+
}
|
|
399
|
+
return c;
|
|
400
|
+
};
|
|
401
|
+
function H(n, s, r) {
|
|
402
|
+
const e = n.nodes?.nodes || [];
|
|
403
|
+
let o = s.nextNodeId;
|
|
404
|
+
const c = /* @__PURE__ */ new Set();
|
|
405
|
+
for (; o; ) {
|
|
406
|
+
if (o === r.id) return !0;
|
|
407
|
+
if (c.has(o)) break;
|
|
408
|
+
c.add(o), o = e.find((y) => y?.id === o)?.nextNodeId;
|
|
409
|
+
}
|
|
410
|
+
let u = k(n, r.id);
|
|
411
|
+
for (; u; ) {
|
|
412
|
+
if (u.id === s.id) return !0;
|
|
413
|
+
u = k(n, u.id);
|
|
414
|
+
}
|
|
415
|
+
return !1;
|
|
416
|
+
}
|
|
417
|
+
function k(n, s) {
|
|
418
|
+
return n.nodes?.nodes?.find(
|
|
419
|
+
(e) => e?.parameters?.nodes?.some(
|
|
420
|
+
(o) => o?.value?.__typename === "NodeFunctionIdWrapper" && o.value.id === s
|
|
421
|
+
)
|
|
422
|
+
) || void 0;
|
|
423
|
+
}
|
|
424
|
+
function U(n, s, r) {
|
|
425
|
+
if (!s) return !1;
|
|
426
|
+
if (s === r) return !0;
|
|
427
|
+
const o = (n.nodes?.nodes || []).find((u) => u?.id === s);
|
|
428
|
+
return o ? o.nextNodeId && U(n, o.nextNodeId || void 0, r) ? !0 : !!o.parameters?.nodes?.some((u) => {
|
|
429
|
+
const d = u?.value;
|
|
430
|
+
return d?.__typename === "NodeFunctionIdWrapper" ? U(n, d.id || void 0, r) : !1;
|
|
431
|
+
}) : !1;
|
|
432
|
+
}
|
|
433
|
+
const te = (n) => {
|
|
434
|
+
const r = `const tempValue = ${JSON.stringify(n.value)};`, e = "temp_value.ts", o = t.createSourceFile(e, r, t.ScriptTarget.Latest), c = I(e, r, o), d = t.createProgram([e], { target: t.ScriptTarget.Latest, noEmit: !0 }, c).getTypeChecker();
|
|
435
|
+
let y = "any";
|
|
436
|
+
const p = (m) => {
|
|
437
|
+
if (t.isVariableDeclaration(m) && m.name.getText() === "tempValue") {
|
|
438
|
+
const a = d.getTypeAtLocation(m);
|
|
439
|
+
y = d.typeToString(
|
|
440
|
+
a,
|
|
441
|
+
m,
|
|
442
|
+
t.TypeFormatFlags.NoTruncation | t.TypeFormatFlags.UseFullyQualifiedType
|
|
443
|
+
);
|
|
444
|
+
}
|
|
445
|
+
t.forEachChild(m, p);
|
|
446
|
+
};
|
|
447
|
+
return p(o), y;
|
|
448
|
+
};
|
|
449
|
+
var q = /* @__PURE__ */ ((n) => (n[n.PRIMITIVE = 0] = "PRIMITIVE", n[n.TYPE = 1] = "TYPE", n[n.ARRAY = 2] = "ARRAY", n[n.OBJECT = 3] = "OBJECT", n))(q || {});
|
|
450
|
+
const ne = (n, s) => {
|
|
451
|
+
const r = E(s), e = `type_probe_${Math.random().toString(36).substring(7)}.ts`, o = `
|
|
452
|
+
${r}
|
|
453
|
+
type TargetType = ${n};
|
|
454
|
+
const val: TargetType = {} as any;
|
|
455
|
+
`, c = t.createSourceFile(e, o, t.ScriptTarget.Latest), u = I(e, o, c), y = t.createProgram([e], x, u).getTypeChecker();
|
|
456
|
+
let p = 1;
|
|
457
|
+
const m = (a) => {
|
|
458
|
+
if (t.isVariableDeclaration(a) && a.name.getText() === "val") {
|
|
459
|
+
const i = y.getTypeAtLocation(a);
|
|
460
|
+
y.isArrayType(i) ? p = 2 : i.isStringLiteral() || i.isNumberLiteral() || (i.getFlags() & (t.TypeFlags.String | t.TypeFlags.Number | t.TypeFlags.Boolean | t.TypeFlags.EnumLiteral | t.TypeFlags.BigInt | t.TypeFlags.ESSymbol)) !== 0 ? p = 0 : (i.isClassOrInterface() || (i.getFlags() & t.TypeFlags.Object) !== 0) && i.getProperties().length > 0 ? p = 3 : p = 1;
|
|
461
|
+
}
|
|
462
|
+
t.forEachChild(a, m);
|
|
463
|
+
};
|
|
464
|
+
return m(c), p;
|
|
465
|
+
}, re = (n, s) => {
|
|
466
|
+
const r = `
|
|
467
|
+
${E(s)}
|
|
468
|
+
type Target = ${n};
|
|
469
|
+
`, e = "temp_type_to_value.ts", o = t.createSourceFile(e, r, t.ScriptTarget.Latest, !0), c = I(e, r, o), d = t.createProgram([e], x, c).getTypeChecker(), y = o.statements.find(
|
|
470
|
+
(i) => t.isTypeAliasDeclaration(i) && i.name.text === "Target"
|
|
471
|
+
);
|
|
472
|
+
if (!y)
|
|
473
|
+
return { __typename: "LiteralValue", value: null };
|
|
474
|
+
const p = d.getTypeAtLocation(y.type), m = (i, g, _ = /* @__PURE__ */ new Set()) => {
|
|
475
|
+
if (_.has(i)) return null;
|
|
476
|
+
_.add(i);
|
|
477
|
+
const T = i.getFlags();
|
|
478
|
+
if (i.isUnion()) {
|
|
479
|
+
if (g.type, t.isTypeAliasDeclaration(g) && g.type && t.isUnionTypeNode(g.type)) {
|
|
480
|
+
const N = d.getTypeFromTypeNode(g.type.types[0]);
|
|
481
|
+
return m(N, g, _);
|
|
482
|
+
}
|
|
483
|
+
const h = i.types.filter((N) => {
|
|
484
|
+
const l = N.getFlags();
|
|
485
|
+
return !(l & t.TypeFlags.Undefined) && !(l & t.TypeFlags.Null);
|
|
486
|
+
}), f = h.length > 0 ? h[0] : i.types[0];
|
|
487
|
+
return m(f, g, _);
|
|
488
|
+
}
|
|
489
|
+
if (T & t.TypeFlags.StringLiteral) return i.value;
|
|
490
|
+
if (T & t.TypeFlags.String) return "sample";
|
|
491
|
+
if (T & t.TypeFlags.NumberLiteral) return i.value;
|
|
492
|
+
if (T & t.TypeFlags.Number) return 1;
|
|
493
|
+
if (T & t.TypeFlags.BooleanLiteral) return i.intrinsicName === "true";
|
|
494
|
+
if (T & t.TypeFlags.Boolean) return !1;
|
|
495
|
+
if (d.isArrayType(i)) {
|
|
496
|
+
const f = i.typeArguments?.[0] || d.getAnyType();
|
|
497
|
+
return [m(f, g, _)];
|
|
498
|
+
}
|
|
499
|
+
if (i.isClassOrInterface() || T & t.TypeFlags.Object || i.getProperties().length > 0) {
|
|
500
|
+
const h = {};
|
|
501
|
+
return i.getProperties().forEach((N) => {
|
|
502
|
+
const l = d.getTypeOfSymbolAtLocation(N, g);
|
|
503
|
+
l && (h[N.getName()] = m(l, g, _));
|
|
504
|
+
}), h;
|
|
505
|
+
}
|
|
506
|
+
return null;
|
|
507
|
+
};
|
|
508
|
+
return {
|
|
509
|
+
value: m(p, y)
|
|
510
|
+
};
|
|
511
|
+
}, ie = (n) => {
|
|
512
|
+
if (!n) return [];
|
|
513
|
+
const s = `type T = ${n}; const val: T = {} as any;`, r = "suggestions_virtual.ts", e = t.createSourceFile(r, s, t.ScriptTarget.Latest), o = I(r, s, e), u = t.createProgram([r], { ...x, noLib: !0 }, o).getTypeChecker(), d = e.statements.find(t.isTypeAliasDeclaration);
|
|
514
|
+
if (!d) return [];
|
|
515
|
+
const y = u.getTypeAtLocation(d), p = (a) => a.isUnion() ? a.types.flatMap(p) : a.isStringLiteral() ? [a.value] : a.isNumberLiteral() ? [a.value.toString()] : a.intrinsicName === "true" ? ["true"] : a.intrinsicName === "false" ? ["false"] : [];
|
|
516
|
+
return Array.from(new Set(p(y))).map((a) => ({
|
|
517
|
+
__typename: "LiteralValue",
|
|
518
|
+
value: a
|
|
519
|
+
}));
|
|
520
|
+
}, se = (n, s, r) => {
|
|
521
|
+
const e = JSON.stringify(s.value), o = `
|
|
522
|
+
${E(r)}
|
|
523
|
+
const testValue: ${n} = ${e};
|
|
524
|
+
`, c = "value_check.ts", u = t.createSourceFile(c, o, t.ScriptTarget.Latest), d = I(c, o, u), p = t.createProgram([c], x, d).getSemanticDiagnostics(u);
|
|
525
|
+
return p.length > 0 ? {
|
|
526
|
+
isValid: !1,
|
|
527
|
+
error: t.flattenDiagnosticMessageText(p[0].messageText, `
|
|
528
|
+
`)
|
|
529
|
+
} : { isValid: !0 };
|
|
530
|
+
}, oe = (n, s, r) => {
|
|
531
|
+
const o = new Map(s.map((l) => [l.identifier, l])).get(n.functionDefinition?.identifier);
|
|
532
|
+
if (!o)
|
|
533
|
+
return {
|
|
534
|
+
parameters: [],
|
|
535
|
+
returnType: "any"
|
|
536
|
+
};
|
|
537
|
+
const c = {
|
|
538
|
+
id: "gid://sagittarius/Flow/0",
|
|
539
|
+
nodes: { __typename: "NodeFunctionConnection", nodes: [n] }
|
|
540
|
+
}, y = (n.parameters?.nodes || []).map((l) => K(l, c, (v, F) => W(v, F, s, r))).map((l) => l === "undefined" ? "({} as any)" : l).join(", "), p = o.signature, m = `
|
|
541
|
+
${E(r)}
|
|
542
|
+
declare function testFunc${p};
|
|
543
|
+
const result = testFunc(${y});
|
|
544
|
+
`, a = "node_types_virtual.ts", i = t.createSourceFile(a, m, t.ScriptTarget.Latest), g = I(a, m, i), T = t.createProgram([a], x, g).getTypeChecker();
|
|
545
|
+
let h = "any", f = [];
|
|
546
|
+
const N = (l) => {
|
|
547
|
+
if (t.isVariableDeclaration(l) && l.name.getText() === "result") {
|
|
548
|
+
const v = T.getTypeAtLocation(l);
|
|
549
|
+
if (h = T.typeToString(
|
|
550
|
+
v,
|
|
551
|
+
l,
|
|
552
|
+
t.TypeFormatFlags.NoTruncation
|
|
553
|
+
), t.isCallExpression(l.initializer)) {
|
|
554
|
+
const F = l.initializer, S = T.getResolvedSignature(F);
|
|
555
|
+
S && (f = S.getParameters().map(($) => {
|
|
556
|
+
const C = T.getTypeOfSymbolAtLocation($, F);
|
|
557
|
+
return T.typeToString(
|
|
558
|
+
C,
|
|
559
|
+
F,
|
|
560
|
+
t.TypeFormatFlags.NoTruncation
|
|
561
|
+
);
|
|
562
|
+
}));
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
t.forEachChild(l, N);
|
|
566
|
+
};
|
|
567
|
+
return N(i), {
|
|
568
|
+
parameters: f,
|
|
569
|
+
returnType: h
|
|
570
|
+
};
|
|
571
|
+
};
|
|
572
|
+
export {
|
|
573
|
+
q as DataTypeVariant,
|
|
574
|
+
Z as getFlowValidation,
|
|
575
|
+
X as getNodeSuggestions,
|
|
576
|
+
W as getNodeValidation,
|
|
577
|
+
ee as getReferenceSuggestions,
|
|
578
|
+
te as getTypeFromValue,
|
|
579
|
+
ne as getTypeVariant,
|
|
580
|
+
oe as getTypesFromNode,
|
|
581
|
+
re as getValueFromType,
|
|
582
|
+
ie as getValueSuggestions,
|
|
583
|
+
se as getValueValidation
|
|
584
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@code0-tech/triangulum",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"homepage": "https://github.com/code0-tech/triangulum#readme",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/code0-tech/triangulum/issues"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/code0-tech/triangulum.git"
|
|
12
|
+
},
|
|
13
|
+
"author": "CodeZero",
|
|
14
|
+
"type": "module",
|
|
15
|
+
"main": "./dist/triangulum.cjs.js",
|
|
16
|
+
"module": "./dist/triangulum.es.js",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/triangulum.es.js",
|
|
22
|
+
"require": "./dist/triangulum.cjs.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist"
|
|
27
|
+
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"test": "vitest run",
|
|
30
|
+
"build": "vite build"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"typescript": "^5.9.3"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@code0-tech/sagittarius-graphql-types": "0.0.0-experimental-2342308809-931efb40b4bf3245999c53abbdd9164cea82e82d",
|
|
37
|
+
"@types/node": "^25.3.2",
|
|
38
|
+
"vite": "^7.3.1",
|
|
39
|
+
"vite-plugin-dts": "^4.5.4",
|
|
40
|
+
"vitest": "^4.0.18"
|
|
41
|
+
}
|
|
42
|
+
}
|