UNPKG

@aws-amplify/appsync-modelgen-plugin

Version:
266 lines 12.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AppSyncModelIntrospectionVisitor = void 0; const visitor_plugin_common_1 = require("@graphql-codegen/visitor-plugin-common"); const scalars_1 = require("../scalars"); const process_connections_1 = require("../utils/process-connections"); const appsync_visitor_1 = require("./appsync-visitor"); const fieldUtils_1 = require("../utils/fieldUtils"); const process_conversation_1 = require("../utils/process-conversation"); const fieldUtils_2 = require("../utils/fieldUtils"); const validateModelIntrospectionSchema = require('../validate-cjs'); ; ; class AppSyncModelIntrospectionVisitor extends appsync_visitor_1.AppSyncModelVisitor { constructor(schema, rawConfig, additionalConfig, defaultScalars = visitor_plugin_common_1.DEFAULT_SCALARS) { super(schema, rawConfig, additionalConfig, defaultScalars); this.introspectionVersion = 1; this.isUnionFieldType = (obj) => { return typeof obj === 'object' && typeof obj.union === 'string'; }; this.isInterfaceFieldType = (obj) => { return typeof obj === 'object' && typeof obj.interface === 'string'; }; } generate() { const shouldUseModelNameFieldInHasManyAndBelongsTo = false; const shouldImputeKeyForUniDirectionalHasMany = true; const shouldUseFieldsInAssociatedWithInHasOne = true; this.processDirectives(shouldUseModelNameFieldInHasManyAndBelongsTo, shouldImputeKeyForUniDirectionalHasMany, shouldUseFieldsInAssociatedWithInHasOne); const modelIntrosepctionSchema = this.generateModelIntrospectionSchema(); if (!validateModelIntrospectionSchema(modelIntrosepctionSchema)) { throw new Error(`Data did not validate against the supplied schema. Underlying errors were ${JSON.stringify(validateModelIntrospectionSchema.errors)}`); } return JSON.stringify(modelIntrosepctionSchema, null, 4); } generateModelIntrospectionSchema() { let result = { version: this.introspectionVersion, models: {}, enums: {}, nonModels: {}, }; const models = Object.values(this.getSelectedModels()).reduce((acc, model) => { return { ...acc, [model.name]: this.generateModelMetadata(model) }; }, {}); const nonModels = Object.values(this.getSelectedNonModels()).reduce((acc, nonModel) => { return { ...acc, [nonModel.name]: this.generateNonModelMetadata(nonModel) }; }, {}); const enums = Object.values(this.enumMap).reduce((acc, enumObj) => { return { ...acc, [this.getEnumName(enumObj)]: this.generateEnumMetadata(enumObj) }; }, {}); result = { ...result, models, nonModels, enums }; const queries = Object.values(this.queryMap).reduce((acc, queryObj) => { const fieldType = this.getType(queryObj.type); if (this.isUnionFieldType(fieldType) || this.isInterfaceFieldType(fieldType) || (0, fieldUtils_1.containsGenerationDirective)(queryObj)) { return acc; } return { ...acc, [queryObj.name]: this.generateGraphQLOperationMetadata(queryObj) }; }, {}); const generations = Object.values(this.queryMap).reduce((acc, queryObj) => { const fieldType = this.getType(queryObj.type); if (this.isUnionFieldType(fieldType) || this.isInterfaceFieldType(fieldType) || !(0, fieldUtils_1.containsGenerationDirective)(queryObj)) { return acc; } return { ...acc, [queryObj.name]: this.generateGenerationMetadata(queryObj) }; }, {}); const mutations = Object.values(this.mutationMap).reduce((acc, mutationObj) => { const fieldType = this.getType(mutationObj.type); if (this.isUnionFieldType(fieldType) || this.isInterfaceFieldType(fieldType) || (0, fieldUtils_2.containsConversationDirective)(mutationObj)) { return acc; } return { ...acc, [mutationObj.name]: this.generateGraphQLOperationMetadata(mutationObj) }; }, {}); const conversations = Object.values(this.mutationMap).reduce((acc, mutationObj) => { if (!(0, fieldUtils_2.containsConversationDirective)(mutationObj)) { return acc; } return { ...acc, [mutationObj.name]: this.generateConversationMetadata(mutationObj) }; }, {}); const subscriptions = Object.values(this.subscriptionMap).reduce((acc, subscriptionObj) => { const fieldType = this.getType(subscriptionObj.type); if (this.isUnionFieldType(fieldType) || this.isInterfaceFieldType(fieldType)) { return acc; } return { ...acc, [subscriptionObj.name]: this.generateGraphQLOperationMetadata(subscriptionObj) }; }, {}); const inputs = Object.values(this.inputObjectMap).reduce((acc, inputObj) => { return { ...acc, [inputObj.name]: this.generateGraphQLInputMetadata(inputObj) }; }, {}); if (Object.keys(queries).length > 0) { result = { ...result, queries }; } if (Object.keys(generations).length > 0) { result = { ...result, generations }; } if (Object.keys(mutations).length > 0) { result = { ...result, mutations }; } if (Object.keys(conversations).length > 0) { result = { ...result, conversations }; } if (Object.keys(subscriptions).length > 0) { result = { ...result, subscriptions }; } if (Object.keys(inputs).length > 0) { result = { ...result, inputs }; } return result; } getFieldAssociation(field) { var _a; if (field.connectionInfo) { const { connectionInfo } = field; const connectionAttribute = { connectionType: connectionInfo.kind }; if (connectionInfo.kind === process_connections_1.CodeGenConnectionType.HAS_MANY) { connectionAttribute.associatedWith = connectionInfo.associatedWithFields.map(f => this.getFieldName(f)); } else if (connectionInfo.kind === process_connections_1.CodeGenConnectionType.HAS_ONE) { connectionAttribute.associatedWith = connectionInfo.associatedWithFields.map(f => this.getFieldName(f)); connectionAttribute.targetNames = (_a = connectionInfo.targetNames) !== null && _a !== void 0 ? _a : []; } else { connectionAttribute.targetNames = connectionInfo.targetNames; } return connectionAttribute; } } generateModelAttributes(model) { return model.directives.map(d => ({ type: d.name, properties: d.arguments, })); } generateModelMetadata(model) { return { ...this.generateNonModelMetadata(model), syncable: true, pluralName: this.pluralizeModelName(model), attributes: this.generateModelAttributes(model), primaryKeyInfo: this.generateModelPrimaryKeyInfo(model), }; } generateNonModelMetadata(nonModel) { return { name: this.getModelName(nonModel), fields: nonModel.fields.reduce((acc, field) => { const fieldType = this.getType(field.type); if (this.isUnionFieldType(fieldType) || this.isInterfaceFieldType(fieldType)) { return acc; } const fieldMeta = { name: this.getFieldName(field), isArray: field.isList, type: fieldType, isRequired: !field.isNullable, attributes: [], }; if (field.isListNullable !== undefined) { fieldMeta.isArrayNullable = field.isListNullable; } if (field.isReadOnly !== undefined) { fieldMeta.isReadOnly = field.isReadOnly; } const association = this.getFieldAssociation(field); if (association) { fieldMeta.association = association; } acc[field.name] = fieldMeta; return acc; }, {}), }; } generateEnumMetadata(enumObj) { return { name: enumObj.name, values: Object.values(enumObj.values), }; } generateGraphQLInputMetadata(inputObj) { return { name: inputObj.name, attributes: inputObj.inputValues.reduce((acc, param) => { const arg = { name: param.name, isArray: param.isList, type: this.getType(param.type), isRequired: !param.isNullable }; if (param.isListNullable !== undefined) { arg.isArrayNullable = param.isListNullable; } return { ...acc, [param.name]: arg }; }, {}), }; } generateGraphQLOperationMetadata(operationObj) { const operationMeta = { name: operationObj.name, isArray: operationObj.isList, type: this.getType(operationObj.type), isRequired: !operationObj.isNullable, }; if (operationObj.isListNullable !== undefined) { operationMeta.isArrayNullable = operationObj.isListNullable; } if (operationObj.parameters && operationObj.parameters.length > 0) { operationMeta.arguments = operationObj.parameters.reduce((acc, param) => { const arg = { name: param.name, isArray: param.isList, type: this.getType(param.type), isRequired: !param.isNullable }; if (param.isListNullable !== undefined) { arg.isArrayNullable = param.isListNullable; } return { ...acc, [param.name]: arg }; }, {}); } return operationMeta; } generateGenerationMetadata(generationObj) { return this.generateGraphQLOperationMetadata(generationObj); } generateConversationMetadata(mutationObj) { return (0, process_conversation_1.processConversationRoute)(mutationObj, this.generateGraphQLOperationMetadata); } getType(gqlType) { if (gqlType in scalars_1.METADATA_SCALAR_MAP) { return scalars_1.METADATA_SCALAR_MAP[gqlType]; } if (gqlType in this.enumMap) { return { enum: this.enumMap[gqlType].name }; } if (gqlType in this.nonModelMap) { return { nonModel: gqlType }; } if (gqlType in this.modelMap) { return { model: gqlType }; } if (gqlType in this.inputObjectMap) { return { input: gqlType }; } if (gqlType in this.unionMap) { return { union: gqlType }; } if (gqlType in this.interfaceMap) { return { interface: gqlType }; } throw new Error(`Unknown type ${gqlType} found during model introspection schema generation`); } generateModelPrimaryKeyInfo(model) { const primaryKeyField = this.getModelPrimaryKeyField(model); if (primaryKeyField && primaryKeyField.primaryKeyInfo) { const { primaryKeyType, sortKeyFields } = primaryKeyField.primaryKeyInfo; return { isCustomPrimaryKey: primaryKeyType === appsync_visitor_1.CodeGenPrimaryKeyType.CustomId, primaryKeyFieldName: this.getFieldName(primaryKeyField), sortKeyFieldNames: sortKeyFields.map(field => this.getFieldName(field)) }; } throw new Error(`No primary key found for model ${model.name}`); } } exports.AppSyncModelIntrospectionVisitor = AppSyncModelIntrospectionVisitor; //# sourceMappingURL=appsync-model-introspection-visitor.js.map