Browse Source

first commit

dev
Christian Ziermann 4 years ago
commit
77b3042c7f
16 changed files with 9354 additions and 0 deletions
  1. +2
    -0
      .gitignore
  2. +16
    -0
      .vscode/launch.json
  3. +41
    -0
      README.md
  4. +12
    -0
      codegen.yml
  5. +1262
    -0
      graphql.schema.json
  6. +6
    -0
      nodemon.json
  7. +7588
    -0
      package-lock.json
  8. +34
    -0
      package.json
  9. +29
    -0
      src/data/pizza-list.ts
  10. +27
    -0
      src/data/topping-list.ts
  11. +202
    -0
      src/generated/graphql.ts
  12. +58
    -0
      src/index.ts
  13. +17
    -0
      src/resolver/pizza-resolver.ts
  14. +16
    -0
      src/resolver/topping-resolver.ts
  15. +24
    -0
      src/schema/pizza.ts
  16. +20
    -0
      tsconfig.json

+ 2
- 0
.gitignore View File

@@ -0,0 +1,2 @@
/build/
/node_modules/

+ 16
- 0
.vscode/launch.json View File

@@ -0,0 +1,16 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/src/index.ts",
"preLaunchTask": "tsc: build - tsconfig.json",
"outFiles": ["${workspaceFolder}/build/**/*.js"]
}
]
}

+ 41
- 0
README.md View File

@@ -0,0 +1,41 @@
# Prepation

``npm init``

See More <https://graphql-code-generator.com/docs/getting-started/installation>

``npm add --save graphql``
or
``yarn add graphql``


``npm add --save-dev @graphql-codegen/cli``
or
``yarn add -D @graphql-codegen/cli``


``npx graphql-codegen init``


``npm add --save-dev @graphql-codegen/typescript``
or
``yarn add -D @graphql-codegen/typescript``

# Server

``npm add apollo-server``

``npm install @types/node --save-dev``

```
npx tsc --init --rootDir src --outDir build \
--esModuleInterop --resolveJsonModule --lib es6 \
--module commonjs --allowJs true --noImplicitAny true
```

``npm install --save-dev ts-node nodemon rimraf``


# UI

* init new Angular project ``ng new graphql-demo``

+ 12
- 0
codegen.yml View File

