Skip to content

Commit

Permalink
feat: add Scala generator to playground (#1773)
Browse files Browse the repository at this point in the history
Co-authored-by: Ashmit JaiSarita Gupta <[email protected]>
  • Loading branch information
akkshitgupta and devilkiller-ag authored Feb 1, 2024
1 parent d9f8592 commit eb34832
Show file tree
Hide file tree
Showing 10 changed files with 234 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
ModelinaPhpOptions,
ModelinaPythonOptions,
ModelinaRustOptions,
ModelinaScalaOptions,
ModelinaTypeScriptOptions
} from '@/types';
import { createContext } from 'react';
Expand All @@ -24,6 +25,8 @@ export const PlaygroundGoConfigContext =
createContext<ModelinaGoOptions | null>(null);
export const PlaygroundRustConfigContext =
createContext<ModelinaRustOptions | null>(null);
export const PlaygroundScalaConfigContext =
createContext<ModelinaScalaOptions | null>(null);
export const PlaygroundKotlinConfigContext =
createContext<ModelinaKotlinOptions | null>(null);
export const PlaygroundDartConfigContext =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ export const PlaygroundContextProvider: React.FC<{ children: React.ReactNode; }>
javaOverwriteToString: false,
javaJavaDocs: false,
javaJavaxAnnotation: false,
scalaCollectionType: 'Array',
scalaPackageName: 'asyncapi.models',
goPackageName: 'asyncapi.models',
kotlinPackageName: 'asyncapi.models'
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
PlaygroundJavaScriptConfigContext,
PlaygroundKotlinConfigContext,
PlaygroundPythonConfigContext,
PlaygroundScalaConfigContext,
PlaygroundRustConfigContext,
PlaygroundCplusplusConfigContext,
PlaygroundGeneralConfigContext,
Expand Down Expand Up @@ -35,9 +36,11 @@ export const OptionsNavigation: React.FunctionComponent<OptionsNavigationProps>
<PlaygroundCplusplusConfigContext.Provider value={config}>
<PlaygroundKotlinConfigContext.Provider value={config}>
<PlaygroundRustConfigContext.Provider value={config}>
<PlaygroundPythonConfigContext.Provider value={config}>
<PlaygroundOptions setNewConfig={setNewConfig} />
</PlaygroundPythonConfigContext.Provider>
<PlaygroundScalaConfigContext.Provider value={config}>
<PlaygroundPythonConfigContext.Provider value={config}>
<PlaygroundOptions setNewConfig={setNewConfig} />
</PlaygroundPythonConfigContext.Provider>
</PlaygroundScalaConfigContext.Provider>
</PlaygroundRustConfigContext.Provider>
</PlaygroundKotlinConfigContext.Provider>
</PlaygroundCplusplusConfigContext.Provider>
Expand Down
14 changes: 14 additions & 0 deletions modelina-website/src/components/playground/Playground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { getJavaGeneratorCode } from '@/helpers/GeneratorCode/JavaGenerator';
import { getGoGeneratorCode } from '@/helpers/GeneratorCode/GoGenerator';
import { getCSharpGeneratorCode } from '@/helpers/GeneratorCode/CSharpGenerator';
import { getRustGeneratorCode } from '@/helpers/GeneratorCode/RustGenerator';
import { getScalaGeneratorCode } from '@/helpers/GeneratorCode/ScalaGenerator';
import { getPythonGeneratorCode } from '@/helpers/GeneratorCode/PythonGenerator';
import { getDartGeneratorCode } from '@/helpers/GeneratorCode/DartGenerator';
import { getCplusplusGeneratorCode } from '@/helpers/GeneratorCode/CplusplusGenerator';
Expand Down Expand Up @@ -165,6 +166,18 @@ const Playground: React.FC<ModelinaPlaygroundProps> = (props) => {
if (query.kotlinPackageName !== undefined) {
setConfig({ ...config, kotlinPackageName: query.kotlinPackageName });
}
if (query.scalaCollectionType !== undefined) {
setConfig({
...config,
scalaCollectionType: query.scalaCollectionType as any
});
}
if (query.scalaPackageName !== undefined) {
setConfig({
...config,
scalaPackageName: query.scalaPackageName as any
});
}

if (props.router.isReady && !hasLoadedQuery) {
setHasLoadedQuery(true);
Expand Down Expand Up @@ -222,6 +235,7 @@ const Playground: React.FC<ModelinaPlaygroundProps> = (props) => {
go: getGoGeneratorCode,
csharp: getCSharpGeneratorCode,
rust: getRustGeneratorCode,
scala: getScalaGeneratorCode,
python: getPythonGeneratorCode,
dart: getDartGeneratorCode,
cplusplus: getCplusplusGeneratorCode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import GoGeneratorOptions from './options/GoGeneratorOptions';
import JavaGeneratorOptions from './options/JavaGeneratorOptions';
import KotlinGeneratorOptions from './options/KotlinGeneratorOptions';
import RustGeneratorOptions from './options/RustGeneratorOptions';
import ScalaGeneratorOptions from './options/ScalaGeneratorOptions';
import PythonGeneratorOptions from './options/PythonGeneratorOptions';
import CplusplusGeneratorOptions from './options/CplusplusGeneratorOptions';
import PhpGeneratorOptions from './options/PhpGeneratorOptions';
Expand Down Expand Up @@ -50,6 +51,9 @@ const PlaygroundOptions: React.FC<PlaygroundOptionsProps> = ({ setNewConfig }) =
case 'rust':
setGeneratorOptions(<RustGeneratorOptions setNewConfig={setNewConfig} />);
break;
case 'scala':
setGeneratorOptions(<ScalaGeneratorOptions setNewConfig={setNewConfig} />);
break;
case 'python':
setGeneratorOptions(<PythonGeneratorOptions setNewConfig={setNewConfig} />);
break;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import React, { useCallback, useContext, useEffect, useState } from 'react';
import Select from '@/components/Select';
import { PlaygroundScalaConfigContext } from '@/components/contexts/PlaygroundConfigContext';
import InfoModal from '@/components/InfoModal';
import { debounce } from 'lodash';

interface ScalaGeneratorOptionsProps {
setNewConfig?: (
queryKey: string,
queryValue: any,
updateCode?: boolean
) => void;
}

interface ScalaGeneratorState {
packageName?: string;
}

export const defaultState: ScalaGeneratorState = {};

const ScalaGeneratorOptions: React.FC<ScalaGeneratorOptionsProps> = ({
setNewConfig
}) => {
const context = useContext(PlaygroundScalaConfigContext);
const [state, setState] = useState<ScalaGeneratorState>(defaultState);

useEffect(() => {
setState({ ...state, packageName: context?.scalaPackageName });
}, [context?.scalaPackageName]);

const debouncedSetNewConfig = debounce(
(queryKey: string, queryValue: any) => setNewConfig?.(queryKey, queryValue),
500
);

const onChangeCollectionType = (collectionType: string) => {
setNewConfig && setNewConfig('scalaCollectionType', collectionType);
};

const onChangePackageName = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
const packageName = event.target.value;
setState({ ...state, packageName });
setNewConfig && debouncedSetNewConfig('scalaPackageName', packageName);
},
[setNewConfig, debouncedSetNewConfig, state]
);

return (
<ul className="flex flex-col">
<h3 className="py-2 w-full text-left border-b-[1px] border-gray-700">
Scala Specific options
</h3>
<li className="flex gap-1 items-center">
<InfoModal text="Package Name :">
<p>
In Scala, a package name is a way to organize and group related
classes, objects, and traits together. It is a naming convention
that helps prevent naming conflicts and provides a hierarchical
structure to the Scala codebase.
</p>
</InfoModal>
<label className="flex flex-grow gap-1 items-center py-2 justify-between cursor-pointer">
<span className="mt-1 max-w-2xl text-sm text-gray-500">
Scala Package Name
</span>
<input
type="text"
className="form-input w-[88%] rounded-md border-gray-300 cursor-pointer font-regular text-md text-gray-700 hover:bg-gray-50 focus-within:text-gray-900"
name="scalaPackageName"
value={state?.packageName}
onChange={onChangePackageName}
/>
</label>
</li>
<li className="flex gap-1 items-center">
<InfoModal text="Scala collection type: ">
<p>
It indicates the collection type. Its value can be either List or
Array.
<br /> <br />
The default value is Array.
</p>
</InfoModal>
<label className="flex flex-grow gap-1 items-center py-2 justify-between cursor-pointer">
<span className="mt-1 max-w-2xl text-sm text-gray-500">
Scala collection type
</span>
<Select
options={[
{ value: 'array', text: 'Array' },
{ value: 'list', text: 'List' }
]}
value={context?.scalaCollectionType}
onChange={onChangeCollectionType}
className="shadow-outline-blue cursor-pointer"
/>
</label>
</li>
</ul>
);
};

export default ScalaGeneratorOptions;
46 changes: 46 additions & 0 deletions modelina-website/src/helpers/GeneratorCode/ScalaGenerator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { ModelinaScalaOptions } from '@/types';
import {
getGeneralGeneratorCode,
renderGeneratorInstanceCode
} from './GeneralGenerator';

export function getScalaGeneratorCode(generatorOptions: ModelinaScalaOptions) {
const optionString: string[] = getGeneralGeneratorCode(
generatorOptions,
'scalaDefaultEnumKeyConstraints',
'scalaDefaultPropertyKeyConstraints',
'scalaDefaultModelNameConstraints'
);
const optionStringPresets: string[] = [];

if (generatorOptions.showTypeMappingExample === true) {
optionString.push(`typeMapping: {
Integer: ({ dependencyManager, constrainedModel, options, partOfProperty }) => {
// Add custom dependency for your type if required.
dependencyManager.addDependency('mod my;');
//Return the type for the integer model
return 'my::IntegerType';
}
}`);
}

const generateInstanceCode = renderGeneratorInstanceCode(
optionString,
optionStringPresets,
'ScalaGenerator'
);

return `// Use the following code as starting point
// To generate the models exactly as displayed in the playground
import {
ScalaGenerator,
IndentationTypes,
FormatHelpers,
scalaDefaultEnumKeyConstraints,
scalaDefaultModelNameConstraints,
scalaDefaultPropertyKeyConstraints
} from '@asyncapi/modelina';
${generateInstanceCode}`;
}
39 changes: 39 additions & 0 deletions modelina-website/src/pages/api/functions/ScalaGenerator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { ModelProps, ModelinaScalaOptions } from "@/types";
import { DeepPartial } from "../../../../../lib/types/utils";
import { scalaDefaultEnumKeyConstraints, scalaDefaultModelNameConstraints, scalaDefaultPropertyKeyConstraints, ScalaGenerator, ScalaOptions } from "../../../../../";
import { applyGeneralOptions, convertModelsToProps } from "./Helpers";

/**
* This is the server side part of the Scala generator, that takes input and generator parameters to generate the models.
*/

export async function getScalaModels(
input:any,
generatorOptions: ModelinaScalaOptions
): Promise<ModelProps[]> {
const options: DeepPartial<ScalaOptions> = {
presets: []
};
applyGeneralOptions(generatorOptions, options, scalaDefaultEnumKeyConstraints, scalaDefaultPropertyKeyConstraints, scalaDefaultModelNameConstraints);

if(generatorOptions.showTypeMappingExample) {
options.typeMapping = {
Integer: ({ dependencyManager }) => {
dependencyManager.addDependency('mod my;');
return 'my::IntegerType';
}
}
}

try {
const generator = new ScalaGenerator(options);
const generatedModels = await generator.generateCompleteModels(input, {
packageName: generatorOptions.scalaPackageName ?? 'asyncapi.models'
});
return convertModelsToProps(generatedModels);
} catch (e : any) {
console.error('Could not generate models');
console.error(e);
return e.message;
}
}
2 changes: 2 additions & 0 deletions modelina-website/src/pages/api/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { getDartModels } from '@/pages/api/functions/DartGenerator';
import { getPythonModels } from '@/pages/api/functions/PythonGenerator';
import { getRustModels } from '@/pages/api/functions/RustGenerator';
import { getCSharpModels } from '@/pages/api/functions/CSharpGenerator';
import { getScalaModels } from './functions/ScalaGenerator';
import { getCplusplusModels } from './functions/CplusplusGenerator';
import { getKotlinModels } from './functions/KotlinGenerator';
import { getPhpModels } from './functions/PhpGenerator';
Expand All @@ -36,6 +37,7 @@ export async function generateNewCode(message: GenerateMessage): Promise<UpdateM
'go': getGoModels,
'csharp': getCSharpModels,
'rust': getRustModels,
'scala': getScalaModels,
'python': getPythonModels,
'kotlin': getKotlinModels,
'dart': getDartModels,
Expand Down
14 changes: 14 additions & 0 deletions modelina-website/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ export interface ModelinaKotlinOptions extends ModelinaGeneralOptions {
kotlinPackageName?: string;
}
export interface ModelinaRustOptions extends ModelinaGeneralOptions {}
export interface ModelinaScalaOptions extends ModelinaGeneralOptions {
scalaCollectionType: 'List' | 'Array' | undefined;
scalaPackageName?: string;
}
export interface ModelinaPythonOptions extends ModelinaGeneralOptions {}
export interface ModelinaDartOptions extends ModelinaGeneralOptions {}
export interface ModelinaGeneralOptions {
Expand All @@ -81,6 +85,7 @@ export interface ModelinaGeneralOptions {
| 'csharp'
| 'kotlin'
| 'rust'
| 'scala'
| 'python'
| 'dart'
| 'cplusplus'
Expand Down Expand Up @@ -149,6 +154,10 @@ export interface ModelinaKotlinQueryOptions {
kotlinPackageName?: string;
}
export interface ModelinaRustQueryOptions {}
export interface ModelinaScalaQueryOptions {
scalaCollectionType?: string;
scalaPackageName?: string;
}
export interface ModelinaPythonQueryOptions {}
export interface ModelinaCplusplusQueryOptions {
cplusplusNamespace?: string;
Expand Down Expand Up @@ -178,6 +187,7 @@ export interface ModelinaOptions
ModelinaCSharpOptions,
ModelinaKotlinOptions,
ModelinaRustOptions,
ModelinaScalaOptions,
ModelinaPythonOptions,
ModelinaDartOptions,
ModelinaPhpOptions,
Expand All @@ -192,6 +202,7 @@ export interface ModelinaQueryOptions
ModelinaCSharpQueryOptions,
ModelinaKotlinQueryOptions,
ModelinaRustQueryOptions,
ModelinaScalaQueryOptions,
ModelinaPythonQueryOptions,
ModelinaCplusplusQueryOptions,
ModelinaDartQueryOptions,
Expand Down Expand Up @@ -229,6 +240,9 @@ export const modelinaLanguageOptions = [
value: 'rust',
text: 'Rust'
},
{ value: 'scala',
text: 'Scala'
},
{
value: 'python',
text: 'Python'
Expand Down

0 comments on commit eb34832

Please sign in to comment.