This repository has been archived by the owner on May 23, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: code overhaul, async/sync fix, better validation, better dx…
… & docs * refactor: server start / config validation WIP * refactor: serverStart & registerDefaultPaths * chore: update acknowledgements * refactor: async/sync fix & handle resource stop * feat: validate registerResourcePath args * refactor: path func result rework * chore: update readme
- Loading branch information
Showing
9 changed files
with
239 additions
and
169 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,50 +1,81 @@ | ||
# Wide API | ||
<div align="center"> | ||
|
||
## Description | ||
# 🌐 Wide API | ||
|
||
A resource for FiveM that provides an API to execute functions on the server. | ||
**A FiveM resource that provides an API to execute functions on the server.** | ||
|
||
### Getting Started | ||
</div> | ||
|
||
1. Download & unpack the release files. | ||
2. Place the folder in your servers resources folder. | ||
3. Edit the config.json file if desired. | ||
4. Start the resource. | ||
## 📚 Table of Contents | ||
|
||
Note: All paths are prefixed with the name of the resource that registered it. (/wide-api/ensure-resource/) | ||
- [Getting Started](#-getting-started) | ||
- [Register Your Own Paths](#-register-your-own-paths) | ||
- [Examples](#examples) | ||
- [Resource Restarter](#-resource-restarter) | ||
- [Handling Resource Restarts](#-handling-resource-restarts) | ||
- [Access Keys](#-access-keys) | ||
- [Caveats](#-caveats) | ||
- [Acknowledgements](#-acknowledgements) | ||
|
||
### Register your own paths | ||
## 🚀 Getting Started | ||
|
||
- This resource exposes one export: | ||
1. **Download** and unpack the release files. | ||
2. **Place** the folder in your server's `resources` folder. | ||
3. **Edit** the `config.json` file according to your preferences. | ||
4. **Start** the resource. | ||
|
||
## 🛠 Register Your Own Paths | ||
|
||
This resource exposes a single export. Your route handler can return any data you want or a custom ApiResponse. See [Caveats](#-caveats) below. | ||
|
||
```javascript | ||
registerResourcePath(path: string, handler: (queryParams: Record<string, string>) => ApiResponse | unknown) | ||
``` | ||
registerResourcePath(path: string, handler: (queryParams: Record<string, string>) => ApiResponse | void) | ||
|
||
### Examples | ||
|
||
- **Lua** (use the colon operator, not the dot operator) | ||
|
||
```lua | ||
exports["wide-api"]:registerResourcePath("yourPathName", function(queryParams) | ||
|
||
end) | ||
``` | ||
|
||
- **JavaScript** (queryParams type is `Record<string, string>`) | ||
|
||
```javascript | ||
globalThis.exports['wide-api'].registerResourcePath( | ||
'yourPathName', | ||
(queryParams) => {}, | ||
); | ||
``` | ||
|
||
### Resource restarter | ||
## 🔁 Resource Restarter | ||
|
||
- To use the 'ensure-resource' path, make sure it is enabled in the config.json file. | ||
- This path accepts one query parameter "resourceName". (/wide-api/ensure-resource?resourceName=baseevents/) | ||
- If using this path the resource will require the permission to use the "ensure", "start", and "stop" commands. | ||
- Enable the 'ensure-resource' path in the `config.json` file. | ||
- This path accepts one query parameter: `resourceName` (e.g. `/wide-api/ensure-resource?resourceName=baseevents/`). | ||
- If using this path, the resource will require permission to use the "ensure", "start", and "stop" commands. | ||
|
||
``` | ||
add_ace resource.wide-api command.ensure allow | ||
add_ace resource.wide-api command.start allow | ||
add_ace resource.wide-api command.stop allow | ||
``` | ||
|
||
### Handling resource restarts | ||
## 🔄 Handling Resource Restarts | ||
|
||
- When the API starts listening the 'wide-api:startServer' command is triggered. | ||
- When creating your own paths you can listen for this event and re-register any paths you've created. | ||
- When the API starts listening, the 'wide-api:startServer' command is triggered. | ||
- To handle resource restarts, listen for this event and re-register any paths you've created. | ||
|
||
### Access Keys | ||
## 🔑 Access Keys | ||
|
||
- Access keys should be added in the config.json file. | ||
- Access keys should be added in the `config.json` file. | ||
- If no access keys are provided, the server listens with unrestricted access. | ||
- If you do provide access keys then you must provide an access key in the 'x-api-key' header. | ||
- When access keys are specified, make sure to include an access key in the 'x-api-key' header for requests. | ||
- Access keys should be added in the format: { description: string, key: string } | ||
|
||
### Acknowledgements | ||
## ⚠️ Caveats | ||
|
||
- [AvarianKnight](https://github.com/AvarianKnight) for the idea and rough draft. | ||
- All paths are prefixed with the name of the resource that registered it (e.g., /wide-api/ensure-resource/). | ||
- If your route handler does not return an object/table that matches the ApiResponse type, the API assumes a response code of 200 and provides your returned data on the "data" key of the API response. Check the [ApiResponse type](https://github.com/c-wide/wide-api/blob/acbee784552da106dc45106b058cb9cffde6d95b/src/response.ts#L25) for more details. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import jsonschema from 'jsonschema'; | ||
import configSchema from '../config.schema.json'; | ||
import type { LoggerLevels } from '~/logger'; | ||
|
||
export type ResourceConfig = { | ||
server: { | ||
port: number; | ||
enableCors: boolean; | ||
accessKeys: Array<{ description: string; key: string }>; | ||
}; | ||
defaultPaths: { | ||
'ensure-resource': boolean; | ||
}; | ||
logger: { | ||
level: LoggerLevels; | ||
}; | ||
compareVersionOnStart: boolean; | ||
}; | ||
|
||
export type ConfigValidationResponse = | ||
| { status: 'success' } | ||
| { status: 'error'; errors: Array<string> }; | ||
|
||
const resourceConfig: ResourceConfig = JSON.parse( | ||
LoadResourceFile(GetCurrentResourceName(), 'config.json'), | ||
); | ||
|
||
export function validateConfig(): ConfigValidationResponse { | ||
const validatorResponse = new jsonschema.Validator().validate( | ||
resourceConfig, | ||
configSchema, | ||
); | ||
|
||
if (!validatorResponse.valid) { | ||
return { | ||
status: 'error', | ||
errors: validatorResponse.errors.map((error) => error.stack), | ||
}; | ||
} | ||
|
||
return { status: 'success' }; | ||
} | ||
|
||
export function getConfig(): ResourceConfig { | ||
return resourceConfig; | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,29 @@ | ||
import { getConfig, validateConfig } from '~/getConfig'; | ||
import { getConfig, validateConfig } from '~/config'; | ||
import { startServer } from '~/startServer'; | ||
import { createEnsureResourcePath } from '~/ensureResource'; | ||
import { compareResourceVersion } from '~/versionChecker'; | ||
import { logger, setLoggerMinLevel } from '~/logger'; | ||
|
||
on('onResourceStart', async (resourceName: string) => { | ||
if (resourceName === GetCurrentResourceName()) { | ||
if (!validateConfig()) return; | ||
const validationResult = validateConfig(); | ||
|
||
const config = getConfig(); | ||
if (validationResult.status !== 'success') { | ||
logger.fatal( | ||
`Invalid config.json detected. Errors: [${validationResult.errors.join( | ||
', ', | ||
)}]`, | ||
); | ||
|
||
if (config.compareVersionOnStart) { | ||
await compareResourceVersion(); | ||
return; | ||
} | ||
|
||
const pathArr: Array<() => void> = []; | ||
const config = getConfig(); | ||
|
||
if (config.defaultPaths['ensure-resource']) { | ||
pathArr.push(createEnsureResourcePath); | ||
if (config.compareVersionOnStart) { | ||
await compareResourceVersion(); | ||
} | ||
|
||
startServer(config.server, pathArr); | ||
setLoggerMinLevel(config.logger.level); | ||
startServer(); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,25 @@ | ||
import { Logger } from 'tslog'; | ||
import { getConfig, LoggerLevel } from '~/getConfig'; | ||
|
||
const level = getConfig().logger.level; | ||
export const LoggerLevel = { | ||
Debug: 'debug', | ||
Info: 'info', | ||
Warn: 'warn', | ||
Error: 'error', | ||
} as const; | ||
|
||
export type LoggerLevels = typeof LoggerLevel[keyof typeof LoggerLevel]; | ||
|
||
const LoggerLevelMap: Record<LoggerLevels, number> = { | ||
debug: 2, | ||
info: 3, | ||
warn: 4, | ||
error: 5, | ||
}; | ||
|
||
export const logger = new Logger({ | ||
prettyLogTemplate: '[{{dateIsoStr}}] [{{logLevelName}}] - ', | ||
minLevel: | ||
level === LoggerLevel.Debug | ||
? 2 | ||
: level === LoggerLevel.Info | ||
? 3 | ||
: level === LoggerLevel.Warn | ||
? 4 | ||
: 5, | ||
}); | ||
|
||
export function setLoggerMinLevel(level: LoggerLevels) { | ||
logger.settings.minLevel = LoggerLevelMap[level]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { getConfig } from '~/config'; | ||
import { createEnsureResourcePath } from '~/ensureResource'; | ||
|
||
export function registerDefaultPaths() { | ||
const config = getConfig(); | ||
|
||
if (config.defaultPaths['ensure-resource']) { | ||
createEnsureResourcePath(); | ||
} | ||
} |
Oops, something went wrong.