@@ -0,0 +1,12 @@
overwrite: true
schema: ./src/schema/*.ts
generates:
src/generated/graphql.ts:
plugins:
- typescript
- typescript-resolvers
- typescript-graphql-request
- typescript-operations
./graphql.schema.json:
plugins:
- "introspection"

+ 1262
- 0
graphql.schema.json
File diff suppressed because it is too large
View File


+ 6
- 0
nodemon.json View File

@@ -0,0 +1,6 @@
{
"watch": ["src"],
"ext": ".ts,.js",
"ignore": [],
"exec": "ts-node ./src/index.ts"
}

+ 7588
- 0
package-lock.json
File diff suppressed because it is too large
View File


+ 34
- 0
package.json View File

@@ -0,0 +1,34 @@
{
"name": "graphql-pizza-demo",
"version": "1.0.0",
"description": "",
"main": "build/index.js",
"dependencies": {
"apollo-server": "^2.15.1",
"graphql": "^15.3.0",
"typescript": "^3.9.6"
},
"devDependencies": {
"@graphql-codegen/cli": "1.16.3",
"@graphql-codegen/introspection": "1.16.3",
"@graphql-codegen/typescript": "^1.16.3",
"@graphql-codegen/typescript-graphql-request": "^1.16.3",
"@graphql-codegen/typescript-operations": "^1.16.3",
"@graphql-codegen/typescript-resolvers": "1.16.3",
"@types/node": "^14.0.20",
"nodemon": "^2.0.4",
"rimraf": "^3.0.2",
"ts-node": "^8.10.2"
},
"scripts": {
"prebuild": "npm run generate",
"prestart": "npm run generate",
"test": "echo \"Error: no test specified\" && exit 1",
"generate": "graphql-codegen --config codegen.yml",
"start": "nodemon",
"start:live": "npm run build && node build/index.js",
"build": "rimraf ./build && tsc"
},
"author": "",
"license": "ISC"
}

+ 29
- 0
src/data/pizza-list.ts View File

@@ -0,0 +1,29 @@
import { Pizza } from "../generated/graphql";
import { ToppingList } from "./topping-list";
import { ToppingResolver } from "../resolver/topping-resolver";

export const PizzaList: Pizza[] = [
{
id: "0",
name: "Tonno",
toppings: [
ToppingResolver.getByName("Tunna"),
ToppingResolver.getByName("Onion")
]
},
{
id: "1",
name: "Salami",
toppings: [
ToppingResolver.getByName("Salami"),
]
},
{
id: "2",
name: "420",
toppings: [
ToppingResolver.getByName("Pineapple"),
]
}
]


+ 27
- 0
src/data/topping-list.ts View File

@@ -0,0 +1,27 @@
import { Pizza, Topping } from "../generated/graphql";

export const ToppingList: Topping[] = [
{
id: "1",
name: "Tunna",
},
{
id: "2",
name: "Onion",
},
{
id: "3",
name: "Pineapple",
},
{
id: "4",
name: "Salami",
},
{
id: "5",
name: "fish sticks",
}

]


+ 202
- 0
src/generated/graphql.ts View File

@@ -0,0 +1,202 @@
import { GraphQLResolveInfo } from 'graphql';
import { GraphQLClient } from 'graphql-request';
import { print } from 'graphql';
import gql from 'graphql-tag';
export type Maybe<T> = T | null;
export type Exact<T extends { [key: string]: any }> = { [K in keyof T]: T[K] };
export type RequireFields<T, K extends keyof T> = { [X in Exclude<keyof T, K>]?: T[X] } & { [P in K]-?: NonNullable<T[P]> };
/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
ID: string;
String: string;
Boolean: boolean;
Int: number;
Float: number;
};

export type Pizza = {
__typename?: 'Pizza';
id: Scalars['ID'];
name: Scalars['String'];
toppings: Array<Topping>;
};

export type Topping = {
__typename?: 'Topping';
id: Scalars['ID'];
name: Scalars['String'];
};

export type Query = {
__typename?: 'Query';
getPizzaById: Pizza;
getToppingById: Topping;
getPizzaByName: Pizza;
getToppingByName: Topping;
listPizza: Array<Maybe<Pizza>>;
listTopping: Array<Maybe<Topping>>;
};


export type QueryGetPizzaByIdArgs = {
pizzaId: Scalars['ID'];
};


export type QueryGetToppingByIdArgs = {
toppingId: Scalars['ID'];
};


export type QueryGetPizzaByNameArgs = {
pizzaName: Scalars['ID'];
};


export type QueryGetToppingByNameArgs = {
toppingName: Scalars['ID'];
};



export type ResolverTypeWrapper<T> = Promise<T> | T;


export type LegacyStitchingResolver<TResult, TParent, TContext, TArgs> = {
fragment: string;
resolve: ResolverFn<TResult, TParent, TContext, TArgs>;
};

export type NewStitchingResolver<TResult, TParent, TContext, TArgs> = {
selectionSet: string;
resolve: ResolverFn<TResult, TParent, TContext, TArgs>;
};
export type StitchingResolver<TResult, TParent, TContext, TArgs> = LegacyStitchingResolver<TResult, TParent, TContext, TArgs> | NewStitchingResolver<TResult, TParent, TContext, TArgs>;
export type Resolver<TResult, TParent = {}, TContext = {}, TArgs = {}> =
| ResolverFn<TResult, TParent, TContext, TArgs>
| StitchingResolver<TResult, TParent, TContext, TArgs>;

export type ResolverFn<TResult, TParent, TContext, TArgs> = (
parent: TParent,
args: TArgs,
context: TContext,
info: GraphQLResolveInfo
) => Promise<TResult> | TResult;

export type SubscriptionSubscribeFn<TResult, TParent, TContext, TArgs> = (
parent: TParent,
args: TArgs,
context: TContext,
info: GraphQLResolveInfo
) => AsyncIterator<TResult> | Promise<AsyncIterator<TResult>>;

export type SubscriptionResolveFn<TResult, TParent, TContext, TArgs> = (
parent: TParent,
args: TArgs,
context: TContext,
info: GraphQLResolveInfo
) => TResult | Promise<TResult>;

export interface SubscriptionSubscriberObject<TResult, TKey extends string, TParent, TContext, TArgs> {
subscribe: SubscriptionSubscribeFn<{ [key in TKey]: TResult }, TParent, TContext, TArgs>;
resolve?: SubscriptionResolveFn<TResult, { [key in TKey]: TResult }, TContext, TArgs>;
}

export interface SubscriptionResolverObject<TResult, TParent, TContext, TArgs> {
subscribe: SubscriptionSubscribeFn<any, TParent, TContext, TArgs>;
resolve: SubscriptionResolveFn<TResult, any, TContext, TArgs>;
}

export type SubscriptionObject<TResult, TKey extends string, TParent, TContext, TArgs> =
| SubscriptionSubscriberObject<TResult, TKey, TParent, TContext, TArgs>
| SubscriptionResolverObject<TResult, TParent, TContext, TArgs>;

export type SubscriptionResolver<TResult, TKey extends string, TParent = {}, TContext = {}, TArgs = {}> =
| ((...args: any[]) => SubscriptionObject<TResult, TKey, TParent, TContext, TArgs>)
| SubscriptionObject<TResult, TKey, TParent, TContext, TArgs>;

export type TypeResolveFn<TTypes, TParent = {}, TContext = {}> = (
parent: TParent,
context: TContext,
info: GraphQLResolveInfo
) => Maybe<TTypes> | Promise<Maybe<TTypes>>;

export type IsTypeOfResolverFn<T = {}> = (obj: T, info: GraphQLResolveInfo) => boolean | Promise<boolean>;

export type NextResolverFn<T> = () => Promise<T>;

export type DirectiveResolverFn<TResult = {}, TParent = {}, TContext = {}, TArgs = {}> = (
next: NextResolverFn<TResult>,
parent: TParent,
args: TArgs,
context: TContext,
info: GraphQLResolveInfo
) => TResult | Promise<TResult>;

/** Mapping between all available schema types and the resolvers types */
export type ResolversTypes = {
Pizza: ResolverTypeWrapper<Pizza>;
ID: ResolverTypeWrapper<Scalars['ID']>;
String: ResolverTypeWrapper<Scalars['String']>;
Topping: ResolverTypeWrapper<Topping>;
Query: ResolverTypeWrapper<{}>;
Boolean: ResolverTypeWrapper<Scalars['Boolean']>;
};

