diff --git a/cloudformation/ecs-service.yaml b/cloudformation/ecs-service.yaml
index 47536fb..3099f95 100644
--- a/cloudformation/ecs-service.yaml
+++ b/cloudformation/ecs-service.yaml
@@ -91,7 +91,7 @@ Resources:
Cluster:
Type: AWS::ECS::Cluster
Properties:
- ClusterName: !Join ['', [!Ref 'AWS::StackName', Cluster]]
+ ClusterName: !Join ["", [!Ref "AWS::StackName", Cluster]]
TaskDefinition:
Type: AWS::ECS::TaskDefinition
@@ -99,7 +99,7 @@ Resources:
DependsOn: LogGroup
Properties:
# Name of the task definition. Subsequent versions of the task definition are grouped together under this name.
- Family: !Join ['', [!Ref 'AWS::StackName', TaskDefinition]]
+ Family: !Join ["", [!Ref "AWS::StackName", TaskDefinition]]
# awsvpc is required for Fargate
NetworkMode: awsvpc
RequiresCompatibilities:
@@ -119,14 +119,10 @@ Resources:
- ContainerPort: !Ref ContainerPort
# Define which parameters should be fetched
Secrets:
- - Name: 'DATABASE_URL'
- ValueFrom: !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${EnvironmentName}/graphql-api/DATABASE_URL'
- - Name: 'COGNITO_POOL_ID'
- ValueFrom: !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${EnvironmentName}/cognito/ADMIN_POOL_ID'
- - Name: 'INTERIORS_URL'
- ValueFrom: !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${EnvironmentName}/INTERIORS_URL'
- - Name: 'INTERIORS_TOKEN'
- ValueFrom: !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${EnvironmentName}/INTERIORS_TOKEN'
+ - Name: "DATABASE_URL"
+ ValueFrom: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${EnvironmentName}/graphql-api/DATABASE_URL"
+ - Name: "COGNITO_POOL_ID"
+ ValueFrom: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${EnvironmentName}/cognito/ADMIN_POOL_ID"
# Send logs to CloudWatch Logs
LogConfiguration:
LogDriver: awslogs
@@ -139,47 +135,47 @@ Resources:
ExecutionRole:
Type: AWS::IAM::Role
Properties:
- RoleName: !Join ['', [!Ref 'AWS::StackName', ExecutionRole]]
+ RoleName: !Join ["", [!Ref "AWS::StackName", ExecutionRole]]
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
- Action: 'sts:AssumeRole'
+ Action: "sts:AssumeRole"
ManagedPolicyArns:
- - 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy'
+ - "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
- arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess
# A role for the containers
TaskRole:
Type: AWS::IAM::Role
Properties:
- RoleName: !Join ['', [!Ref 'AWS::StackName', TaskRole]]
+ RoleName: !Join ["", [!Ref "AWS::StackName", TaskRole]]
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
- Action: 'sts:AssumeRole'
+ Action: "sts:AssumeRole"
# A role needed for auto scaling
AutoScalingRole:
Type: AWS::IAM::Role
Properties:
- RoleName: !Join ['', [!Ref 'AWS::StackName', AutoScalingRole]]
+ RoleName: !Join ["", [!Ref "AWS::StackName", AutoScalingRole]]
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
- Action: 'sts:AssumeRole'
+ Action: "sts:AssumeRole"
ManagedPolicyArns:
- - 'arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceAutoscaleRole'
+ - "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceAutoscaleRole"
ContainerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription:
- !Join ['', [!Ref 'AWS::StackName', ContainerSecurityGroup]]
+ !Join ["", [!Ref "AWS::StackName", ContainerSecurityGroup]]
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
@@ -191,7 +187,7 @@ Resources:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription:
- !Join ['', [!Ref 'AWS::StackName', LoadBalancerSecurityGroup]]
+ !Join ["", [!Ref "AWS::StackName", LoadBalancerSecurityGroup]]
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
@@ -239,7 +235,7 @@ Resources:
HealthCheckTimeoutSeconds: 10
UnhealthyThresholdCount: 2
HealthyThresholdCount: 2
- Name: !Join ['', [!Ref 'AWS::StackName', Group]]
+ Name: !Join ["", [!Ref "AWS::StackName", Group]]
Port: !Ref ContainerPort
Protocol: HTTP
TargetGroupAttributes:
@@ -266,7 +262,7 @@ Resources:
LoadBalancerAttributes:
- Key: idle_timeout.timeout_seconds
Value: 1200
- Name: !Join ['', [!Ref 'AWS::StackName', LB]]
+ Name: !Join ["", [!Ref "AWS::StackName", LB]]
# "internal" is also an option
Scheme: internet-facing
SecurityGroups:
@@ -278,8 +274,8 @@ Resources:
DNSRecord:
Type: AWS::Route53::RecordSet
Properties:
- HostedZoneName: !Join ['', [!Ref HostedZoneName, .]]
- Name: !Join ['', [!Ref Subdomain, ., !Ref HostedZoneName, .]]
+ HostedZoneName: !Join ["", [!Ref HostedZoneName, .]]
+ Name: !Join ["", [!Ref Subdomain, ., !Ref HostedZoneName, .]]
Type: A
AliasTarget:
DNSName: !GetAtt LoadBalancer.DNSName
@@ -288,14 +284,14 @@ Resources:
LogGroup:
Type: AWS::Logs::LogGroup
Properties:
- LogGroupName: !Join ['', [/ecs/, !Ref 'AWS::StackName', TaskDefinition]]
+ LogGroupName: !Join ["", [/ecs/, !Ref "AWS::StackName", TaskDefinition]]
AutoScalingTarget:
Type: AWS::ApplicationAutoScaling::ScalableTarget
Properties:
MinCapacity: !Ref MinContainers
MaxCapacity: !Ref MaxContainers
- ResourceId: !Join ['/', [service, !Ref Cluster, !GetAtt Service.Name]]
+ ResourceId: !Join ["/", [service, !Ref Cluster, !GetAtt Service.Name]]
ScalableDimension: ecs:service:DesiredCount
ServiceNamespace: ecs
# "The Amazon Resource Name (ARN) of an AWS Identity and Access Management (IAM) role that allows Application Auto Scaling to modify your scalable target."
@@ -303,7 +299,7 @@ Resources:
AutoScalingPolicy:
Type: AWS::ApplicationAutoScaling::ScalingPolicy
Properties:
- PolicyName: !Join ['', [!Ref 'AWS::StackName', AutoScalingPolicy]]
+ PolicyName: !Join ["", [!Ref "AWS::StackName", AutoScalingPolicy]]
PolicyType: TargetTrackingScaling
ScalingTargetId: !Ref AutoScalingTarget
TargetTrackingScalingPolicyConfiguration:
@@ -331,7 +327,7 @@ Resources:
PolicyDocument:
Version: 2012-10-17
Statement:
- - Resource: '*'
+ - Resource: "*"
Effect: Allow
Action:
- logs:CreateLogGroup
@@ -384,7 +380,7 @@ Resources:
- s3:GetObject
- s3:GetObjectVersion
- s3:GetBucketVersioning
- - Resource: '*'
+ - Resource: "*"
Effect: Allow
Action:
- ecs:List*
@@ -459,7 +455,7 @@ Resources:
Type: AWS::CodePipeline::Pipeline
Properties:
RoleArn: !GetAtt CodePipelineServiceRole.Arn
- Name: !Join ['', [!Ref 'AWS::StackName', Pipeline]]
+ Name: !Join ["", [!Ref "AWS::StackName", Pipeline]]
ArtifactStore:
Type: S3
Location: !Ref ArtifactBucket
@@ -515,7 +511,7 @@ Resources:
Outputs:
Endpoint:
Description: Endpoint
- Value: !Join ['', ['https://', !Ref DNSRecord]]
+ Value: !Join ["", ["https://", !Ref DNSRecord]]
Service:
Value: Service
PipelineUrl:
diff --git a/docker-compose.yml b/docker-compose.yml
index c82ffeb..57012ed 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -14,8 +14,6 @@ services:
environment:
- COGNITO_POOL_ID=eu-west-1_3O4VfvPn7
- DATABASE_URL=${DATABASE_URL}
- - INTERIOR_TOKEN=${INTERIOR_TOKEN}
- - INTERIOR_URL=${INTERIOR_URL}
networks:
default:
diff --git a/src/datasources/interior-api.ts b/src/datasources/interior-api.ts
index b6b313d..51f8b8d 100644
--- a/src/datasources/interior-api.ts
+++ b/src/datasources/interior-api.ts
@@ -47,7 +47,7 @@ export class InteriorAPI extends BaseSQLDataSource {
}
getInteriorRoomNumber(roomNumberPart: string): number {
- return parseInt(roomNumberPart.slice(4), 10);
+ return convertToPossibleType(roomNumberPart.slice(4));
}
decorateRow(row: any): Interior {
diff --git a/src/datasources/interiors-lambda-api.ts b/src/datasources/interiors-lambda-api.ts
deleted file mode 100644
index 810d477..0000000
--- a/src/datasources/interiors-lambda-api.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { RESTDataSource } from 'apollo-datasource-rest';
-import { Product, ProductGroup } from '../types/product-types';
-
-export class InteriorsLambdaAPI extends RESTDataSource {
- constructor() {
- super();
- this.baseURL = process.env.INTERIOR_URL;
- }
-
- /**
- *
- * @param product Product with printProducts and fields
- * Example usage in a resolver
- *
- * const product = await (dataSources.productApi).getProduct(productId);
- * await (dataSources.interiorsLambdaAPI).generateNewInteriors(product);
- *
- */
- async generateNewInteriors(product: Product): Promise {
- const found = product.printProducts.find(
- (pr) => pr.groupId === ProductGroup.WALLPAPER,
- );
- const isRepeating = found !== undefined;
-
- const body = {
- token: process.env.INTERIOR_TOKEN,
- image: `products/${product.id}.jpg`,
- primary_image_area: [
- product.fields.focusXpoint2,
- product.fields.focusYpoint2,
- ],
- autodetect: true,
- };
-
- if (isRepeating) {
- body['print_file_height'] = product.fields.printFileHeight;
- body['print_file_dpi'] = product.fields.printFileDpi;
- }
- return this.post('/batch', body);
- }
-}
diff --git a/src/datasources/order-api.ts b/src/datasources/order-api.ts
index a701053..eb61602 100644
--- a/src/datasources/order-api.ts
+++ b/src/datasources/order-api.ts
@@ -66,7 +66,7 @@ export class OrderAPI extends BaseSQLDataSource {
.count()
.first()
.cache(MINUTE * 60);
- return res['count'] as number; // Optimize later to return Promise
+ return convertToPossibleType(res['count']); // Optimize later to return Promise
}
async getOrders(input: Maybe): Promise> {
diff --git a/src/datasources/product-api.ts b/src/datasources/product-api.ts
index 84506c2..5392a40 100644
--- a/src/datasources/product-api.ts
+++ b/src/datasources/product-api.ts
@@ -17,7 +17,7 @@ import {
ProductSizeTypes,
} from '../types/product-types';
import { Maybe } from '../types/types';
-import { convertToPossibleType, nullOrNumber } from './utils';
+import { convertToPossibleType } from './utils';
const MINUTE = 60;
@@ -75,40 +75,11 @@ export class ProductAPI extends BaseSQLDataSource {
if (!row.fields) {
return null; // 53460 for example
}
- // Convert to camelCase first
const fields = Object.keys(row.fields).reduce((mem, key) => {
- mem[camelcase(key)] = row.fields[key];
+ mem[camelcase(key)] = convertToPossibleType(row.fields[key]);
return mem;
}, {});
- fields['artNo'] = fields['artNo'];
- fields['name'] = fields['name'];
- fields['copyright'] = fields['copyright'] ?? '';
- fields['batch'] = fields['batch'] ?? '';
- fields['height'] = nullOrNumber(fields['height'] ?? null);
- fields['width'] = nullOrNumber(fields['width'] ?? null);
- fields['printFileWidth'] = nullOrNumber(fields['printFileWidth'] ?? null);
- fields['printFileHeight'] = nullOrNumber(fields['printFileHeight'] ?? null);
- fields['printFileDpi'] = nullOrNumber(fields['printFileDpi'] ?? null);
- fields['marginWidthMax'] = nullOrNumber(fields['marginWidthMax'] ?? null);
- fields['marginWidthMin'] = nullOrNumber(fields['marginWidthMin'] ?? null);
- fields['marginHeightMax'] = nullOrNumber(fields['marginHeightMax'] ?? null);
- fields['marginHeightMin'] = nullOrNumber(fields['marginHeightMin'] ?? null);
- fields['focusXpoint2'] = nullOrNumber(fields['focusXpoint2'] ?? null);
- fields['focusYpoint2'] = nullOrNumber(fields['focusYpoint2'] ?? null);
- fields['focusXpoint'] = nullOrNumber(fields['focusXpoint'] ?? null);
- fields['focusYpoint'] = nullOrNumber(fields['focusYpoint'] ?? null);
- fields['photowallResolution'] = nullOrNumber(
- fields['photowallResolution'] ?? null,
- );
- fields['canvasResolution'] = nullOrNumber(
- fields['canvasResolution'] ?? null,
- );
- fields['wallpaperResolution'] = nullOrNumber(
- fields['wallpaperResolution'] ?? null,
- );
- fields['proportionsWarning?'] = fields['proportionsWarning?'] ?? '';
- fields['imageResolution'] = nullOrNumber(fields['imageResolution'] ?? null);
return fields;
}
@@ -133,6 +104,8 @@ export class ProductAPI extends BaseSQLDataSource {
row.fields = this.getProductFields(row);
row.designerId = row.designerid;
row.orientation = this.getOrientation(row.fields);
+ row.copyright = row.copyright ?? '';
+ row.batch = row.batch ?? '';
return row;
}
@@ -141,7 +114,7 @@ export class ProductAPI extends BaseSQLDataSource {
const res = await this.cachedRaw(query)
.cache(MINUTE * 60)
.then((data) => data.rows);
- return res[0]['count'] as number; // Optimize later to return Promise
+ return convertToPossibleType(res[0]['count']); // Optimize later to return Promise
}
async getProducts(input: ProductsFilterInput): Promise> {
diff --git a/src/datasources/utils.ts b/src/datasources/utils.ts
index 373aa4c..b6844ee 100644
--- a/src/datasources/utils.ts
+++ b/src/datasources/utils.ts
@@ -1,10 +1,8 @@
-type InputType = string | undefined | null;
-
-function isNumeric(n: InputType) {
- return !isNaN(parseFloat(n));
+function isNumeric(n: any) {
+ return !isNaN(n);
}
-function isBoolean(n: InputType | boolean) {
+function isBoolean(n: any) {
if (typeof n === 'boolean') {
return true;
}
@@ -15,13 +13,9 @@ function isBoolean(n: InputType | boolean) {
return false;
}
-export function convertToPossibleType(n: InputType) {
+export function convertToPossibleType(n: any) {
if ('' === n) return '';
if (isBoolean(n)) return Boolean(n);
if (isNumeric(n)) return Number(n);
return n;
}
-
-export function nullOrNumber(n: InputType) {
- return n === null || '' === n ? null : Number(n);
-}
diff --git a/src/index.ts b/src/index.ts
index 357187f..3c6ef47 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -17,7 +17,6 @@ import { InteriorAPI } from './datasources/interior-api';
import { verifyToken } from './cognito/cognito-client';
import { readFileSync } from 'fs';
-import { InteriorsLambdaAPI } from './datasources/interiors-lambda-api';
const path = require('path');
const typeDefs = readFileSync(
path.join(__dirname, './schema.graphql'),
@@ -30,7 +29,6 @@ const knexConfig = knexStringcase(dbConfig);
const categoryApi = new CategoryAPI(knexConfig);
const designerApi = new DesignerAPI(knexConfig);
const imageServerApi = new ImageServerApi();
-const interiorsLambdaApi = new InteriorsLambdaAPI();
const interiorApi = new InteriorAPI(knexConfig, imageServerApi);
const keywordApi = new KeywordAPI(knexConfig);
const marketLocaleApi = new MarketLocaleAPI(knexConfig);
@@ -41,7 +39,6 @@ const dataSources = () => ({
categoryApi,
designerApi,
interiorApi,
- interiorsLambdaApi,
imageServerApi,
keywordApi,
marketLocaleApi,
diff --git a/src/resolvers/keywords-resolver.ts b/src/resolvers/keywords-resolver.ts
index 82f2e69..0c36b2d 100644
--- a/src/resolvers/keywords-resolver.ts
+++ b/src/resolvers/keywords-resolver.ts
@@ -30,6 +30,7 @@ export const keywordsMutationTypeDefs = {
name,
type,
);
+ console.log(id);
return (dataSources.keywordApi).getKeywordById(id);
},
};
diff --git a/src/resolvers/products-resolver.ts b/src/resolvers/products-resolver.ts
index 320563b..34b5562 100644
--- a/src/resolvers/products-resolver.ts
+++ b/src/resolvers/products-resolver.ts
@@ -10,7 +10,6 @@ import { KeywordAPI } from '../datasources/keyword-api';
import { Keyword } from '../types/keyword-types';
import { MarketLocaleAPI } from '../datasources/market-locale-api';
import { InteriorAPI } from '../datasources/interior-api';
-import { InteriorsLambdaAPI } from '../datasources/interiors-lambda-api';
const ProductBlacklist = {
async market(parent, _args, { dataSources }) {
@@ -112,13 +111,7 @@ export const productMutationTypeDefs = {
productId,
groupIds,
);
- const product = await (dataSources.productApi).getProduct(
- productId,
- );
- await ((
- dataSources.interiorsLambdaApi
- )).generateNewInteriors(product);
- return product;
+ return (dataSources.productApi).getProduct(productId);
},
async productKeywords(_, { productId, keywordIds }, { dataSources }) {
await (dataSources.keywordApi).setProductKeywords(
diff --git a/src/schema.graphql b/src/schema.graphql
index 1944340..13a84ad 100644
--- a/src/schema.graphql
+++ b/src/schema.graphql
@@ -267,7 +267,7 @@ type ProductFields {
focusYpoint: Float
focusXpoint2: Float
focusYpoint2: Float
- batch: String
+ batch: String!
imageResolution: Int
printFileWidth: Int
printFileHeight: Int