fal-js/libs/codegen/src/generators/generateFunction.ts
Daniel Rochetti ed322048ff
release: client 0.1.0 (#6)
* chore(client): add assets and bump version
* chore: rename scope to fal-ai
2023-03-31 18:35:08 -03:00

107 lines
3.0 KiB
TypeScript

import { camelCase, pascalCase } from 'change-case';
import * as prettier from 'prettier';
import {
FunctionDeclarationStructure,
ImportDeclarationStructure,
InterfaceDeclarationStructure,
ParameterDeclarationStructure,
Project,
PropertySignatureStructure,
SourceFileStructure,
StatementStructures,
StructureKind,
} from 'ts-morph';
import { IsolateFunctionMetadata, IsolateFunctionParameter } from '../types';
const CORE_TYPES = {
str: 'string',
} as const;
function generateProperty(
param: IsolateFunctionParameter
): PropertySignatureStructure {
return {
kind: StructureKind.PropertySignature,
name: param.name,
isReadonly: true,
type: CORE_TYPES[param.type],
hasQuestionToken: !param.is_required,
};
}
export function generateFunction(metadata: IsolateFunctionMetadata): string {
const identifier = camelCase(metadata.name);
const typename = pascalCase(metadata.name);
const members: StatementStructures[] = [];
members.push({
kind: StructureKind.ImportDeclaration,
namedImports: ['run'],
moduleSpecifier: '@fal-ai/serverless-client',
} as ImportDeclarationStructure);
members.push({
kind: StructureKind.ImportDeclaration,
namedImports: ['credentials'],
moduleSpecifier: '../../credentials',
} as ImportDeclarationStructure);
const inputTypename = `${typename}Input`;
const parameters: ParameterDeclarationStructure[] = [];
if (metadata.parameters && metadata.parameters.length > 0) {
const inputType = {
kind: StructureKind.Interface,
name: inputTypename,
properties: metadata.parameters.map(generateProperty),
} as InterfaceDeclarationStructure;
members.push(inputType);
parameters.push({
kind: StructureKind.Parameter,
name: 'input',
type: inputTypename,
});
}
const onData: ParameterDeclarationStructure = {
kind: StructureKind.Parameter,
name: 'onData',
type: '(data: string) => void',
};
parameters.push(onData);
const isolatedFunction: FunctionDeclarationStructure = {
kind: StructureKind.Function,
isExported: true,
name: identifier,
parameters: parameters,
// returnType: metadata.return_type
// ? CORE_TYPES[metadata.return_type]
// : undefined,
statements: (writer) => {
writer.write('return run(').block(() => {
writer.writeLine(`host: '${metadata.config.host}'`);
writer.writeLine('credentials');
writer.writeLine(`environmentKind: '${metadata.config.env_kind}'`);
writer.writeLine(
`requirements: ${JSON.stringify(metadata.config.requirements)}`
);
writer.writeLine(`definition: '${metadata.definition}'`);
});
writer.writeLine(', onData);');
},
};
members.push(isolatedFunction);
const project = new Project();
const source: SourceFileStructure = {
kind: StructureKind.SourceFile,
statements: members,
};
const filepath = `src/${identifier}.ts`;
const file = project.createSourceFile(filepath, source);
return prettier.format(file.print(), {
filepath,
});
}