Skip to content

Commit

Permalink
push release
Browse files Browse the repository at this point in the history
  • Loading branch information
PichotM committed Feb 3, 2020
0 parents commit e260937
Show file tree
Hide file tree
Showing 10 changed files with 285 additions and 0 deletions.
31 changes: 31 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Logs
logs
*.log
npm-debug.log*

# Dependencies
node_modules/

# Coverage
coverage

# Transpiled files
build/

# VS Code
.vscode
!.vscode/tasks.js

# JetBrains IDEs
.idea/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Misc
.DS_Store
dist/
package-lock.json
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# GraphQL Wrapper for FiveM
This resource aims to facilitate the usage of GraphQL on your fivem server.
It should work with Lua/C#/JS environnements.

## Installation
You need webpack and yarn resources to get this script working and MongoDB.

- Download the latest release
- Extract the resource in your resources/ folder
- Go to the resource folder and start editing `db.ts` to enter your database information.

## Configuration

You need to create models, schemas, queries, mutations etc.. You can find a simple example in `src/config/vehicles.ts`.

https://graphql.org/learn/queries/

## Examples

This wrapper is relatively simple, here at the main functions.

```js
function registerGraphSchema(name: string, config: GraphQLSchemaConfig);
```
It regiters a "graph schema" and this schema can be later retrived with its name.

/!\ You cannot use this function outside of the JS environnement.

```js
query(schema: string, params: string | Source, callback?: Function);
```

This is what you can use to execute queries/mutations with GraphQL.
Example
```js
const s = `mutation {
addVehicle(name: "Blista", plate: "ABCDEFGH", model: "blista") {
name,
model
}
}`
query('Vehicle', s, (result) => console.log(result))
```

8 changes: 8 additions & 0 deletions __resource.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
server_only 'yes'

dependency 'yarn'
dependency 'webpack'

webpack_config 'server.config.js'

server_script 'dist/*.js'
27 changes: 27 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "graphql-fivem",
"version": "0.0.1",
"main": "main.js",
"description": "GraphQL for FiveM.",
"scripts": {
"build": "webpack --mode production --config server.config.js",
"watch": "webpack --mode development --watch true --config server.config.js"
},
"author": "pichotm",
"license": "MIT",
"dependencies": {
"@citizenfx/server": "^1.0.1910-1",
"@types/node": "^12.12.22",
"graphql": "^14.6.0",
"mongoose": "^5.8.11"
},
"devDependencies": {
"bufferutil": "^4.0.1",
"encoding": "^0.1.12",
"ts-loader": "^6.0.2",
"typescript": "^3.7.4",
"utf-8-validate": "^5.0.2",
"webpack": "^4.41.5",
"webpack-cli": "^3.3.2"
}
}
33 changes: 33 additions & 0 deletions server.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const webpack = require("webpack");
const path = require("path")
const fivemPath = "./"

module.exports = {
entry: "./src/main.ts",
module: {
rules: [
{
test: /\.tsx?$/,
use: "ts-loader",
exclude: /node_modules/
},
{
test: /\.mjs$/,
include: /node_modules/,
type: "javascript/auto",
}
]
},
plugins: [new webpack.DefinePlugin({ "global.GENTLY": false })],
optimization: {
minimize: false
},
resolve: {
extensions: [".webpack.js", ".web.js", ".mjs", ".tsx", ".ts", ".js", ".json"]
},
output: {
filename: "server.js",
path: path.resolve(fivemPath, "dist")
},
target: "node"
};
1 change: 1 addition & 0 deletions src/config/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './vehicles'
64 changes: 64 additions & 0 deletions src/config/vehicles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { GraphQLObjectType, GraphQLID, GraphQLString, GraphQLNonNull } from "graphql"
import { Schema } from 'mongoose'
import { registerGraphSchema } from '../main'
import { model } from 'mongoose'

// Model)
const Vehicle = model("Vehicle", new Schema({
name: String,
model: String,
plate: String
}))

const vehicleType = new GraphQLObjectType({
name: "Vehicle",
fields: () => ({
id: { type: GraphQLID },
name: { type: GraphQLString },
model: { type: GraphQLString },
plate: { type: GraphQLString },
})
})

const vehicleQuery = new GraphQLObjectType({
name: 'VehicleQuery',
fields: {
vehicle: {
type: vehicleType,
args: { id: { type: new GraphQLNonNull(GraphQLID) } },
resolve(parent, args){
return Vehicle.findById(args.id)
}
}
}
});

const vehicleMutation = new GraphQLObjectType({
name : 'VehicleMutation',
fields: {
addVehicle: {
type: vehicleType,
args: {
name: { type: GraphQLString },
model: { type: GraphQLString },
plate: { type: GraphQLString },
},
resolve(parent, args) {
const vehicle = new Vehicle({
name: args.name,
model: args.model,
plate: args.plate
})

return vehicle.save()
}
}
}
})

export function loadVehicleConfig() {
registerGraphSchema("Vehicle", {
query: vehicleQuery,
mutation: vehicleMutation
})
}
5 changes: 5 additions & 0 deletions src/db.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const mongodbUrl = "mongodb://localhost:27017"
export const mongodbDatabase = "fivem"

// Set to true if you want to trigger a global event onsce the database is ready.
export const triggerGlobalEvent = false
50 changes: 50 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { graphql, GraphQLSchema, Source, GraphQLSchemaConfig } from 'graphql'
import { connect, connection, Schema, model } from 'mongoose'
import { loadVehicleConfig } from './config'
import { mongodbUrl, mongodbDatabase, triggerGlobalEvent } from './db';

connect(`${mongodbUrl}/${mongodbDatabase}`, { useNewUrlParser: true });

connection.on('error', console.error.bind(console, 'connection error:'));

connection.once('open', function() {
if (triggerGlobalEvent)
emit('onDatabaseReady')

loadVehicleConfig()
});

// Exports
// The purpose of theses are only to facilitate the usage of GraphQL
const schemas: any = {}

/**
* Register a schema in graphQL
* @param name
* @param config
*/
export function registerGraphSchema(name: string, config: GraphQLSchemaConfig) {
schemas[name] = new GraphQLSchema(config);
}

/**
* GraphQL query function helper
* @param schema
* @param params
* @param callback
*/
export function query(schema: string, params: string | Source, callback?: Function) {
if (!schema) return console.error("[GraphQL] schema is missing in your query.");
if (!schemas[schema]) return console.error(`[GraphQL] ${schema} is not registered.`)
if (!params) return console.error("[GraphQL] params is missing in your query.");

const scheme = schemas[schema]
graphql(scheme, params).then((result) => {
if (callback)
callback(result)
})
}

// exports
exports("query", query)
exports("registerGraphSchema", registerGraphSchema)
21 changes: 21 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"allowJs": true,
"types": ["@citizenfx/server", "@types/node"],
"importHelpers": true,
"alwaysStrict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"noImplicitAny": false,
"noImplicitThis": false,
"strictNullChecks": false
},
"include": [
"src/**/*"
]
}

0 comments on commit e260937

Please sign in to comment.