/** Mapping between all available schema types and the resolvers parents */
export type ResolversParentTypes = {
Pizza: Pizza;
ID: Scalars['ID'];
String: Scalars['String'];
Topping: Topping;
Query: {};
Boolean: Scalars['Boolean'];
};

export type PizzaResolvers<ContextType = any, ParentType extends ResolversParentTypes['Pizza'] = ResolversParentTypes['Pizza']> = {
id?: Resolver<ResolversTypes['ID'], ParentType, ContextType>;
name?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
toppings?: Resolver<Array<ResolversTypes['Topping']>, ParentType, ContextType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType>;
};

export type ToppingResolvers<ContextType = any, ParentType extends ResolversParentTypes['Topping'] = ResolversParentTypes['Topping']> = {
id?: Resolver<ResolversTypes['ID'], ParentType, ContextType>;
name?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType>;
};

export type QueryResolvers<ContextType = any, ParentType extends ResolversParentTypes['Query'] = ResolversParentTypes['Query']> = {
getPizzaById?: Resolver<ResolversTypes['Pizza'], ParentType, ContextType, RequireFields<QueryGetPizzaByIdArgs, 'pizzaId'>>;
getToppingById?: Resolver<ResolversTypes['Topping'], ParentType, ContextType, RequireFields<QueryGetToppingByIdArgs, 'toppingId'>>;
getPizzaByName?: Resolver<ResolversTypes['Pizza'], ParentType, ContextType, RequireFields<QueryGetPizzaByNameArgs, 'pizzaName'>>;
getToppingByName?: Resolver<ResolversTypes['Topping'], ParentType, ContextType, RequireFields<QueryGetToppingByNameArgs, 'toppingName'>>;
listPizza?: Resolver<Array<Maybe<ResolversTypes['Pizza']>>, ParentType, ContextType>;
listTopping?: Resolver<Array<Maybe<ResolversTypes['Topping']>>, ParentType, ContextType>;
};

