Skip to content

Commit

Permalink
chore: map type file for model fields (#727)
Browse files Browse the repository at this point in the history
Co-authored-by: Hein Jeong <heinje@amazon.com>
  • Loading branch information
hein-j and Hein Jeong authored Oct 26, 2022
1 parent 3b8486e commit d67202a
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3815,6 +3815,7 @@ export default function BookCreateForm(props) {

exports[`amplify form renderer tests datastore form tests should generate a create form for model with relationships 2`] = `
"import * as React from \\"react\\";
import { Author } from \\"../models\\";
import { EscapeHatchProps } from \\"@aws-amplify/ui-react/internal\\";
import { AutocompleteProps, GridProps, TextFieldProps } from \\"@aws-amplify/ui-react\\";
export declare type ValidationResponse = {
Expand All @@ -3824,12 +3825,12 @@ export declare type ValidationResponse = {
export declare type ValidationFunction<T> = (value: T, validationResponse: ValidationResponse) => ValidationResponse | Promise<ValidationResponse>;
export declare type BookCreateFormInputValues = {
name?: string;
\\"primary-author\\"?: string;
\\"primary-author\\"?: Author;
authorId?: string;
};
export declare type BookCreateFormValidationValues = {
name?: ValidationFunction<string>;
\\"primary-author\\"?: ValidationFunction<string>;
\\"primary-author\\"?: ValidationFunction<Author>;
authorId?: ValidationFunction<string>;
};
export declare type FormProps<T> = Partial<T> & React.DOMAttributes<HTMLDivElement>;
Expand Down Expand Up @@ -4250,6 +4251,7 @@ export default function BookCreateForm(props) {

exports[`amplify form renderer tests datastore form tests should generate a create form with hasOne relationship 2`] = `
"import * as React from \\"react\\";
import { Author } from \\"../models\\";
import { EscapeHatchProps } from \\"@aws-amplify/ui-react/internal\\";
import { AutocompleteProps, GridProps, TextFieldProps } from \\"@aws-amplify/ui-react\\";
export declare type ValidationResponse = {
Expand All @@ -4259,11 +4261,11 @@ export declare type ValidationResponse = {
export declare type ValidationFunction<T> = (value: T, validationResponse: ValidationResponse) => ValidationResponse | Promise<ValidationResponse>;
export declare type BookCreateFormInputValues = {
name?: string;
primaryAuthor?: string;
primaryAuthor?: Author;
};
export declare type BookCreateFormValidationValues = {
name?: ValidationFunction<string>;
primaryAuthor?: ValidationFunction<string>;
primaryAuthor?: ValidationFunction<Author>;
};
export declare type FormProps<T> = Partial<T> & React.DOMAttributes<HTMLDivElement>;
export declare type BookCreateFormOverridesProps = {
Expand Down Expand Up @@ -4758,6 +4760,7 @@ export default function BookCreateForm(props) {

exports[`amplify form renderer tests datastore form tests should generate a create form with multiple hasOne relationships 2`] = `
"import * as React from \\"react\\";
import { Author, Title } from \\"../models\\";
import { EscapeHatchProps } from \\"@aws-amplify/ui-react/internal\\";
import { AutocompleteProps, GridProps, TextFieldProps } from \\"@aws-amplify/ui-react\\";
export declare type ValidationResponse = {
Expand All @@ -4767,13 +4770,13 @@ export declare type ValidationResponse = {
export declare type ValidationFunction<T> = (value: T, validationResponse: ValidationResponse) => ValidationResponse | Promise<ValidationResponse>;
export declare type BookCreateFormInputValues = {
name?: string;
primaryAuthor?: string;
primaryTitle?: string;
primaryAuthor?: Author;
primaryTitle?: Title;
};
export declare type BookCreateFormValidationValues = {
name?: ValidationFunction<string>;
primaryAuthor?: ValidationFunction<string>;
primaryTitle?: ValidationFunction<string>;
primaryAuthor?: ValidationFunction<Author>;
primaryTitle?: ValidationFunction<Title>;
};
export declare type FormProps<T> = Partial<T> & React.DOMAttributes<HTMLDivElement>;
export declare type BookCreateFormOverridesProps = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ function getModelTypeSuggestions({
getElementAccessExpression('getDisplayValue', fieldName),
factory.createToken(SyntaxKind.QuestionDotToken),
undefined,
[factory.createIdentifier('r')],
[factory.createIdentifier(recordString)],
),
factory.createToken(SyntaxKind.QuestionQuestionToken),
getElementAccessExpression(recordString, key),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import {
TypeNode,
Identifier,
StringLiteral,
TypeReferenceNode,
KeywordTypeNode,
} from 'typescript';
import { lowerCaseFirst } from '../../helpers';
import { DATA_TYPE_TO_TYPESCRIPT_MAP, FIELD_TYPE_TO_TYPESCRIPT_MAP } from './typescript-type-map';
Expand All @@ -45,24 +47,29 @@ type GetTypeNodeParam = {
dataType?: DataFieldDataType;
isArray: boolean;
isValidation: boolean;
importCollection?: ImportCollection;
};
/**
* based on the provided dataType (appsync scalar)
* converst to the correct typescript type
* converts to the correct typescript type
* default assumption is string type
*/
const getTypeNode = ({ componentType, dataType, isArray, isValidation }: GetTypeNodeParam) => {
let typescriptType: KeywordTypeSyntaxKind = SyntaxKind.StringKeyword;
const getTypeNode = ({ componentType, dataType, isArray, isValidation, importCollection }: GetTypeNodeParam) => {
let typeNode: KeywordTypeNode | TypeReferenceNode = factory.createKeywordTypeNode(SyntaxKind.StringKeyword);

if (componentType in FIELD_TYPE_TO_TYPESCRIPT_MAP) {
typescriptType = FIELD_TYPE_TO_TYPESCRIPT_MAP[componentType];
typeNode = factory.createKeywordTypeNode(FIELD_TYPE_TO_TYPESCRIPT_MAP[componentType]);
}

if (dataType && typeof dataType === 'string' && dataType in DATA_TYPE_TO_TYPESCRIPT_MAP) {
typescriptType = DATA_TYPE_TO_TYPESCRIPT_MAP[dataType];
typeNode = factory.createKeywordTypeNode(DATA_TYPE_TO_TYPESCRIPT_MAP[dataType]);
}

// e.g. string
const typeNode = factory.createKeywordTypeNode(typescriptType);
if (dataType && typeof dataType === 'object' && 'model' in dataType) {
const modelName = dataType.model;
importCollection?.addImport(ImportSource.LOCAL_MODELS, modelName);
typeNode = factory.createTypeReferenceNode(factory.createIdentifier(modelName));
}

if (isValidation) {
return factory.createTypeReferenceNode(factory.createIdentifier('ValidationFunction'), [typeNode]);
Expand Down Expand Up @@ -146,13 +153,14 @@ export const generateFieldTypes = (
formName: string,
type: 'input' | 'validation',
fieldConfigs: Record<string, FieldConfigMetadata>,
importCollection?: ImportCollection,
) => {
const nestedPaths: [fieldName: string, getTypeNodeParam: GetTypeNodeParam][] = [];
const typeNodes: TypeElement[] = [];
const isValidation = type === 'validation';
const typeName = isValidation ? getValidationTypeName(formName) : getInputValuesTypeName(formName);
Object.entries(fieldConfigs).forEach(([fieldName, { dataType, componentType, isArray }]) => {
const getTypeNodeParam = { dataType, componentType, isArray: !!isArray, isValidation };
const getTypeNodeParam = { dataType, componentType, isArray: !!isArray, isValidation, importCollection };
const hasNestedFieldPath = fieldName.split('.').length > 1;
if (hasNestedFieldPath) {
nestedPaths.push([fieldName, getTypeNodeParam]);
Expand Down
3 changes: 2 additions & 1 deletion packages/codegen-ui-react/lib/forms/react-form-renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,8 @@ export abstract class ReactFormTemplateRenderer extends StudioTemplateRenderer<
return [
validationResponseType,
validationFunctionType,
generateFieldTypes(formName, 'input', fieldConfigs),
// pass in importCollection once to collect models to import
generateFieldTypes(formName, 'input', fieldConfigs, this.importCollection),
generateFieldTypes(formName, 'validation', fieldConfigs),
formOverrideProp,
overrideTypeAliasDeclaration,
Expand Down

0 comments on commit d67202a

Please sign in to comment.