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

Generated client (flutter) code: ModelProvider has type error #862

Open
sisygoboom opened this issue Aug 7, 2024 · 1 comment
Open

Generated client (flutter) code: ModelProvider has type error #862

sisygoboom opened this issue Aug 7, 2024 · 1 comment
Labels
bug Something isn't working transferred Issue has been transferred from another Amplify repository

Comments

@sisygoboom
Copy link

Environment information

System:
  OS: Windows 10 10.0.19045
  CPU: (12) x64 AMD Ryzen 5 3600 6-Core Processor
  Memory: 13.23 GB / 31.93 GB
Binaries:
  Node: 18.18.2 - C:\Program Files\nodejs\node.EXE
  Yarn: undefined - undefined
  npm: 9.8.1 - C:\Program Files\nodejs\npm.CMD
  pnpm: 8.10.5 - C:\Program Files\nodejs\pnpm.CMD
NPM Packages:
  @aws-amplify/backend: 1.0.4
  @aws-amplify/backend-cli: 1.2.0
  aws-amplify: 6.4.3
  aws-cdk: Not Found
  aws-cdk-lib: 2.150.0
  typescript: 5.5.4
AWS environment variables:
  AWS_NODEJS_CONNECTION_REUSE_ENABLED = 1
  AWS_SDK_LOAD_CONFIG = 1
  AWS_STS_REGIONAL_ENDPOINTS = regional
No CDK environment variables

Description

Using npx ampx generate graphql-client-code --format modelgen --model-target dart --out ./lib/models as recommended in the documentation, generates code with a type error:

image

Generated code

// ChatTable.dart

/*
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
*  http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

// NOTE: This file is generated and may not follow lint rules defined in your app
// Generated files can be excluded from analysis in analysis_options.yaml
// For more info, see: https://dart.dev/guides/language/analysis-options#excluding-code-from-analysis

// ignore_for_file: public_member_api_docs, annotate_overrides, dead_code, dead_codepublic_member_api_docs, depend_on_referenced_packages, file_names, library_private_types_in_public_api, no_leading_underscores_for_library_prefixes, no_leading_underscores_for_local_identifiers, non_constant_identifier_names, null_check_on_nullable_type_parameter, override_on_non_overriding_member, prefer_adjacent_string_concatenation, prefer_const_constructors, prefer_if_null_operators, prefer_interpolation_to_compose_strings, slash_for_doc_comments, sort_child_properties_last, unnecessary_const, unnecessary_constructor_name, unnecessary_late, unnecessary_new, unnecessary_null_aware_assignments, unnecessary_nullable_for_final_variable_declarations, unnecessary_string_interpolations, use_build_context_synchronously

import 'ModelProvider.dart';
import 'package:amplify_core/amplify_core.dart' as amplify_core;


/** This is an auto generated class representing the ChatTable type in your schema. */
class ChatTable {
  final String? _pk;
  final String? _sk;
  final String? _message;
  final String? _userId;
  final String? _timestamp;

  String get pk {
    try {
      return _pk!;
    } catch(e) {
      throw amplify_core.AmplifyCodeGenModelException(
          amplify_core.AmplifyExceptionMessages.codeGenRequiredFieldForceCastExceptionMessage,
          recoverySuggestion:
            amplify_core.AmplifyExceptionMessages.codeGenRequiredFieldForceCastRecoverySuggestion,
          underlyingException: e.toString()
          );
    }
  }
  
  String get sk {
    try {
      return _sk!;
    } catch(e) {
      throw amplify_core.AmplifyCodeGenModelException(
          amplify_core.AmplifyExceptionMessages.codeGenRequiredFieldForceCastExceptionMessage,
          recoverySuggestion:
            amplify_core.AmplifyExceptionMessages.codeGenRequiredFieldForceCastRecoverySuggestion,
          underlyingException: e.toString()
          );
    }
  }
  
  String? get message {
    return _message;
  }
  
  String? get userId {
    return _userId;
  }
  
  String? get timestamp {
    return _timestamp;
  }
  
  const ChatTable._internal({required pk, required sk, message, userId, timestamp}): _pk = pk, _sk = sk, _message = message, _userId = userId, _timestamp = timestamp;
  
