@aws-amplify/graphql-schema-generator
Version:
Amplify GraphQL schema generator
204 lines • 16.3 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createConfigureExpression = exports.createImportExpression = exports.createSchema = void 0;
const typescript_1 = __importDefault(require("typescript"));
const graphql_transformer_common_1 = require("graphql-transformer-common");
const schema_representation_1 = require("../schema-representation");
const GQL_TYPESCRIPT_DATA_SCHEMA_TYPE_MAP = {
string: 'string',
int: 'integer',
float: 'float',
boolean: 'boolean',
id: 'id',
awsdate: 'date',
awstime: 'time',
awsdatetime: 'datetime',
awstimestamp: 'timestamp',
awsjson: 'json',
awsemail: 'email',
awsphone: 'phone',
awsurl: 'url',
awsipaddress: 'ipAddress',
};
const createProperty = (field) => {
const typeExpression = createDataType(field);
return typescript_1.default.factory.createPropertyAssignment(typescript_1.default.factory.createIdentifier(field.name), typeExpression);
};
const createDataType = (field) => {
if (isSequenceField(field)) {
const baseTypeExpression = field.type.kind === 'NonNull'
? createDataType(new schema_representation_1.Field(field.name, field.type.type))
: createDataType(new schema_representation_1.Field(field.name, field.type));
return typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createPropertyAccessExpression(baseTypeExpression, graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.DEFAULT_METHOD), undefined, undefined);
}
if (field.type.kind === 'Scalar') {
return typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createIdentifier(`${graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.REFERENCE_A}.${getTypescriptDataSchemaType(field.type.name)}`), undefined, undefined);
}
if (field.type.kind === 'Enum') {
return typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createIdentifier(`${graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.REFERENCE_A}.${graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.REF_METHOD}`), undefined, [typescript_1.default.factory.createStringLiteral((0, graphql_transformer_common_1.toPascalCase)([field.type.name]))]);
}
if (field.type.kind === 'Custom') {
return typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createIdentifier(`${graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.REFERENCE_A}.${graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.STRING_METHOD}`), undefined, undefined);
}
const modifier = field.type.kind === 'List' ? graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.ARRAY_METHOD : graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.REQUIRED_METHOD;
const unwrappedField = new schema_representation_1.Field(field.name, field.type.type);
return typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createPropertyAccessExpression(createDataType(unwrappedField), typescript_1.default.factory.createIdentifier(modifier)), undefined, undefined);
};
const isSequenceField = (field) => {
var _a;
const sequenceRegex = /^nextval\(.+::regclass\)$/;
return ((_a = field.default) === null || _a === void 0 ? void 0 : _a.kind) === 'DB_GENERATED' && sequenceRegex.test(field.default.value.toString());
};
const getTypescriptDataSchemaType = (type) => {
const DEFAULT_DATATYPE = graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.STRING_METHOD;
const tsDataSchemaType = GQL_TYPESCRIPT_DATA_SCHEMA_TYPE_MAP[type.toLowerCase()];
return tsDataSchemaType !== null && tsDataSchemaType !== void 0 ? tsDataSchemaType : DEFAULT_DATATYPE;
};
const createModelDefinition = (model) => {
const properties = model.getFields().map((field) => {
return createProperty(field);
});
return typescript_1.default.factory.createObjectLiteralExpression(properties, true);
};
const createEnums = (type) => {
const typeExpression = typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createIdentifier(`${graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.REFERENCE_A}.${graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.ENUM_METHOD}`), undefined, [
typescript_1.default.factory.createArrayLiteralExpression(type.values.map((value) => typescript_1.default.factory.createStringLiteral(value)), true),
]);
return typescript_1.default.factory.createPropertyAssignment(typescript_1.default.factory.createIdentifier((0, graphql_transformer_common_1.toPascalCase)([type.name])), typeExpression);
};
const createModel = (model) => {
const modelExpr = typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createIdentifier(`${graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.REFERENCE_A}.${graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.MODEL_METHOD}`), undefined, [createModelDefinition(model)]);
const modelExprWithPK = typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createPropertyAccessExpression(modelExpr, typescript_1.default.factory.createIdentifier(graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.IDENTIFIER_METHOD)), undefined, [
typescript_1.default.factory.createArrayLiteralExpression(model
.getPrimaryKey()
.getFields()
.map((field) => typescript_1.default.factory.createStringLiteral(field)), true),
]);
return typescript_1.default.factory.createPropertyAssignment(typescript_1.default.factory.createStringLiteral(model.getName()), modelExprWithPK);
};
const exportModifier = typescript_1.default.factory.createModifier(typescript_1.default.SyntaxKind.ExportKeyword);
const createSchema = (schema, config) => {
const modelsWithPrimaryKeyCount = schema.getModels().filter((model) => model.getPrimaryKey()).length;
if (modelsWithPrimaryKeyCount === 0) {
throw new Error('No valid tables found. Make sure at least one table has a primary key.');
}
const nullableEnumFields = schema.getModels().map((model) => model
.getFields()
.filter((field) => field.type.kind === 'Enum')
.map((field) => {
if (field.type.kind === 'Enum') {
return createEnums(field.type);
}
else {
return undefined;
}
}));
const requiredEnumFields = schema.getModels().map((model) => model
.getFields()
.filter((field) => field.type.kind === 'NonNull' && field.type.type.kind === 'Enum')
.map((field) => {
if (field.type.kind === 'NonNull' && field.type.type.kind === 'Enum') {
return createEnums(field.type.type);
}
else {
return undefined;
}
}));
const models = schema
.getModels()
.filter((model) => model.getPrimaryKey())
.map((model) => {
return createModel(model);
});
const combinedEnums = nullableEnumFields.concat(requiredEnumFields).flat();
const seenEnums = new Set();
const uniqueEnums = combinedEnums.filter((node) => {
if (seenEnums.has(node['name'].escapedText)) {
return false;
}
else {
seenEnums.add(node['name'].escapedText);
return true;
}
});
const modelsWithEnums = models.concat(uniqueEnums);
const tsSchema = typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createPropertyAccessExpression((0, exports.createConfigureExpression)(schema, config), typescript_1.default.factory.createIdentifier(graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.SCHEMA_METHOD)), undefined, [typescript_1.default.factory.createObjectLiteralExpression(modelsWithEnums, true)]);
return typescript_1.default.factory.createVariableStatement([exportModifier], typescript_1.default.factory.createVariableDeclarationList([
typescript_1.default.factory.createVariableDeclaration(typescript_1.default.factory.createIdentifier(graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.EXPORT_VARIABLE_NAME), undefined, undefined, tsSchema),
], typescript_1.default.NodeFlags.Const));
};
exports.createSchema = createSchema;
const createImportExpression = (containsSecret) => {
const importStatement = typescript_1.default.factory.createImportDeclaration(undefined, typescript_1.default.factory.createImportClause(false, undefined, typescript_1.default.factory.createNamedImports([
typescript_1.default.factory.createImportSpecifier(false, undefined, typescript_1.default.factory.createIdentifier(graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.REFERENCE_A)),
])), typescript_1.default.factory.createStringLiteral(graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.SCHEMA_PACKAGE));
const internalsConfigureImportStatement = typescript_1.default.factory.createImportDeclaration(undefined, typescript_1.default.factory.createImportClause(false, undefined, typescript_1.default.factory.createNamedImports([
typescript_1.default.factory.createImportSpecifier(false, undefined, typescript_1.default.factory.createIdentifier(graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.INTERNALS_CONFIGURE_METHOD)),
])), typescript_1.default.factory.createStringLiteral(graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.SCHEMA_PACKAGE_INTERNALS));
const secretImportStatement = typescript_1.default.factory.createImportDeclaration(undefined, typescript_1.default.factory.createImportClause(false, undefined, typescript_1.default.factory.createNamedImports([
typescript_1.default.factory.createImportSpecifier(false, undefined, typescript_1.default.factory.createIdentifier(graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.BACKEND_SECRET_METHOD)),
])), typescript_1.default.factory.createStringLiteral(graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.BACKEND_PACKAGE));
const importStatementWithEslintDisabled = typescript_1.default.addSyntheticLeadingComment(importStatement, typescript_1.default.SyntaxKind.MultiLineCommentTrivia, ' eslint-disable ', true);
const importStatementWithAutoGeneratedComment = typescript_1.default.addSyntheticLeadingComment(importStatementWithEslintDisabled, typescript_1.default.SyntaxKind.MultiLineCommentTrivia, ' THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. ', true);
const importExpressions = [importStatementWithAutoGeneratedComment];
if (containsSecret) {
importExpressions.push(internalsConfigureImportStatement, secretImportStatement);
}
return typescript_1.default.factory.createNodeArray(importExpressions);
};
exports.createImportExpression = createImportExpression;
const createConfigureExpression = (schema, config) => {
var _a, _b;
if (!config) {
return typescript_1.default.factory.createIdentifier(graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.REFERENCE_A);
}
const databaseConfig = [
typescript_1.default.factory.createPropertyAssignment(typescript_1.default.factory.createIdentifier(graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.PROPERTY_IDENTIFIER), typescript_1.default.factory.createStringLiteral(config.identifier)),
typescript_1.default.factory.createPropertyAssignment(typescript_1.default.factory.createIdentifier(graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.PROPERTY_ENGINE), typescript_1.default.factory.createStringLiteral(convertDBEngineToDBProtocol(schema.getEngine().type))),
];
if ((_a = config === null || config === void 0 ? void 0 : config.secretNames) === null || _a === void 0 ? void 0 : _a.connectionUri) {
databaseConfig.push(typescript_1.default.factory.createPropertyAssignment(typescript_1.default.factory.createIdentifier(graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.PROPERTY_CONNECTION_URI), typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createIdentifier(graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.BACKEND_SECRET_METHOD), undefined, [
typescript_1.default.factory.createStringLiteral(config.secretNames.connectionUri),
])));
}
if ((_b = config === null || config === void 0 ? void 0 : config.secretNames) === null || _b === void 0 ? void 0 : _b.sslCertificate) {
databaseConfig.push(typescript_1.default.factory.createPropertyAssignment(typescript_1.default.factory.createIdentifier(graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.PROPERTY_SSL_CERTIFICATE), typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createIdentifier(graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.BACKEND_SECRET_METHOD), undefined, [
typescript_1.default.factory.createStringLiteral(config.secretNames.sslCertificate),
])));
}
if (config.vpcConfig) {
databaseConfig.push(typescript_1.default.factory.createPropertyAssignment(typescript_1.default.factory.createIdentifier(graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.PROPERTY_VPC), createVpcConfigExpression(config.vpcConfig)));
}
const dbConfig = typescript_1.default.factory.createObjectLiteralExpression([
typescript_1.default.factory.createPropertyAssignment(typescript_1.default.factory.createIdentifier(graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.PROPERTY_DATABASE), typescript_1.default.factory.createObjectLiteralExpression(databaseConfig, true)),
], true);
const configureExpr = typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createIdentifier(`${graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.INTERNALS_CONFIGURE_METHOD}`), undefined, [dbConfig]);
return configureExpr;
};
exports.createConfigureExpression = createConfigureExpression;
const convertDBEngineToDBProtocol = (engine) => {
switch (engine) {
case 'MySQL':
return 'mysql';
case 'Postgres':
return 'postgresql';
default:
return 'dynamodb';
}
};
const createVpcConfigExpression = (vpc) => {
const vpcIdExpression = typescript_1.default.factory.createPropertyAssignment(typescript_1.default.factory.createIdentifier(graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.PROPERTY_VPC_ID), typescript_1.default.factory.createStringLiteral(vpc.vpcId));
const securityGroupIdsExpression = typescript_1.default.factory.createPropertyAssignment(typescript_1.default.factory.createIdentifier(graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.PROPERTY_SECURITY_GROUP_IDS), typescript_1.default.factory.createArrayLiteralExpression(vpc.securityGroupIds.map((sg) => typescript_1.default.factory.createStringLiteral(sg)), true));
const subnetAvailabilityZoneExpression = typescript_1.default.factory.createPropertyAssignment(typescript_1.default.factory.createIdentifier(graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.PROPERTY_AZ_CONFIG), typescript_1.default.factory.createArrayLiteralExpression(vpc.subnetAvailabilityZoneConfig.map((az) => {
return typescript_1.default.factory.createObjectLiteralExpression([
typescript_1.default.factory.createPropertyAssignment(typescript_1.default.factory.createIdentifier(graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.PROPERTY_SUBNET_ID), typescript_1.default.factory.createStringLiteral(az.subnetId)),
typescript_1.default.factory.createPropertyAssignment(typescript_1.default.factory.createIdentifier(graphql_transformer_common_1.TYPESCRIPT_DATA_SCHEMA_CONSTANTS.PROPERTY_AZ), typescript_1.default.factory.createStringLiteral(az.availabilityZone)),
], true);
}), true));
const vpcConfig = typescript_1.default.factory.createObjectLiteralExpression([vpcIdExpression, securityGroupIdsExpression, subnetAvailabilityZoneExpression], true);
return vpcConfig;
};
//# sourceMappingURL=helpers.js.map