New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

graphql-connection-transformer

Package Overview
Dependencies
Maintainers
2
Versions
983
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

graphql-connection-transformer - npm Package Compare versions

Comparing version 1.1.0-alpha.0a106b94 to 1.1.0-alpha.0c569abc

19

CHANGELOG.md

@@ -6,2 +6,21 @@ # Change Log

<a name="1.0.28"></a>
## [1.0.28](https://github.com/aws-amplify/amplify-cli/compare/graphql-connection-transformer@1.0.28-beta.0...graphql-connection-transformer@1.0.28) (2018-10-18)
**Note:** Version bump only for package graphql-connection-transformer
<a name="1.0.28-beta.0"></a>
## [1.0.28-beta.0](https://github.com/aws-amplify/amplify-cli/compare/graphql-connection-transformer@1.0.12...graphql-connection-transformer@1.0.28-beta.0) (2018-10-12)
### Bug Fixes
* **graphql-connection-transformer:** Remove unused types ([87c3e0a](https://github.com/aws-amplify/amplify-cli/commit/87c3e0a))
<a name="1.0.12"></a>

@@ -8,0 +27,0 @@ ## [1.0.12](https://github.com/aws-amplify/amplify-cli/compare/graphql-connection-transformer@1.0.11...graphql-connection-transformer@1.0.12) (2018-08-23)

13

lib/__tests__/ModelConnectionTransformer.test.js

@@ -237,2 +237,13 @@ "use strict";

});
test('Test ModelConnectionTransformer with sortField fails if not specified in associated type', function () {
var validSchema = "\n type Post @model {\n id: ID!\n title: String!\n comments: [Comment] @connection(name: \"PostComments\", sortField: \"createdAt\")\n }\n type Comment @model {\n id: ID!\n content: String\n post: Post @connection(name: \"PostComments\")\n }\n ";
var transformer = new graphql_transformer_core_1.default({
transformers: [
new graphql_appsync_transformer_1.default(),
new graphql_dynamodb_transformer_1.default(),
new ModelConnectionTransformer_1.ModelConnectionTransformer()
]
});
expect(function () { transformer.transform(validSchema); }).toThrowError();
});
function expectFields(type, fields) {

@@ -274,4 +285,4 @@ var _loop_1 = function (fieldName) {

function verifyInputCount(doc, type, count) {
return doc.definitions.filter(function (def) { return def.kind === graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION && def.name.value === type; }).length == count;
return doc.definitions.filter(function (def) { return def.kind === graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION && def.name.value === type; }).length === count;
}
//# sourceMappingURL=ModelConnectionTransformer.test.js.map

@@ -40,3 +40,3 @@ "use strict";

function ModelConnectionTransformer() {
var _this = _super.call(this, 'ModelConnectionTransformer', "directive @connection(name: String, keyField: String) on FIELD_DEFINITION") || this;
var _this = _super.call(this, 'ModelConnectionTransformer', "directive @connection(name: String, keyField: String, sortField: String) on FIELD_DEFINITION") || this;
_this.before = function (ctx) {

@@ -69,2 +69,4 @@ var template = _this.resources.initTemplate();

var connectionName = graphql_transformer_common_1.getDirectiveArgument(directive)("name");
var associatedSortFieldName = null;
var sortType = null;
// Find the associated connection field if one exists.

@@ -75,3 +77,6 @@ var associatedConnectionField = relatedType.fields.find(function (f) {

var relatedDirectiveName = graphql_transformer_common_1.getDirectiveArgument(relatedDirective)("name");
return connectionName && relatedDirectiveName && relatedDirectiveName === connectionName;
if (connectionName && relatedDirectiveName && relatedDirectiveName === connectionName) {
associatedSortFieldName = graphql_transformer_common_1.getDirectiveArgument(relatedDirective)('sortField');
return true;
}
}

@@ -89,2 +94,14 @@ return false;

var connectionAttributeName = graphql_transformer_common_1.getDirectiveArgument(directive)("keyField");
var associatedSortField = associatedSortFieldName &&
parent.fields.find(function (f) { return f.name.value === associatedSortFieldName; });
if (associatedSortField) {
if (graphql_transformer_common_1.isListType(associatedSortField.type)) {
throw new graphql_transformer_core_1.InvalidDirectiveError("sortField \"" + associatedSortFieldName + "\" is a list. It should be a scalar.");
}
sortType = graphql_transformer_common_1.getBaseType(associatedSortField.type);
if (!graphql_transformer_common_1.isScalar(associatedSortField.type) || sortType === graphql_transformer_common_1.STANDARD_SCALARS.Boolean) {
throw new graphql_transformer_core_1.InvalidDirectiveError("sortField \"" + associatedSortFieldName + "\" is of type \"" + sortType + "\". " +
"It should be a scalar that maps to a DynamoDB \"String\", \"Number\", or \"Binary\"");
}
}
// Relationship Cardinalities:

@@ -116,2 +133,7 @@ // 1. [] to []

// This is the inverse of 2.
// if the sortField is not defined as a field, throw an error
// Cannot assume the required type of the field
if (associatedSortFieldName && !associatedSortField) {
throw new graphql_transformer_core_1.InvalidDirectiveError("sortField \"" + associatedSortFieldName + "\" not found on type \"" + parent.name.value + "\", other half of connection \"" + connectionName + "\".");
}
if (!connectionAttributeName) {

@@ -122,3 +144,4 @@ connectionAttributeName = makeConnectionAttributeName(parentTypeName, fieldName);

var table = ctx.getResource(tableLogicalId);
var updated = _this.resources.updateTableForConnection(table, connectionName, connectionAttributeName);
var sortField = associatedSortField ? { name: associatedSortFieldName, type: sortType } : null;
var updated = _this.resources.updateTableForConnection(table, connectionName, connectionAttributeName, sortField);
ctx.setResource(tableLogicalId, updated);

@@ -125,0 +148,0 @@ var getResolver = _this.resources.makeGetItemConnectionResolver(parentTypeName, fieldName, relatedTypeName, connectionAttributeName);

23

lib/resources.js

@@ -29,3 +29,4 @@ "use strict";

*/
ResourceFactory.prototype.updateTableForConnection = function (table, connectionName, connectionAttributeName) {
ResourceFactory.prototype.updateTableForConnection = function (table, connectionName, connectionAttributeName, sortField) {
if (sortField === void 0) { sortField = null; }
var gsis = table.Properties.GlobalSecondaryIndexes || [];

@@ -39,10 +40,9 @@ if (gsis.length >= 5) {

if (!existingGSI) {
var keySchema = [new table_1.KeySchema({ AttributeName: connectionAttributeName, KeyType: 'HASH' })];
if (sortField) {
keySchema.push(new table_1.KeySchema({ AttributeName: sortField.name, KeyType: 'RANGE' }));
}
gsis.push(new table_1.GlobalSecondaryIndex({
IndexName: connectionGSIName,
KeySchema: [
new table_1.KeySchema({
AttributeName: connectionAttributeName,
KeyType: 'HASH'
})
],
KeySchema: keySchema,
Projection: new table_1.Projection({

@@ -66,2 +66,11 @@ ProjectionType: 'ALL'

}
// If the attribute definition does not exist yet, add it.
if (sortField) {
var existingSortAttribute = attributeDefinitions.find(function (attr) { return attr.AttributeName === sortField.name; });
if (!existingSortAttribute) {
var scalarType = graphql_transformer_common_1.DEFAULT_SCALARS[sortField.type];
var attributeType = scalarType === 'String' ? 'S' : 'N';
attributeDefinitions.push(new table_1.AttributeDefinition({ AttributeName: sortField.name, AttributeType: attributeType }));
}
}
table.Properties.GlobalSecondaryIndexes = gsis;

@@ -68,0 +77,0 @@ table.Properties.AttributeDefinitions = attributeDefinitions;

{
"name": "graphql-connection-transformer",
"version": "1.1.0-alpha.0a106b94",
"version": "1.1.0-alpha.0c569abc",
"description": "An AppSync model transform for connecting objects.",

@@ -21,6 +21,6 @@ "main": "lib/index.js",

"graphql": "^0.13.2",
"graphql-dynamodb-transformer": "^1.1.0-alpha.0a106b94",
"graphql-mapping-template": "^1.1.0-alpha.0a106b94",
"graphql-transformer-common": "^1.1.0-alpha.0a106b94",
"graphql-transformer-core": "^1.1.0-alpha.0a106b94"
"graphql-dynamodb-transformer": "^1.1.0-alpha.0c569abc",
"graphql-mapping-template": "^1.1.0-alpha.0c569abc",
"graphql-transformer-common": "^1.1.0-alpha.0c569abc",
"graphql-transformer-core": "^1.1.0-alpha.0c569abc"
},

@@ -32,3 +32,3 @@ "devDependencies": {

"aws-sdk": "^2.259.1",
"graphql-appsync-transformer": "^1.1.0-alpha.0a106b94",
"graphql-appsync-transformer": "^1.1.0-alpha.0c569abc",
"jest": "^23.1.0",

@@ -35,0 +35,0 @@ "ts-jest": "^22.4.6",

@@ -365,2 +365,25 @@ import {

test('Test ModelConnectionTransformer with sortField fails if not specified in associated type', () => {
const validSchema = `
type Post @model {
id: ID!
title: String!
comments: [Comment] @connection(name: "PostComments", sortField: "createdAt")
}
type Comment @model {
id: ID!
content: String
post: Post @connection(name: "PostComments")
}
`
const transformer = new GraphQLTransform({
transformers: [
new AppSyncTransformer(),
new DynamoDBModelTransformer(),
new ModelConnectionTransformer()
]
})
expect(() => { transformer.transform(validSchema) }).toThrowError()
});
function expectFields(type: ObjectTypeDefinitionNode, fields: string[]) {

@@ -401,3 +424,3 @@ for (const fieldName of fields) {

function verifyInputCount(doc: DocumentNode, type: string, count: number): boolean {
return doc.definitions.filter(def => def.kind === Kind.INPUT_OBJECT_TYPE_DEFINITION && def.name.value === type).length == count;
return doc.definitions.filter(def => def.kind === Kind.INPUT_OBJECT_TYPE_DEFINITION && def.name.value === type).length === count;
}

@@ -18,2 +18,3 @@ import { Transformer, TransformerContext, InvalidDirectiveError } from 'graphql-transformer-core'

getBaseType, isListType, getDirectiveArgument, blankObject,
isScalar, STANDARD_SCALARS,
toCamelCase, isNonNullType

@@ -41,3 +42,3 @@ } from 'graphql-transformer-common'

'ModelConnectionTransformer',
`directive @connection(name: String, keyField: String) on FIELD_DEFINITION`
`directive @connection(name: String, keyField: String, sortField: String) on FIELD_DEFINITION`
)

@@ -84,2 +85,4 @@ this.resources = new ResourceFactory();

let connectionName = getDirectiveArgument(directive)("name")
let associatedSortFieldName = null
let sortType = null
// Find the associated connection field if one exists.

@@ -91,3 +94,6 @@ const associatedConnectionField = relatedType.fields.find(

const relatedDirectiveName = getDirectiveArgument(relatedDirective)("name")
return connectionName && relatedDirectiveName && relatedDirectiveName === connectionName
if (connectionName && relatedDirectiveName && relatedDirectiveName === connectionName) {
associatedSortFieldName = getDirectiveArgument(relatedDirective)('sortField')
return true
}
}

@@ -111,3 +117,20 @@ return false

let connectionAttributeName = getDirectiveArgument(directive)("keyField")
const associatedSortField = associatedSortFieldName &&
parent.fields.find((f: FieldDefinitionNode) => f.name.value === associatedSortFieldName)
if (associatedSortField) {
if (isListType(associatedSortField.type)) {
throw new InvalidDirectiveError(
`sortField "${associatedSortFieldName}" is a list. It should be a scalar.`
)
}
sortType = getBaseType(associatedSortField.type)
if (!isScalar(associatedSortField.type) || sortType === STANDARD_SCALARS.Boolean) {
throw new InvalidDirectiveError(
`sortField "${associatedSortFieldName}" is of type "${sortType}". ` +
`It should be a scalar that maps to a DynamoDB "String", "Number", or "Binary"`
)
}
}
// Relationship Cardinalities:

@@ -145,2 +168,10 @@ // 1. [] to []

// if the sortField is not defined as a field, throw an error
// Cannot assume the required type of the field
if (associatedSortFieldName && !associatedSortField) {
throw new InvalidDirectiveError(
`sortField "${associatedSortFieldName}" not found on type "${parent.name.value}", other half of connection "${connectionName}".`
)
}
if (!connectionAttributeName) {

@@ -151,3 +182,5 @@ connectionAttributeName = makeConnectionAttributeName(parentTypeName, fieldName)

const table = ctx.getResource(tableLogicalId) as Table
const updated = this.resources.updateTableForConnection(table, connectionName, connectionAttributeName)
const sortField = associatedSortField ? { name: associatedSortFieldName, type: sortType } : null
const updated = this.resources.updateTableForConnection(table, connectionName, connectionAttributeName,
sortField)
ctx.setResource(tableLogicalId, updated)

@@ -154,0 +187,0 @@

@@ -10,3 +10,3 @@ import Table, { GlobalSecondaryIndex, KeySchema, Projection, ProvisionedThroughput, AttributeDefinition } from 'cloudform/types/dynamoDb/table'

} from 'graphql-mapping-template'
import { ResourceConstants, ModelResourceIDs } from 'graphql-transformer-common'
import { ResourceConstants, ModelResourceIDs, DEFAULT_SCALARS } from 'graphql-transformer-common'
import { InvalidDirectiveError } from 'graphql-transformer-core';

@@ -39,2 +39,3 @@

connectionAttributeName: string,
sortField: { name: string, type: string } = null
): Table {

@@ -52,10 +53,9 @@ const gsis = table.Properties.GlobalSecondaryIndexes || [] as GlobalSecondaryIndex[]

if (!existingGSI) {
const keySchema = [new KeySchema({ AttributeName: connectionAttributeName, KeyType: 'HASH' })]
if (sortField) {
keySchema.push(new KeySchema({ AttributeName: sortField.name, KeyType: 'RANGE' }))
}
gsis.push(new GlobalSecondaryIndex({
IndexName: connectionGSIName,
KeySchema: [
new KeySchema({
AttributeName: connectionAttributeName,
KeyType: 'HASH'
})
],
KeySchema: keySchema,
Projection: new Projection({

@@ -80,2 +80,13 @@ ProjectionType: 'ALL'

}
// If the attribute definition does not exist yet, add it.
if (sortField) {
const existingSortAttribute = attributeDefinitions.find(attr => attr.AttributeName === sortField.name)
if (!existingSortAttribute) {
const scalarType = DEFAULT_SCALARS[sortField.type]
const attributeType = scalarType === 'String' ? 'S' : 'N'
attributeDefinitions.push(new AttributeDefinition({ AttributeName: sortField.name, AttributeType: attributeType }))
}
}
table.Properties.GlobalSecondaryIndexes = gsis

@@ -82,0 +93,0 @@ table.Properties.AttributeDefinitions = attributeDefinitions

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc