Skip to content

Commit

Permalink
Integrate monorepo changes (#3)
Browse files Browse the repository at this point in the history
* feat: Add Next.js codebase scanning and server action generation

- Add Next.js specific types, scanner, and generator
- Update root index.ts to use consistent export strategy

* feat: add type support for jest

- Add new function `analyzeNextjsSourceFiles` to handle the source files
- Update `scanNextjsCodebase` to call `analyzeNextjsSourceFiles` and return the result
- Add tests
- Update imports
- add @next/eslint-plugin-next to next project

* Refactor code generation to use Blocks architecture

- Added Block and FunctionCallBlock types
- Separated functions from functions.ts into smaller, focused modules
- Introduced a new Blocks-based approach for code generation
- Restructured the project directory:
  * Added generator/blocks directory for block-specific logic
  * Created block-generator.ts for handling block-to-TypeScript conversion
  * Updated code-generator.ts to use the new Blocks system
- Migrated existing functionality to work with the new Blocks structure
- Temporarily removed unit tests (will be added later)

* feat: switch to block based code generation

- create `CodeGeneratorState` to keep track of blocks and variables when generating code
-  add `createFunctionCallBlock` to create block using function info
- add `functionCallBlockToTypeScript` to create TypeScript statements using blocks
- refactor `generateCode` and `blockToTypeScript` to use code generator state
- export new added functions
- update readme

* Extracted ts-codegenerator from monorepo
  • Loading branch information
ozhanefemeral authored Jul 26, 2024
1 parent 6810e71 commit d97f944
Show file tree
Hide file tree
Showing 20 changed files with 844 additions and 459 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
dist
.npmrc
.npmrc
bun.lockb
24 changes: 20 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@

- **Module Parsing**: Extract information about functions, variables and types
- **Code Generation**: Generate new TypeScript code based on parsed information.
- **Block-based Code Generation**: New 'Blocks' concept for more flexible code generation.
- **Function Call Generation**: Create TypeScript AST nodes for function calls, including handling of async functions and Promises.
- **Variable Declaration Generation**: Generate variable declarations with associated function calls.
- **Unique Variable Naming**: Automatically generate unique variable names to avoid conflicts when generating code.
- **Type Extraction**: Extract and process return types from functions, including handling of Promise types.

## Installation

Install the package using pnpm:
Install the package using bun:

```bash
pnpm add @ozhanefe/ts-codegenerator
bun add @ozhanefe/ts-codegenerator
```

Note: This package requires TypeScript as a peer dependency. Make sure you have TypeScript installed in your project.
Expand All @@ -25,16 +26,31 @@ Note: This package requires TypeScript as a peer dependency. Make sure you have

Here's a basic example of how to use the package:

import { parseFunctionsFromFile, generateCode } from '@ozhanefe/ts-codegenerator';
```typescript
import {
parseFunctionsFromFile,
generateCode,
} from "@ozhanefe/ts-codegenerator";

// Parse functions from a TypeScript file
const { functionsInfo } = parseFunctionsFromFile('path/to/your/file.ts');
const { functionsInfo } = parseFunctionsFromFile("path/to/your/file.ts");

// Generate new code based on the parsed functions
const generatedCode = generateCode(functionsInfo);

console.log(generatedCode);
```

## Running Tests

To run the unit tests, including the new tests for the function call block generator:

```bash
bun test
```

## Contributing

Contributions are welcome! Please create an issue or pull request if you have any suggestions or feedback.

p.s: We manually set the version of '@ozhanefe/ts-codegenerator' package in the apps isntead of linking from the local package. So what we work on does not affect the apps.
166 changes: 166 additions & 0 deletions dist/index.d.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import { Node, SourceFile } from 'ts-morph';
import { Statement, VariableStatement, CallExpression, AwaitExpression } from 'typescript';

interface VariableInfo {
name: string;
type: string;
}
interface FunctionInfo {
name: string;
returnType: string;
jsDocComment?: string;
code?: string;
variables?: VariableInfo[];
returnVariable?: VariableInfo;
parameters?: VariableInfo[];
}
interface VariableInfoWithIndex extends VariableInfo {
index: number;
}
interface TypeInfo {
name: string;
properties?: Array<{
name: string;
type: string;
}>;
methods?: Array<FunctionInfo>;
extends?: string[];
implements?: string[];
}

interface Block {
index: number;
comment?: string;
blockType: string;
}
interface FunctionCallBlock extends Block {
functionInfo: FunctionInfo;
parameters?: VariableInfo[];
returnVariable: VariableInfo;
isAsync: boolean;
blockType: "functionCall";
}
type CodeBlock = FunctionCallBlock;

interface CodebaseInfo {
functions: FunctionInfo[];
types: TypeInfo[];
}
interface ModuleInfoFields {
fileName: string;
interfaces: string[];
functions: FunctionInfo[];
fileContent: string;
usedTypes: string[];
}

interface CodeGeneratorState {
blocks: CodeBlock[];
variables: VariableInfoWithIndex[];
isAsync: boolean;
}

declare function getFunctionInfoFromNode(node: Node): FunctionInfo | null;
declare function parseFunctionsFromText(sourceCode: string): {
functionsInfo: FunctionInfo[];
usedTypes: string[];
};

declare function getFunctionVariables(sourceFile: SourceFile, functionName: string): VariableInfo[] | undefined;

declare function blockToTypeScript(block: CodeBlock, state: CodeGeneratorState | {
variables: VariableInfoWithIndex[];
}): Statement;

declare function generateCode(blocks: CodeBlock[]): string;

/**
* Finds a variable by type.
* @param variables Available variables.
* @param type Type to search for.
* @param latest Whether to return the latest matching variable.
* @param toIndex Upper bound index to search.
* @returns Matching variable information or undefined.
*/
declare function findVariableByType(variables: VariableInfoWithIndex[], type: string, latest?: boolean, toIndex?: number): VariableInfoWithIndex | undefined;
/**
* Generates a unique variable name.
* @param baseName The base name for the variable.
* @param variables Existing variables.
* @returns A unique variable name.
*/
declare function getUniqueVariableName(baseName: string, variables: VariableInfoWithIndex[]): string;
/**
* Extracts the return type from a function's return type string.
* @param returnType The return type string of a function.
* @returns The extracted return type.
*/
declare function extractReturnType(returnType: string | undefined): string;
/**
* Extracts variables from function information.
* @param functionInfos Array of function information.
* @returns Array of variable information with index.
*/
declare function extractVariables(functionInfos: FunctionInfo[]): VariableInfoWithIndex[];

/**
* Creates a variable declaration with a function call.
*
* @param {FunctionCallBlock} block - The block containing information about the function to call.
* @param {VariableInfoWithIndex[]} variables - The available variables.
* @return {VariableStatement} The created variable declaration with a function call.
*/
declare function createVariableWithFunctionCall(block: FunctionCallBlock, state: CodeGeneratorState | {
variables: VariableInfoWithIndex[];
}): VariableStatement;
/**
* Creates a function call expression.
* @param functionInfo Information about the function to call.
* @param variables Available variables to use as parameters.
* @param index Current index in the function sequence.
* @returns A CallExpression or AwaitExpression.
*/
declare function createFunctionCall(functionInfo: FunctionInfo, variables: VariableInfoWithIndex[], index: number): CallExpression | AwaitExpression;
/**
* Creates a function call block.
*
* @param {FunctionInfo} functionInfo - Information about the function to call.
* @param {CodeGeneratorState} state - The current state of the code generator.
* @return {FunctionCallBlock} The created function call block.
*/
declare function createFunctionCallBlock(functionInfo: FunctionInfo, state: CodeGeneratorState): FunctionCallBlock;
/**
* Converts a function call block into a TypeScript variable statement.
*
* @param {FunctionCallBlock} block - The function call block to convert.
* @param {CodeGeneratorState | { variables: VariableInfoWithIndex[] }} state - The state of the code generator.
* @return {VariableStatement} The TypeScript variable statement representing the function call block.
*/
declare function functionCallBlockToTypeScript(block: FunctionCallBlock, state: CodeGeneratorState | {
variables: VariableInfoWithIndex[];
}): VariableStatement;

declare function scanCodebase(projectPath: string): CodebaseInfo;

interface ServerActionInfo extends FunctionInfo {
filePath: string;
}
interface NextCodebaseInfo {
serverActions: ServerActionInfo[];
}

declare function scanNextjsCodebase(projectPath: string): NextCodebaseInfo;
declare function analyzeNextjsSourceFiles(sourceFiles: SourceFile[]): NextCodebaseInfo;

declare function generateServerAction(info: ServerActionInfo): string;

type index_NextCodebaseInfo = NextCodebaseInfo;
type index_ServerActionInfo = ServerActionInfo;
declare const index_analyzeNextjsSourceFiles: typeof analyzeNextjsSourceFiles;
declare const index_generateServerAction: typeof generateServerAction;
declare const index_scanNextjsCodebase: typeof scanNextjsCodebase;
declare namespace index {
export { type index_NextCodebaseInfo as NextCodebaseInfo, type index_ServerActionInfo as ServerActionInfo, index_analyzeNextjsSourceFiles as analyzeNextjsSourceFiles, index_generateServerAction as generateServerAction, index_scanNextjsCodebase as scanNextjsCodebase };
}

export { type Block, type CodebaseInfo, type FunctionCallBlock, type FunctionInfo, type ModuleInfoFields, type NextCodebaseInfo, index as NextJS, type ServerActionInfo, type TypeInfo, type VariableInfo, type VariableInfoWithIndex, blockToTypeScript, createFunctionCall, createFunctionCallBlock, createVariableWithFunctionCall, extractReturnType, extractVariables, findVariableByType, functionCallBlockToTypeScript, generateCode, generateServerAction, getFunctionInfoFromNode, getFunctionVariables, getUniqueVariableName, parseFunctionsFromText, scanCodebase, scanNextjsCodebase };
166 changes: 166 additions & 0 deletions dist/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import { Node, SourceFile } from 'ts-morph';
import { Statement, VariableStatement, CallExpression, AwaitExpression } from 'typescript';

interface VariableInfo {
name: string;
type: string;
}
interface FunctionInfo {
name: string;
returnType: string;
jsDocComment?: string;
code?: string;
variables?: VariableInfo[];
returnVariable?: VariableInfo;
parameters?: VariableInfo[];
}
interface VariableInfoWithIndex extends VariableInfo {
index: number;
}
interface TypeInfo {
name: string;
properties?: Array<{
name: string;
type: string;
}>;
methods?: Array<FunctionInfo>;
extends?: string[];
implements?: string[];
}

interface Block {
index: number;
comment?: string;
blockType: string;
}
interface FunctionCallBlock extends Block {
functionInfo: FunctionInfo;
parameters?: VariableInfo[];
returnVariable: VariableInfo;
isAsync: boolean;
blockType: "functionCall";
}
type CodeBlock = FunctionCallBlock;

interface CodebaseInfo {
functions: FunctionInfo[];
types: TypeInfo[];
}
interface ModuleInfoFields {
fileName: string;
interfaces: string[];
functions: FunctionInfo[];
fileContent: string;
usedTypes: string[];
}

interface CodeGeneratorState {
blocks: CodeBlock[];
variables: VariableInfoWithIndex[];
isAsync: boolean;
}

declare function getFunctionInfoFromNode(node: Node): FunctionInfo | null;
declare function parseFunctionsFromText(sourceCode: string): {
functionsInfo: FunctionInfo[];
usedTypes: string[];
};

declare function getFunctionVariables(sourceFile: SourceFile, functionName: string): VariableInfo[] | undefined;

declare function blockToTypeScript(block: CodeBlock, state: CodeGeneratorState | {
variables: VariableInfoWithIndex[];
}): Statement;

declare function generateCode(blocks: CodeBlock[]): string;

/**
* Finds a variable by type.
* @param variables Available variables.
* @param type Type to search for.
* @param latest Whether to return the latest matching variable.
* @param toIndex Upper bound index to search.
* @returns Matching variable information or undefined.
*/
declare function findVariableByType(variables: VariableInfoWithIndex[], type: string, latest?: boolean, toIndex?: number): VariableInfoWithIndex | undefined;
/**
* Generates a unique variable name.
* @param baseName The base name for the variable.
* @param variables Existing variables.
* @returns A unique variable name.
*/
declare function getUniqueVariableName(baseName: string, variables: VariableInfoWithIndex[]): string;
/**
* Extracts the return type from a function's return type string.
* @param returnType The return type string of a function.
* @returns The extracted return type.
*/
declare function extractReturnType(returnType: string | undefined): string;
/**
* Extracts variables from function information.
* @param functionInfos Array of function information.
* @returns Array of variable information with index.
*/
declare function extractVariables(functionInfos: FunctionInfo[]): VariableInfoWithIndex[];

/**
* Creates a variable declaration with a function call.
*
* @param {FunctionCallBlock} block - The block containing information about the function to call.
* @param {VariableInfoWithIndex[]} variables - The available variables.
* @return {VariableStatement} The created variable declaration with a function call.
*/
declare function createVariableWithFunctionCall(block: FunctionCallBlock, state: CodeGeneratorState | {
variables: VariableInfoWithIndex[];
}): VariableStatement;
/**
* Creates a function call expression.
* @param functionInfo Information about the function to call.
* @param variables Available variables to use as parameters.
* @param index Current index in the function sequence.
* @returns A CallExpression or AwaitExpression.
*/
declare function createFunctionCall(functionInfo: FunctionInfo, variables: VariableInfoWithIndex[], index: number): CallExpression | AwaitExpression;
/**
* Creates a function call block.
*
* @param {FunctionInfo} functionInfo - Information about the function to call.
* @param {CodeGeneratorState} state - The current state of the code generator.
* @return {FunctionCallBlock} The created function call block.
*/
declare function createFunctionCallBlock(functionInfo: FunctionInfo, state: CodeGeneratorState): FunctionCallBlock;
/**
* Converts a function call block into a TypeScript variable statement.
*
* @param {FunctionCallBlock} block - The function call block to convert.
* @param {CodeGeneratorState | { variables: VariableInfoWithIndex[] }} state - The state of the code generator.
* @return {VariableStatement} The TypeScript variable statement representing the function call block.
*/
declare function functionCallBlockToTypeScript(block: FunctionCallBlock, state: CodeGeneratorState | {
variables: VariableInfoWithIndex[];
}): VariableStatement;

declare function scanCodebase(projectPath: string): CodebaseInfo;

interface ServerActionInfo extends FunctionInfo {
filePath: string;
}
interface NextCodebaseInfo {
serverActions: ServerActionInfo[];
}

declare function scanNextjsCodebase(projectPath: string): NextCodebaseInfo;
declare function analyzeNextjsSourceFiles(sourceFiles: SourceFile[]): NextCodebaseInfo;

declare function generateServerAction(info: ServerActionInfo): string;

type index_NextCodebaseInfo = NextCodebaseInfo;
type index_ServerActionInfo = ServerActionInfo;
declare const index_analyzeNextjsSourceFiles: typeof analyzeNextjsSourceFiles;
declare const index_generateServerAction: typeof generateServerAction;
declare const index_scanNextjsCodebase: typeof scanNextjsCodebase;
declare namespace index {
export { type index_NextCodebaseInfo as NextCodebaseInfo, type index_ServerActionInfo as ServerActionInfo, index_analyzeNextjsSourceFiles as analyzeNextjsSourceFiles, index_generateServerAction as generateServerAction, index_scanNextjsCodebase as scanNextjsCodebase };
}

export { type Block, type CodebaseInfo, type FunctionCallBlock, type FunctionInfo, type ModuleInfoFields, type NextCodebaseInfo, index as NextJS, type ServerActionInfo, type TypeInfo, type VariableInfo, type VariableInfoWithIndex, blockToTypeScript, createFunctionCall, createFunctionCallBlock, createVariableWithFunctionCall, extractReturnType, extractVariables, findVariableByType, functionCallBlockToTypeScript, generateCode, generateServerAction, getFunctionInfoFromNode, getFunctionVariables, getUniqueVariableName, parseFunctionsFromText, scanCodebase, scanNextjsCodebase };
Loading

0 comments on commit d97f944

Please sign in to comment.