Be more careful with default types (#34)
This commit is contained in:
@@ -91,7 +91,7 @@ Resources:
|
|||||||
Cluster:
|
Cluster:
|
||||||
Type: AWS::ECS::Cluster
|
Type: AWS::ECS::Cluster
|
||||||
Properties:
|
Properties:
|
||||||
ClusterName: !Join ["", [!Ref "AWS::StackName", Cluster]]
|
ClusterName: !Join ['', [!Ref 'AWS::StackName', Cluster]]
|
||||||
|
|
||||||
TaskDefinition:
|
TaskDefinition:
|
||||||
Type: AWS::ECS::TaskDefinition
|
Type: AWS::ECS::TaskDefinition
|
||||||
@@ -99,7 +99,7 @@ Resources:
|
|||||||
DependsOn: LogGroup
|
DependsOn: LogGroup
|
||||||
Properties:
|
Properties:
|
||||||
# Name of the task definition. Subsequent versions of the task definition are grouped together under this name.
|
# 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
|
# awsvpc is required for Fargate
|
||||||
NetworkMode: awsvpc
|
NetworkMode: awsvpc
|
||||||
RequiresCompatibilities:
|
RequiresCompatibilities:
|
||||||
@@ -119,10 +119,14 @@ Resources:
|
|||||||
- ContainerPort: !Ref ContainerPort
|
- ContainerPort: !Ref ContainerPort
|
||||||
# Define which parameters should be fetched
|
# Define which parameters should be fetched
|
||||||
Secrets:
|
Secrets:
|
||||||
- Name: "DATABASE_URL"
|
- Name: 'DATABASE_URL'
|
||||||
ValueFrom: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${EnvironmentName}/graphql-api/DATABASE_URL"
|
ValueFrom: !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${EnvironmentName}/graphql-api/DATABASE_URL'
|
||||||
- Name: "COGNITO_POOL_ID"
|
- Name: 'COGNITO_POOL_ID'
|
||||||
ValueFrom: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${EnvironmentName}/cognito/ADMIN_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'
|
||||||
# Send logs to CloudWatch Logs
|
# Send logs to CloudWatch Logs
|
||||||
LogConfiguration:
|
LogConfiguration:
|
||||||
LogDriver: awslogs
|
LogDriver: awslogs
|
||||||
@@ -135,47 +139,47 @@ Resources:
|
|||||||
ExecutionRole:
|
ExecutionRole:
|
||||||
Type: AWS::IAM::Role
|
Type: AWS::IAM::Role
|
||||||
Properties:
|
Properties:
|
||||||
RoleName: !Join ["", [!Ref "AWS::StackName", ExecutionRole]]
|
RoleName: !Join ['', [!Ref 'AWS::StackName', ExecutionRole]]
|
||||||
AssumeRolePolicyDocument:
|
AssumeRolePolicyDocument:
|
||||||
Statement:
|
Statement:
|
||||||
- Effect: Allow
|
- Effect: Allow
|
||||||
Principal:
|
Principal:
|
||||||
Service: ecs-tasks.amazonaws.com
|
Service: ecs-tasks.amazonaws.com
|
||||||
Action: "sts:AssumeRole"
|
Action: 'sts:AssumeRole'
|
||||||
ManagedPolicyArns:
|
ManagedPolicyArns:
|
||||||
- "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
|
- 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy'
|
||||||
- arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess
|
- arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess
|
||||||
# A role for the containers
|
# A role for the containers
|
||||||
TaskRole:
|
TaskRole:
|
||||||
Type: AWS::IAM::Role
|
Type: AWS::IAM::Role
|
||||||
Properties:
|
Properties:
|
||||||
RoleName: !Join ["", [!Ref "AWS::StackName", TaskRole]]
|
RoleName: !Join ['', [!Ref 'AWS::StackName', TaskRole]]
|
||||||
AssumeRolePolicyDocument:
|
AssumeRolePolicyDocument:
|
||||||
Statement:
|
Statement:
|
||||||
- Effect: Allow
|
- Effect: Allow
|
||||||
Principal:
|
Principal:
|
||||||
Service: ecs-tasks.amazonaws.com
|
Service: ecs-tasks.amazonaws.com
|
||||||
Action: "sts:AssumeRole"
|
Action: 'sts:AssumeRole'
|
||||||
|
|
||||||
# A role needed for auto scaling
|
# A role needed for auto scaling
|
||||||
AutoScalingRole:
|
AutoScalingRole:
|
||||||
Type: AWS::IAM::Role
|
Type: AWS::IAM::Role
|
||||||
Properties:
|
Properties:
|
||||||
RoleName: !Join ["", [!Ref "AWS::StackName", AutoScalingRole]]
|
RoleName: !Join ['', [!Ref 'AWS::StackName', AutoScalingRole]]
|
||||||
AssumeRolePolicyDocument:
|
AssumeRolePolicyDocument:
|
||||||
Statement:
|
Statement:
|
||||||
- Effect: Allow
|
- Effect: Allow
|
||||||
Principal:
|
Principal:
|
||||||
Service: ecs-tasks.amazonaws.com
|
Service: ecs-tasks.amazonaws.com
|
||||||
Action: "sts:AssumeRole"
|
Action: 'sts:AssumeRole'
|
||||||
ManagedPolicyArns:
|
ManagedPolicyArns:
|
||||||
- "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceAutoscaleRole"
|
- 'arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceAutoscaleRole'
|
||||||
|
|
||||||
ContainerSecurityGroup:
|
ContainerSecurityGroup:
|
||||||
Type: AWS::EC2::SecurityGroup
|
Type: AWS::EC2::SecurityGroup
|
||||||
Properties:
|
Properties:
|
||||||
GroupDescription:
|
GroupDescription:
|
||||||
!Join ["", [!Ref "AWS::StackName", ContainerSecurityGroup]]
|
!Join ['', [!Ref 'AWS::StackName', ContainerSecurityGroup]]
|
||||||
VpcId: !Ref VPC
|
VpcId: !Ref VPC
|
||||||
SecurityGroupIngress:
|
SecurityGroupIngress:
|
||||||
- IpProtocol: tcp
|
- IpProtocol: tcp
|
||||||
@@ -187,7 +191,7 @@ Resources:
|
|||||||
Type: AWS::EC2::SecurityGroup
|
Type: AWS::EC2::SecurityGroup
|
||||||
Properties:
|
Properties:
|
||||||
GroupDescription:
|
GroupDescription:
|
||||||
!Join ["", [!Ref "AWS::StackName", LoadBalancerSecurityGroup]]
|
!Join ['', [!Ref 'AWS::StackName', LoadBalancerSecurityGroup]]
|
||||||
VpcId: !Ref VPC
|
VpcId: !Ref VPC
|
||||||
SecurityGroupIngress:
|
SecurityGroupIngress:
|
||||||
- IpProtocol: tcp
|
- IpProtocol: tcp
|
||||||
@@ -235,7 +239,7 @@ Resources:
|
|||||||
HealthCheckTimeoutSeconds: 10
|
HealthCheckTimeoutSeconds: 10
|
||||||
UnhealthyThresholdCount: 2
|
UnhealthyThresholdCount: 2
|
||||||
HealthyThresholdCount: 2
|
HealthyThresholdCount: 2
|
||||||
Name: !Join ["", [!Ref "AWS::StackName", Group]]
|
Name: !Join ['', [!Ref 'AWS::StackName', Group]]
|
||||||
Port: !Ref ContainerPort
|
Port: !Ref ContainerPort
|
||||||
Protocol: HTTP
|
Protocol: HTTP
|
||||||
TargetGroupAttributes:
|
TargetGroupAttributes:
|
||||||
@@ -262,7 +266,7 @@ Resources:
|
|||||||
LoadBalancerAttributes:
|
LoadBalancerAttributes:
|
||||||
- Key: idle_timeout.timeout_seconds
|
- Key: idle_timeout.timeout_seconds
|
||||||
Value: 1200
|
Value: 1200
|
||||||
Name: !Join ["", [!Ref "AWS::StackName", LB]]
|
Name: !Join ['', [!Ref 'AWS::StackName', LB]]
|
||||||
# "internal" is also an option
|
# "internal" is also an option
|
||||||
Scheme: internet-facing
|
Scheme: internet-facing
|
||||||
SecurityGroups:
|
SecurityGroups:
|
||||||
@@ -274,8 +278,8 @@ Resources:
|
|||||||
DNSRecord:
|
DNSRecord:
|
||||||
Type: AWS::Route53::RecordSet
|
Type: AWS::Route53::RecordSet
|
||||||
Properties:
|
Properties:
|
||||||
HostedZoneName: !Join ["", [!Ref HostedZoneName, .]]
|
HostedZoneName: !Join ['', [!Ref HostedZoneName, .]]
|
||||||
Name: !Join ["", [!Ref Subdomain, ., !Ref HostedZoneName, .]]
|
Name: !Join ['', [!Ref Subdomain, ., !Ref HostedZoneName, .]]
|
||||||
Type: A
|
Type: A
|
||||||
AliasTarget:
|
AliasTarget:
|
||||||
DNSName: !GetAtt LoadBalancer.DNSName
|
DNSName: !GetAtt LoadBalancer.DNSName
|
||||||
@@ -284,14 +288,14 @@ Resources:
|
|||||||
LogGroup:
|
LogGroup:
|
||||||
Type: AWS::Logs::LogGroup
|
Type: AWS::Logs::LogGroup
|
||||||
Properties:
|
Properties:
|
||||||
LogGroupName: !Join ["", [/ecs/, !Ref "AWS::StackName", TaskDefinition]]
|
LogGroupName: !Join ['', [/ecs/, !Ref 'AWS::StackName', TaskDefinition]]
|
||||||
|
|
||||||
AutoScalingTarget:
|
AutoScalingTarget:
|
||||||
Type: AWS::ApplicationAutoScaling::ScalableTarget
|
Type: AWS::ApplicationAutoScaling::ScalableTarget
|
||||||
Properties:
|
Properties:
|
||||||
MinCapacity: !Ref MinContainers
|
MinCapacity: !Ref MinContainers
|
||||||
MaxCapacity: !Ref MaxContainers
|
MaxCapacity: !Ref MaxContainers
|
||||||
ResourceId: !Join ["/", [service, !Ref Cluster, !GetAtt Service.Name]]
|
ResourceId: !Join ['/', [service, !Ref Cluster, !GetAtt Service.Name]]
|
||||||
ScalableDimension: ecs:service:DesiredCount
|
ScalableDimension: ecs:service:DesiredCount
|
||||||
ServiceNamespace: ecs
|
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."
|
# "The Amazon Resource Name (ARN) of an AWS Identity and Access Management (IAM) role that allows Application Auto Scaling to modify your scalable target."
|
||||||
@@ -299,7 +303,7 @@ Resources:
|
|||||||
AutoScalingPolicy:
|
AutoScalingPolicy:
|
||||||
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||||
Properties:
|
Properties:
|
||||||
PolicyName: !Join ["", [!Ref "AWS::StackName", AutoScalingPolicy]]
|
PolicyName: !Join ['', [!Ref 'AWS::StackName', AutoScalingPolicy]]
|
||||||
PolicyType: TargetTrackingScaling
|
PolicyType: TargetTrackingScaling
|
||||||
ScalingTargetId: !Ref AutoScalingTarget
|
ScalingTargetId: !Ref AutoScalingTarget
|
||||||
TargetTrackingScalingPolicyConfiguration:
|
TargetTrackingScalingPolicyConfiguration:
|
||||||
@@ -327,7 +331,7 @@ Resources:
|
|||||||
PolicyDocument:
|
PolicyDocument:
|
||||||
Version: 2012-10-17
|
Version: 2012-10-17
|
||||||
Statement:
|
Statement:
|
||||||
- Resource: "*"
|
- Resource: '*'
|
||||||
Effect: Allow
|
Effect: Allow
|
||||||
Action:
|
Action:
|
||||||
- logs:CreateLogGroup
|
- logs:CreateLogGroup
|
||||||
@@ -380,7 +384,7 @@ Resources:
|
|||||||
- s3:GetObject
|
- s3:GetObject
|
||||||
- s3:GetObjectVersion
|
- s3:GetObjectVersion
|
||||||
- s3:GetBucketVersioning
|
- s3:GetBucketVersioning
|
||||||
- Resource: "*"
|
- Resource: '*'
|
||||||
Effect: Allow
|
Effect: Allow
|
||||||
Action:
|
Action:
|
||||||
- ecs:List*
|
- ecs:List*
|
||||||
@@ -455,7 +459,7 @@ Resources:
|
|||||||
Type: AWS::CodePipeline::Pipeline
|
Type: AWS::CodePipeline::Pipeline
|
||||||
Properties:
|
Properties:
|
||||||
RoleArn: !GetAtt CodePipelineServiceRole.Arn
|
RoleArn: !GetAtt CodePipelineServiceRole.Arn
|
||||||
Name: !Join ["", [!Ref "AWS::StackName", Pipeline]]
|
Name: !Join ['', [!Ref 'AWS::StackName', Pipeline]]
|
||||||
ArtifactStore:
|
ArtifactStore:
|
||||||
Type: S3
|
Type: S3
|
||||||
Location: !Ref ArtifactBucket
|
Location: !Ref ArtifactBucket
|
||||||
@@ -511,7 +515,7 @@ Resources:
|
|||||||
Outputs:
|
Outputs:
|
||||||
Endpoint:
|
Endpoint:
|
||||||
Description: Endpoint
|
Description: Endpoint
|
||||||
Value: !Join ["", ["https://", !Ref DNSRecord]]
|
Value: !Join ['', ['https://', !Ref DNSRecord]]
|
||||||
Service:
|
Service:
|
||||||
Value: Service
|
Value: Service
|
||||||
PipelineUrl:
|
PipelineUrl:
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- COGNITO_POOL_ID=eu-west-1_3O4VfvPn7
|
- COGNITO_POOL_ID=eu-west-1_3O4VfvPn7
|
||||||
- DATABASE_URL=${DATABASE_URL}
|
- DATABASE_URL=${DATABASE_URL}
|
||||||
|
- INTERIOR_TOKEN=${INTERIOR_TOKEN}
|
||||||
|
- INTERIOR_URL=${INTERIOR_URL}
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ export class InteriorAPI extends BaseSQLDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getInteriorRoomNumber(roomNumberPart: string): number {
|
getInteriorRoomNumber(roomNumberPart: string): number {
|
||||||
return convertToPossibleType(roomNumberPart.slice(4));
|
return parseInt(roomNumberPart.slice(4), 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
decorateRow(row: any): Interior {
|
decorateRow(row: any): Interior {
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
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
|
||||||
|
* <code>
|
||||||
|
* const product = await (<ProductAPI>dataSources.productApi).getProduct(productId);
|
||||||
|
* await (<InteriorsLambdaAPI>dataSources.interiorsLambdaAPI).generateNewInteriors(product);
|
||||||
|
* </code>
|
||||||
|
*/
|
||||||
|
async generateNewInteriors(product: Product): Promise<any> {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -66,7 +66,7 @@ export class OrderAPI extends BaseSQLDataSource {
|
|||||||
.count()
|
.count()
|
||||||
.first()
|
.first()
|
||||||
.cache(MINUTE * 60);
|
.cache(MINUTE * 60);
|
||||||
return convertToPossibleType(res['count']); // Optimize later to return Promise
|
return res['count'] as number; // Optimize later to return Promise
|
||||||
}
|
}
|
||||||
|
|
||||||
async getOrders(input: Maybe<GeneralInput>): Promise<Array<Order>> {
|
async getOrders(input: Maybe<GeneralInput>): Promise<Array<Order>> {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import {
|
|||||||
ProductSizeTypes,
|
ProductSizeTypes,
|
||||||
} from '../types/product-types';
|
} from '../types/product-types';
|
||||||
import { Maybe } from '../types/types';
|
import { Maybe } from '../types/types';
|
||||||
import { convertToPossibleType } from './utils';
|
import { convertToPossibleType, nullOrNumber } from './utils';
|
||||||
|
|
||||||
const MINUTE = 60;
|
const MINUTE = 60;
|
||||||
|
|
||||||
@@ -75,11 +75,40 @@ export class ProductAPI extends BaseSQLDataSource {
|
|||||||
if (!row.fields) {
|
if (!row.fields) {
|
||||||
return null; // 53460 for example
|
return null; // 53460 for example
|
||||||
}
|
}
|
||||||
|
// Convert to camelCase first
|
||||||
const fields = Object.keys(row.fields).reduce((mem, key) => {
|
const fields = Object.keys(row.fields).reduce((mem, key) => {
|
||||||
mem[camelcase(key)] = convertToPossibleType(row.fields[key]);
|
mem[camelcase(key)] = row.fields[key];
|
||||||
return mem;
|
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 <ProductFields>fields;
|
return <ProductFields>fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,8 +133,6 @@ export class ProductAPI extends BaseSQLDataSource {
|
|||||||
row.fields = this.getProductFields(row);
|
row.fields = this.getProductFields(row);
|
||||||
row.designerId = row.designerid;
|
row.designerId = row.designerid;
|
||||||
row.orientation = this.getOrientation(row.fields);
|
row.orientation = this.getOrientation(row.fields);
|
||||||
row.copyright = row.copyright ?? '';
|
|
||||||
row.batch = row.batch ?? '';
|
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +141,7 @@ export class ProductAPI extends BaseSQLDataSource {
|
|||||||
const res = await this.cachedRaw(query)
|
const res = await this.cachedRaw(query)
|
||||||
.cache(MINUTE * 60)
|
.cache(MINUTE * 60)
|
||||||
.then((data) => data.rows);
|
.then((data) => data.rows);
|
||||||
return convertToPossibleType(res[0]['count']); // Optimize later to return Promise
|
return res[0]['count'] as number; // Optimize later to return Promise
|
||||||
}
|
}
|
||||||
|
|
||||||
async getProducts(input: ProductsFilterInput): Promise<Array<Product>> {
|
async getProducts(input: ProductsFilterInput): Promise<Array<Product>> {
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
function isNumeric(n: any) {
|
type InputType = string | undefined | null;
|
||||||
return !isNaN(n);
|
|
||||||
|
function isNumeric(n: InputType) {
|
||||||
|
return !isNaN(parseFloat(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
function isBoolean(n: any) {
|
function isBoolean(n: InputType | boolean) {
|
||||||
if (typeof n === 'boolean') {
|
if (typeof n === 'boolean') {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -13,9 +15,13 @@ function isBoolean(n: any) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function convertToPossibleType(n: any) {
|
export function convertToPossibleType(n: InputType) {
|
||||||
if ('' === n) return '';
|
if ('' === n) return '';
|
||||||
if (isBoolean(n)) return Boolean(n);
|
if (isBoolean(n)) return Boolean(n);
|
||||||
if (isNumeric(n)) return Number(n);
|
if (isNumeric(n)) return Number(n);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function nullOrNumber(n: InputType) {
|
||||||
|
return n === null || '' === n ? null : Number(n);
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import { InteriorAPI } from './datasources/interior-api';
|
|||||||
|
|
||||||
import { verifyToken } from './cognito/cognito-client';
|
import { verifyToken } from './cognito/cognito-client';
|
||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
|
import { InteriorsLambdaAPI } from './datasources/interiors-lambda-api';
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const typeDefs = readFileSync(
|
const typeDefs = readFileSync(
|
||||||
path.join(__dirname, './schema.graphql'),
|
path.join(__dirname, './schema.graphql'),
|
||||||
@@ -29,6 +30,7 @@ const knexConfig = knexStringcase(dbConfig);
|
|||||||
const categoryApi = new CategoryAPI(knexConfig);
|
const categoryApi = new CategoryAPI(knexConfig);
|
||||||
const designerApi = new DesignerAPI(knexConfig);
|
const designerApi = new DesignerAPI(knexConfig);
|
||||||
const imageServerApi = new ImageServerApi();
|
const imageServerApi = new ImageServerApi();
|
||||||
|
const interiorsLambdaApi = new InteriorsLambdaAPI();
|
||||||
const interiorApi = new InteriorAPI(knexConfig, imageServerApi);
|
const interiorApi = new InteriorAPI(knexConfig, imageServerApi);
|
||||||
const keywordApi = new KeywordAPI(knexConfig);
|
const keywordApi = new KeywordAPI(knexConfig);
|
||||||
const marketLocaleApi = new MarketLocaleAPI(knexConfig);
|
const marketLocaleApi = new MarketLocaleAPI(knexConfig);
|
||||||
@@ -39,6 +41,7 @@ const dataSources = () => ({
|
|||||||
categoryApi,
|
categoryApi,
|
||||||
designerApi,
|
designerApi,
|
||||||
interiorApi,
|
interiorApi,
|
||||||
|
interiorsLambdaApi,
|
||||||
imageServerApi,
|
imageServerApi,
|
||||||
keywordApi,
|
keywordApi,
|
||||||
marketLocaleApi,
|
marketLocaleApi,
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ export const keywordsMutationTypeDefs = {
|
|||||||
name,
|
name,
|
||||||
type,
|
type,
|
||||||
);
|
);
|
||||||
console.log(id);
|
|
||||||
return (<KeywordAPI>dataSources.keywordApi).getKeywordById(id);
|
return (<KeywordAPI>dataSources.keywordApi).getKeywordById(id);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { KeywordAPI } from '../datasources/keyword-api';
|
|||||||
import { Keyword } from '../types/keyword-types';
|
import { Keyword } from '../types/keyword-types';
|
||||||
import { MarketLocaleAPI } from '../datasources/market-locale-api';
|
import { MarketLocaleAPI } from '../datasources/market-locale-api';
|
||||||
import { InteriorAPI } from '../datasources/interior-api';
|
import { InteriorAPI } from '../datasources/interior-api';
|
||||||
|
import { InteriorsLambdaAPI } from '../datasources/interiors-lambda-api';
|
||||||
|
|
||||||
const ProductBlacklist = {
|
const ProductBlacklist = {
|
||||||
async market(parent, _args, { dataSources }) {
|
async market(parent, _args, { dataSources }) {
|
||||||
@@ -111,7 +112,13 @@ export const productMutationTypeDefs = {
|
|||||||
productId,
|
productId,
|
||||||
groupIds,
|
groupIds,
|
||||||
);
|
);
|
||||||
return (<ProductAPI>dataSources.productApi).getProduct(productId);
|
const product = await (<ProductAPI>dataSources.productApi).getProduct(
|
||||||
|
productId,
|
||||||
|
);
|
||||||
|
await (<InteriorsLambdaAPI>(
|
||||||
|
dataSources.interiorsLambdaApi
|
||||||
|
)).generateNewInteriors(product);
|
||||||
|
return product;
|
||||||
},
|
},
|
||||||
async productKeywords(_, { productId, keywordIds }, { dataSources }) {
|
async productKeywords(_, { productId, keywordIds }, { dataSources }) {
|
||||||
await (<KeywordAPI>dataSources.keywordApi).setProductKeywords(
|
await (<KeywordAPI>dataSources.keywordApi).setProductKeywords(
|
||||||
|
|||||||
+1
-1
@@ -267,7 +267,7 @@ type ProductFields {
|
|||||||
focusYpoint: Float
|
focusYpoint: Float
|
||||||
focusXpoint2: Float
|
focusXpoint2: Float
|
||||||
focusYpoint2: Float
|
focusYpoint2: Float
|
||||||
batch: String!
|
batch: String
|
||||||
imageResolution: Int
|
imageResolution: Int
|
||||||
printFileWidth: Int
|
printFileWidth: Int
|
||||||
printFileHeight: Int
|
printFileHeight: Int
|
||||||
|
|||||||
Reference in New Issue
Block a user