export type Resolvers<ContextType = any> = {
Pizza?: PizzaResolvers<ContextType>;
Topping?: ToppingResolvers<ContextType>;
Query?: QueryResolvers<ContextType>;
};


/**
* @deprecated
* Use "Resolvers" root object instead. If you wish to get "IResolvers", add "typesPrefix: I" to your config.
*/
export type IResolvers<ContextType = any> = Resolvers<ContextType>;



export type SdkFunctionWrapper = <T>(action: () => Promise<T>) => Promise<T>;


const defaultWrapper: SdkFunctionWrapper = sdkFunction => sdkFunction();
export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper = defaultWrapper) {
return {

};
}
export type Sdk = ReturnType<typeof getSdk>;

+ 58
- 0
src/index.ts View File

@@ -0,0 +1,58 @@
import { ApolloServer } from "apollo-server";
import { Resolvers } from "./generated/graphql";
import { pizzaSchema } from "./schema/pizza";
import { PizzaResolver } from "./resolver/pizza-resolver";
import { ToppingResolver } from "./resolver/topping-resolver";



const resolvers: Resolvers = {
Topping: {
id: (root, args, context) => {
return root.id
},
name: (root, args, context) => {
return root.name
},
},
Pizza: {
id: (root, args, context) => {
return root.id
},
name: (root, args, context) => {
return root.name
},
toppings: (root, args, context) => {
return root.toppings
},
},
Query: {
getPizzaById: (root, args, context) => {
return PizzaResolver.getById(args.pizzaId);
},
getPizzaByName: (root, args, context) => {
return PizzaResolver.getByName(args.pizzaName);
},
listPizza: (root, args, context) => {
return PizzaResolver.list();
},
getToppingById: (root, args, context) => {
return ToppingResolver.getById(args.toppingId);
},
getToppingByName: (root, args, context) => {
return ToppingResolver.getByName(args.toppingName);
},
listTopping: (root, args, context) => {
return ToppingResolver.list();
},
}
}

const server = new ApolloServer({
typeDefs: pizzaSchema,
resolvers: resolvers as any
});

server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`)
});

+ 17
- 0
src/resolver/pizza-resolver.ts View File

@@ -0,0 +1,17 @@
import { Topping, Pizza, } from "../generated/graphql";
import { PizzaList } from "../data/pizza-list";
export class PizzaResolver {

static getById = (id: string): Pizza => {
return PizzaList.filter(pizza => pizza.id === id)[0];
};

static list = (): Pizza[] => {
return PizzaList;
};

static getByName = (name: string): Pizza => {
return PizzaList.filter(pizza => pizza.name === name)[0];
};

}

+ 16
- 0
src/resolver/topping-resolver.ts View File

@@ -0,0 +1,16 @@
import { Topping, } from "../generated/graphql";
import { ToppingList } from "../data/topping-list";
export class ToppingResolver {
static getById = (id: string): Topping => {
return ToppingList.filter(topping => topping.id === id)[0];
};

static getByName = (name: string): Topping => {
return ToppingList.filter(topping => topping.name === name)[0];
};

static list = (): Topping[] => {
return ToppingList;
};

}

+ 24
- 0
src/schema/pizza.ts View File

@@ -0,0 +1,24 @@

import gql from "graphql-tag";

export const pizzaSchema = gql`
type Pizza {
id: ID!
name: String!
toppings: [Topping!]!
}

type Topping {
id: ID!
name: String!
}

type Query {
getPizzaById(pizzaId: ID!): Pizza!
getToppingById(toppingId: ID!): Topping!
getPizzaByName(pizzaName: ID!): Pizza!
getToppingByName(toppingName: ID!): Topping!
listPizza: [Pizza]!
listTopping: [Topping]!
}
`;

+ 20
- 0
tsconfig.json View File

@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */,
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
"lib": [
"es6"
] /* Specify library files to be included in the compilation. */,
"allowJs": true /* Allow javascript files to be compiled. */,
"outDir": "build" /* Redirect output structure to the directory. */,
"rootDir": "src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
"strict": true /* Enable all strict type-checking options. */,
"skipLibCheck": true,
"noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
"resolveJsonModule": true /* Include modules imported with '.json' extension */,
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */,
"sourceMap": true,
}
}

Loading…
Cancel
Save