UNPKG

@aws-amplify/appsync-modelgen-plugin

Version:
654 lines 35.7 kB
"use strict"; 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