This commit is contained in:
Fre Timmerman 2021-02-02 11:34:34 +01:00
parent debca3352b
commit 40d325a318
8 changed files with 183 additions and 26 deletions

View File

@ -16,9 +16,10 @@
"graphql": "^15.5.0", "graphql": "^15.5.0",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
"type-graphql": "^1.1.1", "type-graphql": "^1.1.1",
"uuid": "^3.3.2" "uuid": "^3.3.2",
"yup": "^0.32.8"
}, },
"devDependencies": { "devDependencies": {
"tsc-watch": "^4.2.9" "tsc-watch": "^4.2.9"
} }
} }

View File

@ -3,14 +3,29 @@
# !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! # !!! DO NOT MODIFY THIS FILE BY YOURSELF !!!
# ----------------------------------------------- # -----------------------------------------------
type Mutation {
"""Create a new store"""
createStore(input: StoreInput!): Store!
}
type Query { type Query {
"""Get all the stores """ """Get all the stores"""
stores: [Store!]! stores: [Store!]!
} }
type Store { type Store {
id: ID! city: String!
id: String!
"""The name of the store"""
name: String! name: String!
number: Int!
postalCode: String!
street: String!
}
input StoreInput {
city: String!
name: String!
number: Int!
postalCode: String!
street: String!
} }

View File

@ -1,18 +1,33 @@
import * as uuid from 'uuid'; import uuid from 'uuid';
const stores = [ const stores = [
{ {
city: 'Aalst',
id: 'cc406ed9-fc02-4185-b073-8c12b61b5c79', id: 'cc406ed9-fc02-4185-b073-8c12b61b5c79',
name: 'Den Olijfboom', name: 'Den Olijfboom',
number: 38,
postalCode: '9300',
street: 'Molenstraat',
}, },
{ {
city: 'Aalst',
id: '5f2919aa-333a-4745-8166-3002ab30de0e', id: '5f2919aa-333a-4745-8166-3002ab30de0e',
name: 'Pizza Talia' name: 'Pizza Talia',
number: 147,
postalCode: '9300',
street: 'Sint Jobstraat',
} }
]; ];
export function createStore({ name }) { export function createStore({ city, name, number, postalCode, street }) {
const newStore = { id: uuid(), name }; const newStore = {
city,
id: uuid(),
name,
number,
postalCode,
street,
};
stores.push(newStore); stores.push(newStore);
return newStore; return newStore;
} }

View File

