Skip to content

Commit bf2925e

Browse files
author
nicosammito
committed
feat: reorganize module structure and update imports for validation and suggestion functionalities
1 parent 5ca7176 commit bf2925e

24 files changed

Lines changed: 350 additions & 279 deletions

src/data.ts

Lines changed: 0 additions & 87 deletions
This file was deleted.
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import ts from "typescript";
2-
import {createCompilerHost} from "./utils";
2+
import {createCompilerHost} from "../utils";
3+
import {LiteralValue} from "@code0-tech/sagittarius-graphql-types";
34

45
/**
56
* Uses the TypeScript compiler to generate a precise type string from any runtime value.
67
*/
7-
export const getTypeFromValue = (value: any): string => {
8+
export const getTypeFromValue = (value: LiteralValue): string => {
89
// 1. Serialize value to a JSON string for embedding in source code.
9-
const literal = JSON.stringify(value);
10+
const literal = JSON.stringify(value.value);
1011

1112
// 2. Wrap value in virtual source code.
1213
const sourceCode = `const tempValue = ${literal};`;
Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import ts from "typescript";
2-
import {ExtendedDataType, getSharedTypeDeclarations, createCompilerHost, DEFAULT_COMPILER_OPTIONS} from "./utils";
2+
import {ExtendedDataType, getSharedTypeDeclarations, createCompilerHost, DEFAULT_COMPILER_OPTIONS} from "../utils";
33

4-
export enum Variant {
4+
export enum DataTypeVariant {
55
PRIMITIVE,
66
TYPE,
77
ARRAY,
@@ -12,16 +12,16 @@ export enum Variant {
1212
* Determines the variant of a given TypeScript type string using the TS compiler.
1313
*/
1414
export const getTypeVariant = (
15-
typeString: string,
15+
type: string,
1616
dataTypes: ExtendedDataType[]
17-
): Variant => {
17+
): DataTypeVariant => {
1818
const typeDefs = getSharedTypeDeclarations(dataTypes);
1919
const fileName = `type_probe_${Math.random().toString(36).substring(7)}.ts`;
2020

2121
// We declare a variable with the type to probe it
2222
const sourceCode = `
2323
${typeDefs}
24-
type TargetType = ${typeString};
24+
type TargetType = ${type};
2525
const val: TargetType = {} as any;
2626
`;
2727

@@ -30,29 +30,29 @@ export const getTypeVariant = (
3030
const program = ts.createProgram([fileName], DEFAULT_COMPILER_OPTIONS, host);
3131
const checker = program.getTypeChecker();
3232

33-
let discoveredVariant: Variant = Variant.TYPE;
33+
let discoveredVariant: DataTypeVariant = DataTypeVariant.TYPE;
3434

3535
const visit = (node: ts.Node) => {
3636
if (ts.isVariableDeclaration(node) && node.name.getText() === "val") {
3737
const type = checker.getTypeAtLocation(node);
3838

3939
if (checker.isArrayType(type)) {
40-
discoveredVariant = Variant.ARRAY;
40+
discoveredVariant = DataTypeVariant.ARRAY;
4141
} else if (
4242
type.isStringLiteral() ||
4343
type.isNumberLiteral() ||
4444
(type.getFlags() & (ts.TypeFlags.String | ts.TypeFlags.Number | ts.TypeFlags.Boolean | ts.TypeFlags.EnumLiteral | ts.TypeFlags.BigInt | ts.TypeFlags.ESSymbol)) !== 0
4545
) {
46-
discoveredVariant = Variant.PRIMITIVE;
46+
discoveredVariant = DataTypeVariant.PRIMITIVE;
4747
} else if (type.isClassOrInterface() || (type.getFlags() & ts.TypeFlags.Object) !== 0) {
4848
// Check if it's literally just a type alias to something else or a complex object
4949
if (type.getProperties().length > 0) {
50-
discoveredVariant = Variant.OBJECT;
50+
discoveredVariant = DataTypeVariant.OBJECT;
5151
} else {
52-
discoveredVariant = Variant.TYPE;
52+
discoveredVariant = DataTypeVariant.TYPE;
5353
}
5454
} else {
55-
discoveredVariant = Variant.TYPE;
55+
discoveredVariant = DataTypeVariant.TYPE;
5656
}
5757
}
5858
ts.forEachChild(node, visit);

src/extraction/getTypesFromFunction.ts

Whitespace-only changes.

src/extraction/getTypesFromNode.ts

Whitespace-only changes.
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import ts from "typescript";
22
import {LiteralValue} from "@code0-tech/sagittarius-graphql-types";
3-
import {createCompilerHost, DEFAULT_COMPILER_OPTIONS, getSharedTypeDeclarations, ExtendedDataType} from "./utils";
3+
import {createCompilerHost, DEFAULT_COMPILER_OPTIONS, ExtendedDataType, getSharedTypeDeclarations} from "../utils";
44

55
/**
66
* Generates a sample LiteralValue from a TypeScript type string.
77
*/
88
export const getValueFromType = (
9-
targetType: string,
9+
type: string,
1010
dataTypes: ExtendedDataType[]
1111
): LiteralValue => {
1212
// 1. Prepare declarations.
1313
const sourceCode = `
1414
${getSharedTypeDeclarations(dataTypes)}
15-
type Target = ${targetType};
15+
type Target = ${type};
1616
`;
1717

1818
const fileName = "temp_type_to_value.ts";
@@ -34,7 +34,7 @@ export const getValueFromType = (
3434
return {__typename: 'LiteralValue', value: null};
3535
}
3636

37-
const type = checker.getTypeAtLocation(targetNode.type);
37+
const typeFound = checker.getTypeAtLocation(targetNode.type);
3838

3939
/**
4040
* Recursively generates a sample JavaScript value for a given TypeScript Type.
@@ -98,7 +98,7 @@ export const getValueFromType = (
9898
return null;
9999
};
100100

101-
const sample = generateSample(type, targetNode);
101+
const sample = generateSample(typeFound, targetNode);
102102

103103
// Test Expectation: result.value should be null for unknown types.
104104
// However, if we return null from the function, result.value access fails.

src/index.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
export * from './data';
2-
export * from './getFlowValidation';
3-
export * from './getNodeSuggestions';
4-
export * from './getNodeValidation';
5-
export * from './getReferenceSuggestions';
6-
export * from './getTypeFromValue';
7-
export * from './getTypeVariant';
8-
export * from './getValueFromType';
9-
export * from './getValueSuggestions';
10-
export * from './getValueValidation';
11-
export * from './utils';
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';
1210

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,49 @@
11
import {NodeFunction} from "@code0-tech/sagittarius-graphql-types";
22
import ts from "typescript";
3-
import {ExtendedFunction, createCompilerHost, DEFAULT_COMPILER_OPTIONS, getSharedTypeDeclarations} from "./utils";
4-
import {DATA_TYPES} from "./data";
3+
import {createCompilerHost, DEFAULT_COMPILER_OPTIONS, ExtendedFunction, getSharedTypeDeclarations} from "../utils";
4+
import {DATA_TYPES} from "../../test/data";
55

66
/**
77
* Suggests NodeFunctions based on a given type and a list of available FunctionDefinitions.
88
* Returns functions whose return type is compatible with the target type.
99
*/
10-
export function getNodeSuggestions(targetType: string, functions: ExtendedFunction[]): NodeFunction[] {
11-
if (!targetType || !functions || functions.length === 0) {
10+
export function getNodeSuggestions(type: string, functions: ExtendedFunction[]): NodeFunction[] {
11+
if (!type || !functions || functions.length === 0) {
1212
return [];
1313
}
1414

1515
const fileName = "suggestions.ts";
1616

1717
const sharedTypes = getSharedTypeDeclarations(DATA_TYPES);
1818

19+
function getGenericsCount(input: string): number {
20+
const match = input.match(/<([^>]+)>/);
21+
if (!match) return 0;
22+
return match[1].split(',').map(s => s.trim()).filter(Boolean).length;
23+
}
24+
1925
const sourceCode = `
2026
${sharedTypes}
21-
type TargetType = ${targetType};
27+
type TargetType = ${type};
2228
${functions.map((f, i) => {
23-
const generics = f.genericKeys && f.genericKeys.length > 0
24-
? `<${f.genericKeys.map(k => `${k} = any`).join(",")}>`
25-
: "";
26-
return `type F${i}${generics} = ${f.returnType};`;
27-
}).join("\n")}
29+
30+
return `
31+
declare function Fu${i}${f.signature};
32+
type F${i} = ReturnType<typeof Fu${i}${getGenericsCount(f.signature) > 0 ? `<${Array(getGenericsCount(f.signature)).fill("any").join(", ")}>` : ""}>;
33+
`;
34+
}).join("\n")}
2835
${functions.map((_, i) => `const check${i}: TargetType = {} as F${i};`).join("\n")}
2936
`;
3037

38+
console.log(sourceCode)
39+
3140
const sourceFile = ts.createSourceFile(fileName, sourceCode, ts.ScriptTarget.Latest);
3241
const host = createCompilerHost(fileName, sourceCode, sourceFile);
3342
const program = ts.createProgram([fileName], {
3443
...DEFAULT_COMPILER_OPTIONS
3544
}, host);
3645

37-
const diagnostics = ts.getPreEmitDiagnostics(program);
46+
const diagnostics = program.getSemanticDiagnostics();
3847
const errorLines = new Set<number>();
3948
diagnostics.forEach(diag => {
4049
if (diag.file === sourceFile && diag.start !== undefined) {
@@ -49,6 +58,8 @@ export function getNodeSuggestions(targetType: string, functions: ExtendedFuncti
4958
const lines = sourceCode.split("\n");
5059
const actualLine = lines.findIndex(l => l.includes(lineToMatch));
5160

61+
62+
5263
if (actualLine !== -1 && errorLines.has(actualLine)) {
5364
return null;
5465
}
@@ -63,12 +74,12 @@ export function getNodeSuggestions(targetType: string, functions: ExtendedFuncti
6374
},
6475
parameters: {
6576
__typename: "NodeParameterConnection",
66-
nodes: (f.parameters?.nodes || []).map(p => ({
77+
nodes: (f.parameterDefinitions?.nodes || []).map(p => ({
6778
__typename: "NodeParameter",
6879
parameterDefinition: {
6980
__typename: "ParameterDefinition",
70-
id: p.identifier as any,
71-
identifier: p.identifier
81+
id: p?.identifier as any,
82+
identifier: p?.identifier
7283
},
7384
value: null
7485
}))

0 commit comments

Comments
 (0)