  factory ChatTable({required String pk, required String sk, String? message, String? userId, String? timestamp}) {
    return ChatTable._internal(
      pk: pk,
      sk: sk,
      message: message,
      userId: userId,
      timestamp: timestamp);
  }
  
  bool equals(Object other) {
    return this == other;
  }
  
  @override
  bool operator ==(Object other) {
    if (identical(other, this)) return true;
    return other is ChatTable &&
      _pk == other._pk &&
      _sk == other._sk &&
      _message == other._message &&
      _userId == other._userId &&
      _timestamp == other._timestamp;
  }
  
  @override
  int get hashCode => toString().hashCode;
  
  @override
  String toString() {
    var buffer = new StringBuffer();
    
    buffer.write("ChatTable {");
    buffer.write("pk=" + "$_pk" + ", ");
    buffer.write("sk=" + "$_sk" + ", ");
    buffer.write("message=" + "$_message" + ", ");
    buffer.write("userId=" + "$_userId" + ", ");
    buffer.write("timestamp=" + "$_timestamp");
    buffer.write("}");
    
    return buffer.toString();
  }
  
  ChatTable copyWith({String? pk, String? sk, String? message, String? userId, String? timestamp}) {
    return ChatTable._internal(
      pk: pk ?? this.pk,
      sk: sk ?? this.sk,
      message: message ?? this.message,
      userId: userId ?? this.userId,
      timestamp: timestamp ?? this.timestamp);
  }
  
  ChatTable copyWithModelFieldValues({
    ModelFieldValue<String>? pk,
    ModelFieldValue<String>? sk,
    ModelFieldValue<String?>? message,
    ModelFieldValue<String?>? userId,
    ModelFieldValue<String?>? timestamp
  }) {
    return ChatTable._internal(
      pk: pk == null ? this.pk : pk.value,
      sk: sk == null ? this.sk : sk.value,
      message: message == null ? this.message : message.value,
      userId: userId == null ? this.userId : userId.value,
      timestamp: timestamp == null ? this.timestamp : timestamp.value
    );
  }
  
  ChatTable.fromJson(Map<String, dynamic> json)  
    : _pk = json['pk'],
      _sk = json['sk'],
      _message = json['message'],
      _userId = json['userId'],
      _timestamp = json['timestamp'];
  
  Map<String, dynamic> toJson() => {
    'pk': _pk, 'sk': _sk, 'message': _message, 'userId': _userId, 'timestamp': _timestamp
  };
  
  Map<String, Object?> toMap() => {
    'pk': _pk,
    'sk': _sk,
    'message': _message,
    'userId': _userId,
    'timestamp': _timestamp
  };

  static var schema = amplify_core.Model.defineSchema(define: (amplify_core.ModelSchemaDefinition modelSchemaDefinition) {
    modelSchemaDefinition.name = "ChatTable";
    modelSchemaDefinition.pluralName = "ChatTables";
    
    modelSchemaDefinition.addField(amplify_core.ModelFieldDefinition.customTypeField(
      fieldName: 'pk',
      isRequired: true,
      ofType: amplify_core.ModelFieldType(amplify_core.ModelFieldTypeEnum.string)
    ));
    
    modelSchemaDefinition.addField(amplify_core.ModelFieldDefinition.customTypeField(
      fieldName: 'sk',
      isRequired: true,
      ofType: amplify_core.ModelFieldType(amplify_core.ModelFieldTypeEnum.string)
    ));
    
    modelSchemaDefinition.addField(amplify_core.ModelFieldDefinition.customTypeField(
      fieldName: 'message',
      isRequired: false,
      ofType: amplify_core.ModelFieldType(amplify_core.ModelFieldTypeEnum.string)
    ));
    
    modelSchemaDefinition.addField(amplify_core.ModelFieldDefinition.customTypeField(
      fieldName: 'userId',
      isRequired: false,
      ofType: amplify_core.ModelFieldType(amplify_core.ModelFieldTypeEnum.string)
    ));
    
    modelSchemaDefinition.addField(amplify_core.ModelFieldDefinition.customTypeField(
      fieldName: 'timestamp',
      isRequired: false,
      ofType: amplify_core.ModelFieldType(amplify_core.ModelFieldTypeEnum.string)
    ));
  });
}
// ModelProvider.dart

