Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build code introspection service #7760

Merged
merged 3 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/twenty-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"monaco-editor-auto-typings": "^0.4.5",
"passport": "^0.7.0",
"psl": "^1.9.0",
"ts-morph": "^24.0.0",
"tsconfig-paths": "^4.2.0",
"typeorm": "patch:[email protected]#./patches/typeorm+0.3.20.patch",
"unzipper": "^0.12.3",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { CustomException } from 'src/utils/custom-exception';

export class CodeIntrospectionException extends CustomException {
code: CodeIntrospectionExceptionCode;
constructor(message: string, code: CodeIntrospectionExceptionCode) {
super(message, code);
}
}

export enum CodeIntrospectionExceptionCode {
ONLY_ONE_FUNCTION_ALLOWED = 'ONLY_ONE_FUNCTION_ALLOWED',
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
thomtrp marked this conversation as resolved.
Show resolved Hide resolved

import { CodeIntrospectionService } from 'src/engine/metadata-modules/serverless-function/code-introspection/code-introspection.service';

@Module({
providers: [CodeIntrospectionService],
exports: [CodeIntrospectionService],
})
export class CodeIntrospectionModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { Injectable } from '@nestjs/common';

import {
ArrowFunction,
FunctionDeclaration,
Project,
SyntaxKind,
} from 'ts-morph';

import {
CodeIntrospectionException,
CodeIntrospectionExceptionCode,
} from 'src/engine/metadata-modules/serverless-function/code-introspection/code-introspection.exception';

type FunctionParameter = {
name: string;
type: string;
};

@Injectable()
export class CodeIntrospectionService {
private project: Project;

constructor() {
this.project = new Project();
}

public analyze(
thomtrp marked this conversation as resolved.
Show resolved Hide resolved
fileContent: string,
fileName = 'temp.ts',
): FunctionParameter[] {
const sourceFile = this.project.createSourceFile(fileName, fileContent, {
overwrite: true,
});

const functionDeclarations = sourceFile.getFunctions();

if (functionDeclarations.length > 0) {
return this.analyzeFunctions(functionDeclarations);
}

const arrowFunctions = sourceFile.getDescendantsOfKind(
SyntaxKind.ArrowFunction,
);

if (arrowFunctions.length > 0) {
return this.analyzeArrowFunctions(arrowFunctions);
}

return [];
}

private analyzeFunctions(
functionDeclarations: FunctionDeclaration[],
): FunctionParameter[] {
if (functionDeclarations.length > 1) {
throw new CodeIntrospectionException(
'Only one function is allowed',
CodeIntrospectionExceptionCode.ONLY_ONE_FUNCTION_ALLOWED,
);
}

const functionDeclaration = functionDeclarations[0];

return functionDeclaration.getParameters().map((parameter) => {
return {
name: parameter.getName(),
type: parameter.getType().getText(),
};
});
}

private analyzeArrowFunctions(arrowFunctions: ArrowFunction[]) {
if (arrowFunctions.length > 1) {
throw new CodeIntrospectionException(
'Only one arrow function is allowed',
CodeIntrospectionExceptionCode.ONLY_ONE_FUNCTION_ALLOWED,
);
}

const arrowFunction = arrowFunctions[0];

return arrowFunction.getParameters().map((parameter) => {
return {
name: parameter.getName(),
type: parameter.getType().getText(),
};
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { FileModule } from 'src/engine/core-modules/file/file.module';
import { ServerlessModule } from 'src/engine/core-modules/serverless/serverless.module';
import { ThrottlerModule } from 'src/engine/core-modules/throttler/throttler.module';
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
import { CodeIntrospectionModule } from 'src/engine/metadata-modules/serverless-function/code-introspection/code-introspection.module';
import { ServerlessFunctionDTO } from 'src/engine/metadata-modules/serverless-function/dtos/serverless-function.dto';
import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity';
import { ServerlessFunctionResolver } from 'src/engine/metadata-modules/serverless-function/serverless-function.resolver';
Expand All @@ -31,6 +32,7 @@ import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverles
TypeOrmModule.forFeature([FeatureFlagEntity], 'core'),
FileModule,
ThrottlerModule,
CodeIntrospectionModule,
],
services: [ServerlessFunctionService],
resolvers: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,24 @@ import { InjectRepository } from '@nestjs/typeorm';
import { basename, dirname, join } from 'path';

import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm';
import { Repository } from 'typeorm';
import deepEqual from 'deep-equal';
import { Repository } from 'typeorm';
thomtrp marked this conversation as resolved.
Show resolved Hide resolved

import { FileStorageExceptionCode } from 'src/engine/core-modules/file-storage/interfaces/file-storage-exception';
import { ServerlessExecuteResult } from 'src/engine/core-modules/serverless/drivers/interfaces/serverless-driver.interface';

import { ThrottlerService } from 'src/engine/core-modules/throttler/throttler.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { FileStorageService } from 'src/engine/core-modules/file-storage/file-storage.service';
import { readFileContent } from 'src/engine/core-modules/file-storage/utils/read-file-content';
import { ENV_FILE_NAME } from 'src/engine/core-modules/serverless/drivers/constants/env-file-name';
import { INDEX_FILE_NAME } from 'src/engine/core-modules/serverless/drivers/constants/index-file-name';
import { LAST_LAYER_VERSION } from 'src/engine/core-modules/serverless/drivers/layers/last-layer-version';
import { getBaseTypescriptProjectFiles } from 'src/engine/core-modules/serverless/drivers/utils/get-base-typescript-project-files';
import { getLastLayerDependencies } from 'src/engine/core-modules/serverless/drivers/utils/get-last-layer-dependencies';
import { ServerlessService } from 'src/engine/core-modules/serverless/serverless.service';
import { getServerlessFolder } from 'src/engine/core-modules/serverless/utils/serverless-get-folder.utils';
import { ThrottlerService } from 'src/engine/core-modules/throttler/throttler.service';
import { CreateServerlessFunctionInput } from 'src/engine/metadata-modules/serverless-function/dtos/create-serverless-function.input';
import { UpdateServerlessFunctionInput } from 'src/engine/metadata-modules/serverless-function/dtos/update-serverless-function.input';
import {
ServerlessFunctionEntity,
Expand All @@ -27,11 +32,6 @@ import {
ServerlessFunctionExceptionCode,
} from 'src/engine/metadata-modules/serverless-function/serverless-function.exception';
import { isDefined } from 'src/utils/is-defined';
import { getLastLayerDependencies } from 'src/engine/core-modules/serverless/drivers/utils/get-last-layer-dependencies';
import { LAST_LAYER_VERSION } from 'src/engine/core-modules/serverless/drivers/layers/last-layer-version';
import { CreateServerlessFunctionInput } from 'src/engine/metadata-modules/serverless-function/dtos/create-serverless-function.input';
import { getBaseTypescriptProjectFiles } from 'src/engine/core-modules/serverless/drivers/utils/get-base-typescript-project-files';
import { ENV_FILE_NAME } from 'src/engine/core-modules/serverless/drivers/constants/env-file-name';

@Injectable()
export class ServerlessFunctionService extends TypeOrmQueryService<ServerlessFunctionEntity> {
Expand Down Expand Up @@ -81,9 +81,11 @@ export class ServerlessFunctionService extends TypeOrmQueryService<ServerlessFun
filename: ENV_FILE_NAME,
});

const fileContent = await readFileContent(indexFileStream);

return {
'.env': await readFileContent(envFileStream),
'src/index.ts': await readFileContent(indexFileStream),
'src/index.ts': fileContent,
};
} catch (error) {
if (error.code === FileStorageExceptionCode.FILE_NOT_FOUND) {
Expand Down
51 changes: 51 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -15073,6 +15073,17 @@ __metadata:
languageName: node
linkType: hard

"@ts-morph/common@npm:~0.25.0":
version: 0.25.0
resolution: "@ts-morph/common@npm:0.25.0"
dependencies:
minimatch: "npm:^9.0.4"
path-browserify: "npm:^1.0.1"
tinyglobby: "npm:^0.2.9"
checksum: 10c0/c67e66db678e44886e9823e6482834acebfae0ea52ccbfa2af1ca9abfe5a9774dad6e852c8f480909bc196175f17e15454af71d7a41a1c137db09e74f046a830
languageName: node
linkType: hard

"@tsconfig/node10@npm:^1.0.7":
version: 1.0.11
resolution: "@tsconfig/node10@npm:1.0.11"
Expand Down Expand Up @@ -22021,6 +22032,13 @@ __metadata:
languageName: node
linkType: hard

"code-block-writer@npm:^13.0.3":
version: 13.0.3
resolution: "code-block-writer@npm:13.0.3"
checksum: 10c0/87db97b37583f71cfd7eced8bf3f0a0a0ca53af912751a734372b36c08cd27f3e8a4878ec05591c0cd9ae11bea8add1423e132d660edd86aab952656dd41fd66
languageName: node
linkType: hard

"code-point-at@npm:^1.0.0":
version: 1.1.0
resolution: "code-point-at@npm:1.1.0"
Expand Down Expand Up @@ -26491,6 +26509,18 @@ __metadata:
languageName: node
linkType: hard

"fdir@npm:^6.4.0":
version: 6.4.0
resolution: "fdir@npm:6.4.0"
peerDependencies:
picomatch: ^3 || ^4
peerDependenciesMeta:
picomatch:
optional: true
checksum: 10c0/9a03efa1335d78ea386b701799b08ad9e7e8da85d88567dc162cd28dd8e9486e8c269b3e95bfeb21dd6a5b14ebf69d230eb6e18f49d33fbda3cd97432f648c48
languageName: node
linkType: hard

"fetch-retry@npm:^5.0.2":
version: 5.0.6
resolution: "fetch-retry@npm:5.0.6"
Expand Down Expand Up @@ -43048,6 +43078,16 @@ __metadata:
languageName: node
linkType: hard

"tinyglobby@npm:^0.2.9":
version: 0.2.9
resolution: "tinyglobby@npm:0.2.9"
dependencies:
fdir: "npm:^6.4.0"
picomatch: "npm:^4.0.2"
checksum: 10c0/f65f847afe70f56de069d4f1f9c3b0c1a76aaf2b0297656754734a83b9bac8e105b5534dfbea8599560476b88f7b747d0855370a957a07246d18b976addb87ec
languageName: node
linkType: hard

"tinypool@npm:^0.8.2":
version: 0.8.4
resolution: "tinypool@npm:0.8.4"
Expand Down Expand Up @@ -43474,6 +43514,16 @@ __metadata:
languageName: node
linkType: hard

"ts-morph@npm:^24.0.0":
version: 24.0.0
resolution: "ts-morph@npm:24.0.0"
dependencies:
"@ts-morph/common": "npm:~0.25.0"
code-block-writer: "npm:^13.0.3"
checksum: 10c0/2a0813ba428a154966d4038901f6c32457a60870936b23778f2629433257f87d1881fc4ecae7b791a223a88c2edf96aaac9fb0f88bf34d3c652af8c09c4f43bc
languageName: node
linkType: hard

"ts-node@npm:10.9.1":
version: 10.9.1
resolution: "ts-node@npm:10.9.1"
Expand Down Expand Up @@ -43817,6 +43867,7 @@ __metadata:
passport: "npm:^0.7.0"
psl: "npm:^1.9.0"
rimraf: "npm:^5.0.5"
ts-morph: "npm:^24.0.0"
tsconfig-paths: "npm:^4.2.0"
typeorm: "patch:[email protected]#./patches/typeorm+0.3.20.patch"
typescript: "npm:5.3.3"
Expand Down
Loading