@ -7,10 +7,24 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
var __metadata = (this && this.__metadata) || function (k, v) { var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
}; };
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
import "reflect-metadata"; import "reflect-metadata";
import { Resolver, Query } from "type-graphql"; import { Resolver, Query, Mutation, Arg } from "type-graphql";
import { Store } from "./typeDefs.js"; import { Store, StoreInput } from "./typeDefs.js";
import { getStores } from "./data.js"; import { createStore, getStores } from "./data.js";
import * as yup from 'yup';
import { UserInputError } from "apollo-server";
// define input validations
const createStoreSchema = yup.object()
.shape({
city: yup.string().max(255).required(),
name: yup.string().max(255).required(),
number: yup.number().required().positive().integer(),
postalCode: yup.string().required().max(10),
street: yup.string().required().max(255),
});
let StoreResolver = class StoreResolver { let StoreResolver = class StoreResolver {
constructor() { constructor() {
this.storeCollection = getStores(); this.storeCollection = getStores();
@ -18,13 +32,32 @@ let StoreResolver = class StoreResolver {
async stores() { async stores() {
return await this.storeCollection; return await this.storeCollection;
} }
async createStore(input) {
// check validity
return await createStoreSchema
.validate(input)
.then(validData => {
// put in db with data.js and return the value to grapqhl
return createStore(validData);
})
.catch(err => {
return new UserInputError('Invalid input', { validationErrors: err.errors });
});
}
}; };
__decorate([ __decorate([
Query(returns => [Store], { description: "Get all the stores " }), Query(returns => [Store], { description: "Get all the stores" }),
__metadata("design:type", Function), __metadata("design:type", Function),
__metadata("design:paramtypes", []), __metadata("design:paramtypes", []),
__metadata("design:returntype", Promise) __metadata("design:returntype", Promise)
], StoreResolver.prototype, "stores", null); ], StoreResolver.prototype, "stores", null);
__decorate([
Mutation(() => Store, { description: "Create a new store" }),
__param(0, Arg("input")),
__metadata("design:type", Function),
__metadata("design:paramtypes", [StoreInput]),
__metadata("design:returntype", Promise)
], StoreResolver.prototype, "createStore", null);
StoreResolver = __decorate([ StoreResolver = __decorate([
Resolver() Resolver()
], StoreResolver); ], StoreResolver);

View File

@ -1,14 +1,43 @@
import "reflect-metadata"; import "reflect-metadata";
import { Resolver, Query } from "type-graphql"; import { Resolver, Query, Mutation, Arg } from "type-graphql";
import { Store } from "./typeDefs.js"; import { Store, StoreInput } from "./typeDefs.js";
import { getStores } from "./data.js"; import { createStore, getStores } from "./data.js";
import * as yup from 'yup';
import { UserInputError } from "apollo-server";
// define input validations
const createStoreSchema = yup.object()
.shape({
city: yup.string().max(255).required(),
name: yup.string().max(255).required(),
number: yup.number().required().positive().integer(),
postalCode: yup.string().required().max(10),
street: yup.string().required().max(255),
});
@Resolver() @Resolver()
export class StoreResolver { export class StoreResolver {
private storeCollection: Store[] = getStores(); private storeCollection: Store[] = getStores();
@Query(returns => [Store], { description: "Get all the stores " }) @Query(returns => [Store], { description: "Get all the stores" })
async stores(): Promise<Store[]> { async stores(): Promise<Store[]> {
return await this.storeCollection; return await this.storeCollection;
} }
@Mutation(() => Store, { description: "Create a new store" })
async createStore(@Arg("input") input: StoreInput) {
// check validity
return await createStoreSchema
.validate(input)
.then(validData => {
// put in db with data.js and return the value to grapqhl
return createStore(validData);
})
.catch(err => {
return new UserInputError('Invalid input', { validationErrors: err.errors });
});
}
} }

View File

@ -10,18 +10,60 @@ var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
}; };
import "reflect-metadata"; import "reflect-metadata";
import { ObjectType, Field, ID } from "type-graphql"; import { ObjectType, Field, InputType, Int } from "type-graphql";
let Store = class Store { let Store = class Store {
}; };
__decorate([ __decorate([
Field(() => ID), Field(),
__metadata("design:type", String) __metadata("design:type", String)
], Store.prototype, "id", void 0); ], Store.prototype, "id", void 0);
__decorate([ __decorate([
Field(() => String, { description: "The name of the store" }), Field(),
__metadata("design:type", String) __metadata("design:type", String)
], Store.prototype, "name", void 0); ], Store.prototype, "name", void 0);
__decorate([
Field(),
__metadata("design:type", String)
], Store.prototype, "city", void 0);
__decorate([
Field(type => Int),
__metadata("design:type", Number)
], Store.prototype, "number", void 0);
__decorate([
Field(),
__metadata("design:type", String)
], Store.prototype, "postalCode", void 0);
__decorate([
Field(),
__metadata("design:type", String)
], Store.prototype, "street", void 0);
Store = __decorate([ Store = __decorate([
ObjectType() ObjectType()
], Store); ], Store);
export { Store }; export { Store };
let StoreInput = class StoreInput {
};
__decorate([
Field(),
__metadata("design:type", String)
], StoreInput.prototype, "name", void 0);
__decorate([
Field(),
__metadata("design:type", String)
], StoreInput.prototype, "city", void 0);
__decorate([
Field(type => Int),
__metadata("design:type", Number)
], StoreInput.prototype, "number", void 0);
__decorate([
Field(),
__metadata("design:type", String)
], StoreInput.prototype, "postalCode", void 0);
__decorate([
Field(),
__metadata("design:type", String)
], StoreInput.prototype, "street", void 0);
StoreInput = __decorate([
InputType()
], StoreInput);
export { StoreInput };

View File

@ -2,14 +2,35 @@
// which ways the data can be fetched from the GraphQL server. // which ways the data can be fetched from the GraphQL server.
import "reflect-metadata"; import "reflect-metadata";
import { ObjectType, Field, ID } from "type-graphql"; import { ObjectType, Field, ID, InputType, Int } from "type-graphql";
import { number } from "yup/lib/locale";
@ObjectType() @ObjectType()
export class Store { export class Store {
@Field(() => ID) @Field()
id: string; id: string;
@Field()
@Field(() => String, { description: "The name of the store" })
name: string; name: string;
@Field()
city: string;
@Field(type => Int)
number: number;
@Field()
postalCode: string
@Field()
street: string
}
@InputType()
export class StoreInput {
@Field()
name: string;
@Field()
city: string;
@Field(type => Int)
number: number;
@Field()
postalCode: string
@Field()
street: string
} }

View File

@ -8,6 +8,7 @@
], ],
"moduleResolution": "node", "moduleResolution": "node",
"experimentalDecorators": true, "experimentalDecorators": true,
"emitDecoratorMetadata": true "emitDecoratorMetadata": true,
"allowSyntheticDefaultImports": true
} }
} }