/*
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
*  http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

// NOTE: This file is generated and may not follow lint rules defined in your app
// Generated files can be excluded from analysis in analysis_options.yaml
// For more info, see: https://dart.dev/guides/language/analysis-options#excluding-code-from-analysis

// ignore_for_file: public_member_api_docs, annotate_overrides, dead_code, dead_codepublic_member_api_docs, depend_on_referenced_packages, file_names, library_private_types_in_public_api, no_leading_underscores_for_library_prefixes, no_leading_underscores_for_local_identifiers, non_constant_identifier_names, null_check_on_nullable_type_parameter, override_on_non_overriding_member, prefer_adjacent_string_concatenation, prefer_const_constructors, prefer_if_null_operators, prefer_interpolation_to_compose_strings, slash_for_doc_comments, sort_child_properties_last, unnecessary_const, unnecessary_constructor_name, unnecessary_late, unnecessary_new, unnecessary_null_aware_assignments, unnecessary_nullable_for_final_variable_declarations, unnecessary_string_interpolations, use_build_context_synchronously

import 'package:amplify_core/amplify_core.dart' as amplify_core;
import 'ChatTable.dart';

export 'ChatTable.dart';

class ModelProvider implements amplify_core.ModelProviderInterface {
  @override
  String version = "c087081b6e396e9ccf6e84954b9ab9de";
  @override
  List<amplify_core.ModelSchema> modelSchemas = [];
  @override
  List<amplify_core.ModelSchema> customTypeSchemas = [ChatTable.schema];
  static final ModelProvider _instance = ModelProvider();

  static ModelProvider get instance => _instance;
}


class ModelFieldValue<T> {
  const ModelFieldValue.value(this.value);

  final T value;
}

Related user generated code

// amplify/data/resource.ts

import { type ClientSchema, a, defineData } from '@aws-amplify/backend';
import { getMessagesByConversationId } from '../functions/getMessagesByConversationId/resource';
import { sendMessage } from '../functions/sendMessage/resource';

const schema = a.schema({
  ChatTable: a.customType({
    pk: a.string().required(),
    sk: a.string().required(),
    message: a.string(),
    userId: a.string(),
    timestamp: a.string(),
  }),
  getMessagesByConversationId: a
    .query()
    .arguments({
      conversationId: a.string().required(),
      lastKey: a.string(),
    })
    .returns(a.ref('ChatTable').array())
    .handler(a.handler.function(getMessagesByConversationId))
    .authorization(allow => [allow.publicApiKey()]),
  sendMessage: a
    .mutation()
    .arguments({
      userId: a.string().required(),
      message: a.string().required(),
      conversationId: a.string().required(),
      //timestamp: a.string().required(),
    })
    .returns(a.ref('ChatTable'))
    .handler(a.handler.function(sendMessage))
    .authorization(allow => [allow.publicApiKey()]),
})
.authorization(allow => [
  allow.resource(getMessagesByConversationId).to(['query']),
  allow.resource(sendMessage).to(['mutate']),
]);

export type Schema = ClientSchema<typeof schema>;

export const data = defineData({
  schema,
  authorizationModes: {
    defaultAuthorizationMode: 'apiKey',
    apiKeyAuthorizationMode: {
      expiresInDays: 30
    },
  },
  functions: {
    getMessagesByConversationId,
    sendMessage,
  }
});
@sisygoboom sisygoboom added the pending-triage Issues that need further discussion to determine label Aug 7, 2024
@sundersc
Copy link
Contributor

sundersc commented Aug 8, 2024

Marking it as a bug. Codegen expects at least one model in the schema to add the getModelTypeByModelName block.

Workaround: Add a dummy model to the schema.

Dummy: a.model({
      description: a.string()
    })
    .authorization(allow => [allow.publicApiKey()])

@sundersc sundersc added the bug Something isn't working label Aug 8, 2024
@ykethan ykethan transferred this issue from aws-amplify/amplify-backend Aug 8, 2024
@ykethan ykethan added transferred Issue has been transferred from another Amplify repository and removed pending-triage Issues that need further discussion to determine labels Aug 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working transferred Issue has been transferred from another Amplify repository
Projects
None yet
Development

No branches or pull requests

3 participants