@aws-amplify/appsync-modelgen-plugin
Version:
654 lines • 35.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AppSyncSwiftVisitor = void 0;
const visitor_plugin_common_1 = require("@graphql-codegen/visitor-plugin-common");
const change_case_1 = require("change-case");
const lower_case_first_1 = require("lower-case-first");
const graphql_transformer_common_1 = require("graphql-transformer-common");
const swift_config_1 = require("../configs/swift-config");
const swift_declaration_block_1 = require("../languages/swift-declaration-block");
const process_connections_1 = require("../utils/process-connections");
const appsync_visitor_1 = require("./appsync-visitor");
const process_auth_1 = require("../utils/process-auth");
const warn_1 = require("../utils/warn");
const scalars_1 = require("../scalars");
class AppSyncSwiftVisitor extends appsync_visitor_1.AppSyncModelVisitor {
constructor(schema, rawConfig, additionalConfig, defaultScalars = scalars_1.SWIFT_SCALAR_MAP) {
super(schema, rawConfig, additionalConfig, defaultScalars);
this.modelExtensionImports = ['import Amplify', 'import Foundation'];
this.imports = ['import Amplify', 'import Foundation'];
this._parsedConfig.emitAuthProvider = rawConfig.emitAuthProvider || false;
this._parsedConfig.generateIndexRules = rawConfig.generateIndexRules || false;
}
generate() {
const shouldUseModelNameFieldInHasManyAndBelongsTo = true;
const shouldImputeKeyForUniDirectionalHasMany = false;
this.processDirectives(shouldUseModelNameFieldInHasManyAndBelongsTo, shouldImputeKeyForUniDirectionalHasMany);
const code = [`// swiftlint:disable all`];
if (this._parsedConfig.generate === appsync_visitor_1.CodeGenGenerateEnum.metadata) {
code.push(this.generateSchema());
}
else if (this._parsedConfig.generate === appsync_visitor_1.CodeGenGenerateEnum.loader) {
code.push(this.generateClassLoader());
}
else if (this.selectedTypeIsEnum()) {
code.push(this.generateEnums());
}
else if (this.selectedTypeIsNonModel()) {
code.push(this.generateNonModelType());
}
else {
code.push(this.generateStruct());
}
return code.join('\n');
}
generateStruct() {
let result = [...this.imports, ''];
Object.entries(this.getSelectedModels()).forEach(([name, obj]) => {
const structBlock = new swift_declaration_block_1.SwiftDeclarationBlock()
.withName(this.getModelName(obj))
.access('public')
.withProtocols(['Model']);
let primaryKeyComponentFieldsName = ['id'];
if (this.config.respectPrimaryKeyAttributesOnConnectionField) {
const primaryKeyField = this.getModelPrimaryKeyField(obj);
const { sortKeyFields } = primaryKeyField.primaryKeyInfo;
primaryKeyComponentFieldsName = [primaryKeyField, ...sortKeyFields].map(field => field.name);
}
Object.entries(obj.fields).forEach(([fieldName, field]) => {
const fieldType = this.getNativeType(field);
const isVariable = !primaryKeyComponentFieldsName.includes(field.name);
const listType = field.connectionInfo ? swift_declaration_block_1.ListType.LIST : swift_declaration_block_1.ListType.ARRAY;
if (this.isGenerateModelsForLazyLoadAndCustomSelectionSet() && this.isHasOneOrBelongsToConnectionField(field)) {
structBlock.addProperty(`_${this.getFieldName(field)}`, `LazyReference<${fieldType}>`, undefined, `internal`, {
optional: false,
isList: field.isList,
variable: isVariable,
isEnum: this.isEnumType(field),
listType: field.isList ? listType : undefined,
isListNullable: field.isListNullable,
handleListNullabilityTransparently: this.config.handleListNullabilityTransparently,
});
const lazyLoadGetOrRequired = !this.isFieldRequired(field) ? 'get()' : 'require()';
structBlock.addProperty(this.getFieldName(field), fieldType, undefined, 'public', {
optional: !this.isFieldRequired(field),
isList: field.isList,
variable: isVariable,
isEnum: this.isEnumType(field),
listType: field.isList ? listType : undefined,
isListNullable: field.isListNullable,
handleListNullabilityTransparently: this.config.handleListNullabilityTransparently,
}, undefined, `get async throws { \n try await _${this.getFieldName(field)}.${lazyLoadGetOrRequired}\n}`);
}
else {
structBlock.addProperty(this.getFieldName(field), fieldType, undefined, 'public', {
optional: !this.isFieldRequired(field),
isList: field.isList,
variable: isVariable,
isEnum: this.isEnumType(field),
listType: field.isList ? listType : undefined,
isListNullable: field.isListNullable,
handleListNullabilityTransparently: this.isHasManyConnectionField(field)
? false
: this.config.handleListNullabilityTransparently,
});
}
});
const initParams = this.getWritableFields(obj);
const initImpl = `self.init(${(0, visitor_plugin_common_1.indentMultiline)(obj.fields
.map(field => {
const fieldName = (0, swift_declaration_block_1.escapeKeywords)(this.getFieldName(field));
return field.isReadOnly ? `${fieldName}: nil` : `${fieldName}: ${fieldName}`;
})
.join(',\n')).trim()})`;
if (this.config.isTimestampFieldsAdded && this.hasReadOnlyFields(obj)) {
structBlock.addClassMethod('init', null, initImpl, initParams.map(field => {
const listType = field.connectionInfo ? swift_declaration_block_1.ListType.LIST : swift_declaration_block_1.ListType.ARRAY;
return {
name: this.getFieldName(field),
type: this.getNativeType(field),
value: field.name === 'id' ? 'UUID().uuidString' : undefined,
flags: {
optional: field.isNullable,
isList: field.isList,
isEnum: this.isEnumType(field),
listType: field.isList ? listType : undefined,
isListNullable: field.isListNullable,
handleListNullabilityTransparently: this.isHasManyConnectionField(field)
? false
: this.config.handleListNullabilityTransparently,
},
};
}), 'public', {});
structBlock.addClassMethod('init', null, this.getInitBody(obj.fields), obj.fields.map(field => {
const listType = field.connectionInfo ? swift_declaration_block_1.ListType.LIST : swift_declaration_block_1.ListType.ARRAY;
return {
name: this.getFieldName(field),
type: this.getNativeType(field),
value: field.name === 'id' ? 'UUID().uuidString' : undefined,
flags: {
optional: field.isNullable,
isList: field.isList,
isEnum: this.isEnumType(field),
listType: field.isList ? listType : undefined,
isListNullable: field.isListNullable,
handleListNullabilityTransparently: this.isHasManyConnectionField(field)
? false
: this.config.handleListNullabilityTransparently,
},
};
}), 'internal', {});
}
else {
structBlock.addClassMethod('init', null, this.getInitBody(obj.fields), obj.fields.map(field => {
const listType = field.connectionInfo ? swift_declaration_block_1.ListType.LIST : swift_declaration_block_1.ListType.ARRAY;
return {
name: this.getFieldName(field),
type: this.getNativeType(field),
value: field.name === 'id' ? 'UUID().uuidString' : undefined,
flags: {
optional: field.isNullable,
isList: field.isList,
isEnum: this.isEnumType(field),
listType: field.isList ? listType : undefined,
isListNullable: field.isListNullable,
handleListNullabilityTransparently: this.isHasManyConnectionField(field)
? false
: this.config.handleListNullabilityTransparently,
},
};
}), 'public', {});
}
if (this.isGenerateModelsForLazyLoadAndCustomSelectionSet()) {
var customEncodingAndDecodingRequired = false;
Object.entries(obj.fields).forEach(([fieldName, field]) => {
if (this.isHasOneOrBelongsToConnectionField(field)) {
customEncodingAndDecodingRequired = true;
let fieldName = this.getFieldName(field);
let capitalizedFieldName = fieldName.charAt(0).toUpperCase() + fieldName.slice(1);
structBlock.addClassMethod(`set${capitalizedFieldName}`, null, `self._${fieldName} = LazyReference(${fieldName})`, [
{
name: `_ ${this.getFieldName(field)}`,
type: this.getNativeType(field),
value: undefined,
flags: { optional: !this.isFieldRequired(field) },
},
], 'public', {
mutating: true,
});
}
});
if (customEncodingAndDecodingRequired) {
structBlock.addClassMethod('init', null, this.getDecoderBody(obj.fields), [
{
value: undefined,
name: 'from decoder',
type: 'Decoder',
flags: {},
},
], 'public', { throws: true });
structBlock.addClassMethod('encode', null, this.getEncoderBody(obj.fields), [
{
value: undefined,
name: 'to encoder',
type: 'Encoder',
flags: {},
},
], 'public', { throws: true });
}
}
result.push(structBlock.string);
});
return result.join('\n');
}
generateEnums() {
const result = [...this.imports, ''];
Object.entries(this.getSelectedEnums()).forEach(([name, enumValue]) => {
const enumDeclaration = new swift_declaration_block_1.SwiftDeclarationBlock()
.asKind('enum')
.access('public')
.withProtocols(['String', 'EnumPersistable'])
.withName((0, change_case_1.pascalCase)(this.getEnumName(enumValue)));
Object.entries(enumValue.values).forEach(([name, value]) => {
enumDeclaration.addEnumValue(name, value);
});
result.push(enumDeclaration.string);
});
return result.join('\n');
}
generateNonModelType() {
let result = [...this.imports, ''];
Object.entries(this.getSelectedNonModels()).forEach(([name, obj]) => {
const structBlock = new swift_declaration_block_1.SwiftDeclarationBlock()
.withName(this.getModelName(obj))
.access('public')
.withProtocols(['Embeddable']);
Object.values(obj.fields).forEach(field => {
const fieldType = this.getNativeType(field);
structBlock.addProperty(this.getFieldName(field), fieldType, undefined, 'DEFAULT', {
optional: !this.isFieldRequired(field),
isList: field.isList,
variable: true,
isEnum: this.isEnumType(field),
listType: field.isList ? swift_declaration_block_1.ListType.ARRAY : undefined,
isListNullable: field.isListNullable,
handleListNullabilityTransparently: this.isHasManyConnectionField(field) ? false : this.config.handleListNullabilityTransparently,
});
});
result.push(structBlock.string);
});
return result.join('\n');
}
generateSchema() {
let result = [...this.modelExtensionImports, ''];
Object.values(this.getSelectedModels())
.filter(m => m.type === 'model')
.forEach(model => {
const schemaDeclarations = new swift_declaration_block_1.SwiftDeclarationBlock().asKind('extension').withName(this.getModelName(model));
this.generateCodingKeys(this.getModelName(model), model, schemaDeclarations),
this.generateModelSchema(this.getModelName(model), model, schemaDeclarations);
result.push(schemaDeclarations.string);
if (this.isCustomPKEnabled()) {
result.push('');
result.push(this.generatePrimaryKeyExtensions(model));
}
if (this.isGenerateModelsForLazyLoadAndCustomSelectionSet()) {
result.push(this.generateModelPathExtensions(model));
}
});
Object.values(this.getSelectedNonModels()).forEach(model => {
const schemaDeclarations = new swift_declaration_block_1.SwiftDeclarationBlock().asKind('extension').withName(this.getNonModelName(model));
this.generateCodingKeys(this.getNonModelName(model), model, schemaDeclarations),
this.generateModelSchema(this.getNonModelName(model), model, schemaDeclarations);
result.push(schemaDeclarations.string);
});
return result.join('\n');
}
generateCodingKeys(name, model, extensionDeclaration) {
const codingKeyEnum = new swift_declaration_block_1.SwiftDeclarationBlock()
.asKind('enum')
.access('public')
.withName('CodingKeys')
.withProtocols(['String', 'ModelKey'])
.withComment('MARK: - CodingKeys');
model.fields.forEach(field => codingKeyEnum.addEnumValue(this.getFieldName(field), field.name));
extensionDeclaration.appendBlock(codingKeyEnum.string);
extensionDeclaration.addProperty('keys', '', 'CodingKeys.self', 'public', {
static: true,
variable: false,
});
}
generateModelSchema(name, model, extensionDeclaration) {
const useImprovedPluralization = this.config.improvePluralization || (this.config.transformerVersion === 2);
const keysName = (0, lower_case_first_1.lowerCaseFirst)(model.name);
const fields = model.fields.map(field => this.generateFieldSchema(field, keysName));
const authRules = this.generateAuthRules(model);
const keyDirectives = this.config.generateIndexRules ? this.generateKeyRules(model) : [];
const priamryKeyRules = this.generatePrimaryKeyRules(model);
const attributes = [...keyDirectives, priamryKeyRules].filter(f => f);
const pluralFields = useImprovedPluralization ?
[`model.listPluralName = "${(0, graphql_transformer_common_1.plurality)(model.name, useImprovedPluralization)}"`, `model.syncPluralName = "${this.pluralizeModelName(model)}"`] :
[`model.pluralName = "${this.pluralizeModelName(model)}"`];
const isGenerateModelPathEnabled = this.isGenerateModelsForLazyLoadAndCustomSelectionSet() && !this.selectedTypeIsNonModel();
const closure = [
'{ model in',
`let ${keysName} = ${this.getModelName(model)}.keys`,
'',
...(authRules.length ? [`model.authRules = ${authRules}`, ''] : []),
...pluralFields,
'',
...(attributes.length ? ['model.attributes(', (0, visitor_plugin_common_1.indentMultiline)(attributes.join(',\n')), ')', ''] : []),
'model.fields(',
(0, visitor_plugin_common_1.indentMultiline)(fields.join(',\n')),
')',
'}',
isGenerateModelPathEnabled ? `public class Path: ModelPath<${this.getModelName(model)}> { }` : '',
'',
isGenerateModelPathEnabled ? 'public static var rootPath: PropertyContainerPath? { Path() }' : '',
].join('\n');
extensionDeclaration.addProperty('schema', '', `defineSchema ${(0, visitor_plugin_common_1.indentMultiline)(closure).trim()}`, 'public', { static: true, variable: false }, ' MARK: - ModelSchema');
}
generatePrimaryKeyExtensions(model) {
let result = [];
const primaryKeyField = model.fields.find(field => field.primaryKeyInfo);
const { primaryKeyType, sortKeyFields } = primaryKeyField.primaryKeyInfo;
const useDefaultExplicitID = primaryKeyType === appsync_visitor_1.CodeGenPrimaryKeyType.ManagedId || primaryKeyType === appsync_visitor_1.CodeGenPrimaryKeyType.OptionallyManagedId;
const identifiableExtension = new swift_declaration_block_1.SwiftDeclarationBlock()
.asKind('extension')
.withName(`${this.getModelName(model)}: ModelIdentifiable`);
const identifierFormatValue = `ModelIdentifierFormat.${useDefaultExplicitID ? 'Default' : 'Custom'}`;
identifiableExtension.addProperty('IdentifierFormat', '', identifierFormatValue, 'public', { isTypeAlias: true });
const identifierValue = useDefaultExplicitID ? 'DefaultModelIdentifier<Self>' : 'ModelIdentifier<Self, ModelIdentifierFormat.Custom>';
identifiableExtension.addProperty('IdentifierProtocol', '', identifierValue, 'public', { isTypeAlias: true });
result.push(identifiableExtension.string);
if (!useDefaultExplicitID) {
const identifierExtension = new swift_declaration_block_1.SwiftDeclarationBlock()
.asKind('extension')
.withName(`${this.getModelName(model)}.IdentifierProtocol`);
const primaryKeyComponentFields = [primaryKeyField, ...sortKeyFields];
const identifierArgs = primaryKeyComponentFields.map(field => ({
name: this.getFieldName(field),
type: this.getNativeType(field),
flags: {},
value: undefined,
}));
const identifierBody = `.make(fields:[${primaryKeyComponentFields
.map(field => `(name: "${this.getFieldName(field)}", value: ${this.getFieldName(field)})`)
.join(', ')}])`;
identifierExtension.addClassMethod('identifier', 'Self', identifierBody, identifierArgs, 'public', { static: true });
result.push(identifierExtension.string);
}
return result.join('\n\n');
}
generateModelPathExtensions(model) {
const modelPathExtension = new swift_declaration_block_1.SwiftDeclarationBlock()
.asKind('extension')
.withName(`ModelPath`)
.withCondition(`ModelType == ${this.getModelName(model)}`);
Object.values(model.fields).forEach(field => {
if (this.isEnumType(field) || this.isNonModelType(field)) {
return;
}
const fieldName = this.getFieldName(field);
const fieldType = this.getNativeType(field);
const pathType = field.connectionInfo ? 'ModelPath' : 'FieldPath';
const pathValue = field.connectionInfo
? field.connectionInfo.kind === process_connections_1.CodeGenConnectionType.HAS_MANY
? `${fieldType}.Path(name: \"${fieldName}\", isCollection: true, parent: self)`
: `${fieldType}.Path(name: \"${fieldName}\", parent: self)`
: `${this.getFieldTypePathValue(fieldType)}(\"${fieldName}\")`;
modelPathExtension.addProperty(fieldName, `${pathType}<${fieldType}>`, '', undefined, {
variable: true,
}, undefined, pathValue);
});
return modelPathExtension.string;
}
generateClassLoader() {
const structList = Object.values(this.modelMap).map(typeObj => `${this.getModelName(typeObj)}.self`);
const result = [...this.modelExtensionImports, ''];
const classDeclaration = new swift_declaration_block_1.SwiftDeclarationBlock()
.access('public')
.withName('AmplifyModels')
.asKind('class')
.withProtocols(['AmplifyModelRegistration'])
.final()
.withComment('Contains the set of classes that conforms to the `Model` protocol.');
classDeclaration.addProperty('version', 'String', `"${this.computeVersion()}"`, 'public', {});
const body = structList.map(modelClass => `ModelRegistry.register(modelType: ${modelClass})`).join('\n');
classDeclaration.addClassMethod('registerModels', null, body, [{ type: 'ModelRegistry.Type', name: 'registry', flags: {}, value: undefined }], 'public', {});
result.push(classDeclaration.string);
return result.join('\n');
}
getInitBody(fields) {
let result = fields.map(field => {
if (this.isGenerateModelsForLazyLoadAndCustomSelectionSet()) {
const connectionHasOneOrBelongsTo = this.isHasOneOrBelongsToConnectionField(field);
const escapedFieldName = (0, swift_declaration_block_1.escapeKeywords)(this.getFieldName(field));
const propertyName = connectionHasOneOrBelongsTo ? `_${this.getFieldName(field)}` : escapedFieldName;
const fieldValue = connectionHasOneOrBelongsTo ? `LazyReference(${escapedFieldName})` : escapedFieldName;
return (0, visitor_plugin_common_1.indent)(`self.${propertyName} = ${fieldValue}`);
}
else {
const fieldName = (0, swift_declaration_block_1.escapeKeywords)(this.getFieldName(field));
return (0, visitor_plugin_common_1.indent)(`self.${fieldName} = ${fieldName}`);
}
});
return result.join('\n');
}
getDecoderBody(fields) {
let result = [];
result.push((0, visitor_plugin_common_1.indent)('let values = try decoder.container(keyedBy: CodingKeys.self)'));
fields.forEach(field => {
const connectionHasOneOrBelongsTo = this.isHasOneOrBelongsToConnectionField(field);
const escapedFieldName = (0, swift_declaration_block_1.escapeKeywords)(this.getFieldName(field));
const assignedFieldName = connectionHasOneOrBelongsTo ? `_${this.getFieldName(field)}` : escapedFieldName;
const fieldType = this.getDecoderBodyFieldType(field);
const decodeMethod = field.connectionInfo ? 'decodeIfPresent' : 'decode';
const defaultLazyReference = connectionHasOneOrBelongsTo ? ' ?? LazyReference(identifiers: nil)' : '';
const defaultListReference = this.isHasManyConnectionField(field) ? ' ?? .init()' : '';
const optionalTry = !this.isFieldRequired(field) && !field.connectionInfo ? '?' : '';
result.push((0, visitor_plugin_common_1.indent)(`${assignedFieldName} = try${optionalTry} values.${decodeMethod}(${fieldType}.self, forKey: .${escapedFieldName})${defaultLazyReference}${defaultListReference}`));
});
return result.join('\n');
}
getDecoderBodyFieldType(field) {
const nativeType = this.getNativeType(field);
const optionality = !this.isFieldRequired(field) ? '?' : '';
if (this.isHasOneOrBelongsToConnectionField(field)) {
return `LazyReference<${nativeType}>`;
}
if (field.isList) {
if (field.connectionInfo) {
return `List<${nativeType}>${optionality}`;
}
return `[${nativeType}]`;
}
return `${nativeType}${optionality}`;
}
getEncoderBody(fields) {
let result = [];
result.push((0, visitor_plugin_common_1.indent)('var container = encoder.container(keyedBy: CodingKeys.self)'));
fields.forEach(field => {
const escapedFieldName = (0, swift_declaration_block_1.escapeKeywords)(this.getFieldName(field));
const fieldValue = this.isHasOneOrBelongsToConnectionField(field) ? `_${this.getFieldName(field)}` : escapedFieldName;
result.push((0, visitor_plugin_common_1.indent)(`try container.encode(${fieldValue}, forKey: .${escapedFieldName})`));
});
return result.join('\n');
}
getListType(typeStr, field) {
return `${typeStr}`;
}
generateFieldSchema(field, modelKeysName) {
if (!this.isCustomPKEnabled() && field.type === 'ID' && field.name === 'id') {
return `.id()`;
}
let ofType;
let isReadOnly = '';
const isEnumType = this.isEnumType(field);
const isModelType = this.isModelType(field);
const isNonModelType = this.isNonModelType(field);
const name = `${modelKeysName}.${this.getFieldName(field)}`;
const typeName = this.getSwiftModelTypeName(field);
const { connectionInfo } = field;
const isRequiredField = !this.isHasManyConnectionField(field) && this.config.handleListNullabilityTransparently
? this.isRequiredField(field)
: this.isFieldRequired(field);
const isRequired = isRequiredField ? '.required' : '.optional';
if (connectionInfo) {
if (connectionInfo.kind === process_connections_1.CodeGenConnectionType.HAS_MANY) {
let association = `associatedWith: ${this.getModelName(connectionInfo.connectedModel)}.keys.${this.getFieldName(connectionInfo.associatedWith)}`;
if (connectionInfo.associatedWithNativeReferences) {
association = `associatedFields: [${this.getCodingKey(connectionInfo.connectedModel, connectionInfo.associatedWithNativeReferences)}]`;
}
return `.hasMany(${name}, is: ${isRequired}, ofType: ${typeName}, ${association})`;
}
if (connectionInfo.kind === process_connections_1.CodeGenConnectionType.HAS_ONE) {
let association = `associatedWith: ${this.getModelName(connectionInfo.connectedModel)}.keys.${this.getFieldName(connectionInfo.associatedWith)}`;
if (connectionInfo.associatedWithNativeReferences) {
association = `associatedFields: [${this.getCodingKey(connectionInfo.connectedModel, connectionInfo.associatedWithNativeReferences)}]`;
}
let targetNameAttrStr = '';
if (connectionInfo.targetNames || connectionInfo.targetName) {
targetNameAttrStr = this.isCustomPKEnabled() && connectionInfo.targetNames
? `, targetNames: [${connectionInfo.targetNames.map(target => `"${target}"`).join(', ')}]`
: `, targetName: "${connectionInfo.targetName}"`;
}
return `.hasOne(${name}, is: ${isRequired}, ofType: ${typeName}, ${association}${targetNameAttrStr})`;
}
if (connectionInfo.kind === process_connections_1.CodeGenConnectionType.BELONGS_TO) {
const targetNameAttrStr = this.isCustomPKEnabled()
? `targetNames: [${connectionInfo.targetNames.map(target => `"${target}"`).join(', ')}]`
: `targetName: "${connectionInfo.targetName}"`;
return `.belongsTo(${name}, is: ${isRequired}, ofType: ${typeName}, ${targetNameAttrStr})`;
}
}
if (field.isList) {
if (isModelType) {
ofType = `.collection(of: ${this.getSwiftModelTypeName(field)})`;
}
else {
ofType = `.embeddedCollection(of: ${this.getSwiftModelTypeName(field)})`;
}
}
else {
if (isEnumType) {
ofType = `.enum(type: ${typeName})`;
}
else if (isModelType) {
ofType = `.model(${typeName})`;
}
else if (isNonModelType) {
ofType = `.embedded(type: ${typeName})`;
}
else {
ofType = typeName;
}
}
if (field.isReadOnly) {
isReadOnly = 'isReadOnly: true';
}
const args = [`${name}`, `is: ${isRequired}`, isReadOnly, `ofType: ${ofType}`].filter(arg => arg).join(', ');
return `.field(${args})`;
}
getSwiftModelTypeName(field) {
if (this.isEnumType(field)) {
return `${this.getEnumName(field.type)}.self`;
}
if (this.isModelType(field)) {
return `${this.getModelName(this.modelMap[field.type])}.self`;
}
if (this.isNonModelType(field)) {
return `${this.getNonModelName(this.nonModelMap[field.type])}.self`;
}
if (field.type in swift_config_1.schemaTypeMap) {
if (field.isList) {
return `${this.getNativeType(field)}.self`;
}
return swift_config_1.schemaTypeMap[field.type];
}
return '.string';
}
getFieldTypePathValue(fieldType) {
if (fieldType === 'String') {
return 'string';
}
else if (fieldType === 'Int') {
return 'int';
}
else if (fieldType === 'Double') {
return 'double';
}
else if (fieldType === 'Bool') {
return 'bool';
}
else if (fieldType === 'Temporal.Date') {
return 'date';
}
else if (fieldType === 'Temporal.DateTime') {
return 'datetime';
}
else if (fieldType === 'Temporal.Time') {
return 'time';
}
return fieldType;
}
getEnumValue(value) {
return (0, change_case_1.camelCase)(value);
}
isFieldRequired(field) {
if (this.isHasManyConnectionField(field)) {
return false;
}
return !field.isNullable;
}
generateKeyRules(model) {
return model.directives
.filter(directive => directive.name === 'key')
.map(directive => {
const name = directive.arguments.name ? `"${directive.arguments.name}"` : 'nil';
const fields = directive.arguments.fields.map((field) => `"${field}"`).join(', ');
return `.index(fields: [${fields}], name: ${name})`;
});
}
generatePrimaryKeyRules(model) {
if (!this.isCustomPKEnabled() || this.selectedTypeIsNonModel()) {
return '';
}
const primaryKeyField = model.fields.find(f => f.primaryKeyInfo);
const { sortKeyFields } = primaryKeyField.primaryKeyInfo;
const modelName = (0, lower_case_first_1.lowerCaseFirst)(this.getModelName(model));
return `.primaryKey(fields: [${[primaryKeyField, ...sortKeyFields]
.map(field => `${modelName}.${this.getFieldName(field)}`)
.join(', ')}])`;
}
isHasManyConnectionField(field) {
if (field.connectionInfo && field.connectionInfo.kind === process_connections_1.CodeGenConnectionType.HAS_MANY) {
return true;
}
return false;
}
isHasOneOrBelongsToConnectionField(field) {
if (field.connectionInfo &&
(field.connectionInfo.kind === process_connections_1.CodeGenConnectionType.HAS_ONE || field.connectionInfo.kind === process_connections_1.CodeGenConnectionType.BELONGS_TO)) {
return true;
}
return false;
}
generateAuthRules(model) {
const authDirectives = model.directives.filter(d => d.name === 'auth');
const rules = [];
authDirectives.forEach(directive => {
var _a;
(_a = directive.arguments) === null || _a === void 0 ? void 0 : _a.rules.forEach(rule => {
var _a, _b;
const authRule = [];
switch (rule.allow) {
case process_auth_1.AuthStrategy.owner:
authRule.push('allow: .owner');
authRule.push(`ownerField: "${rule.ownerField}"`);
authRule.push(`identityClaim: "${rule.identityClaim}"`);
break;
case process_auth_1.AuthStrategy.private:
authRule.push('allow: .private');
break;
case process_auth_1.AuthStrategy.public:
authRule.push('allow: .public');
break;
case process_auth_1.AuthStrategy.groups:
authRule.push('allow: .groups');
authRule.push(`groupClaim: "${rule.groupClaim}"`);
if (rule.groups) {
authRule.push(`groups: [${(_a = rule.groups) === null || _a === void 0 ? void 0 : _a.map(group => `"${group}"`).join(', ')}]`);
}
else {
authRule.push(`groupsField: "${rule.groupField}"`);
}
break;
default:
(0, warn_1.printWarning)(`Model ${model.name} has auth with authStrategy ${rule.allow} of which is not yet supported in DataStore.`);
return;
}
if (rule.provider != null && this.config.emitAuthProvider) {
authRule.push(`provider: .${rule.provider}`);
}
authRule.push(`operations: [${(_b = rule.operations) === null || _b === void 0 ? void 0 : _b.map(op => `.${op}`).join(', ')}]`);
rules.push(`rule(${authRule.join(', ')})`);
});
});
if (rules.length) {
return ['[', `${(0, visitor_plugin_common_1.indentMultiline)(rules.join(',\n'))}`, ']'].join('\n');
}
return '';
}
getWritableFields(model) {
return model.fields.filter(f => !f.isReadOnly);
}
hasReadOnlyFields(model) {
return model.fields.filter(f => f.isReadOnly).length !== 0;
}
getCodingKey(model, field) {
return `${this.getModelName(model)}.keys.${this.getFieldName(field)}`;
}
}
exports.AppSyncSwiftVisitor = AppSyncSwiftVisitor;
//# sourceMappingURL=appsync-swift-visitor.js.map