Merge branch 'master' of github.com:benallfree/pockethost

This commit is contained in:
Ben Allfree 2023-08-13 01:09:10 -07:00
commit a9f87897d6
5 changed files with 172 additions and 0 deletions

View File

@ -18,6 +18,7 @@
* [FTP Access](usage/ftp.md)
* [Backup & Restore](usage/backup-and-restore.md)
* [Cloud Functions](usage/cloud.md)
* [PocketBase Hooks](usage/hooks.md)
* [Upgrading](usage/upgrading.md)
## Contributing

View File

@ -15,6 +15,7 @@ Inside each instance directory, you will find:
| pb_data | The PocketBase data directory |
| pb_static | The location from which static files are served |
| pb_migrations | The PocketBase [migrations](https://pocketbase.io/docs/migrations/) directory |
| pb_hooks | The PocketBase [hooks](https://pocketbase.io/docs/js-overview/) directory |
| worker | The Deno-based cloud worker |
## Recommended Clients

165
gitbook/usage/hooks.md Normal file
View File

@ -0,0 +1,165 @@
# PocketBase Hooks
The prebuilt PocketBase v0.17+ executable comes with embedded ES5 JavaScript engine (goja) which enables you to write custom server-side code using plain JavaScript.
Every Pockethost instance comes with a `pb_hooks` directory which is mounted into the PocketBase instance at `/pb_hooks`. This directory is where you can place your custom server-side code.
For more information on PocketBase hooks, see the [PocketBase documentation](https://pocketbase.io/docs/js-overview/).
## Quickstart
You can start by creating `*.pb.js` file(s) inside the `pb_hooks` directory. The `*.pb.js` files are automatically loaded and executed by PocketBase.
## Code Samples
These are only a few simple and limited examples of what you can do with PocketBase hooks. There is lot more available to you. For more information, see the [PocketBase documentation](https://pocketbase.io/docs/js-overview/).
**Listen to the `onAfterBootstrap` hook handler and log a message to the console. This sample also shows how you can import utils or configs from another file.**
```
// pb_hooks/main.pb.js
// This runs when the PocketBase instance is first bootstrapped
onAfterBootstrap((e) => {
// You can load config or util files for your app
const config = require(`${__hooks}/config/config.js`);
const name = 'Hooks!'
const fxTest = config.hello(name);
console.log("App initialized!");
console.log(`fxTest: ${fxTest}`);
console.log(`App name: ${JSON.stringify(config)}`);
});
```
```
// pb_hooks/config/config.js
module.exports = {
appName: "pockethost-test",
appVersion: "0.0.1",
hello: (name) => {
return "Hello " + name
}
};
```
**Register a new route that you can interface with using the SDK**
```
// pb_hooks/somefile.pb.js
routerAdd("POST", "/test/:testId", (c) => {
const testId = c.pathParam("testId");
return c.json(200, {
testId
});
});
```
You can now interface with this route using the PocketBase SDK. Here's a JS SDK example:
```
const pb = new PocketBase('http://127.0.0.1:8090');
const response = await pb.send("/test/theTestId", {
method: "POST"
});
// response returns { testId: "theTestId" }
```
**Find a record and update it**
```
// pb_hooks/posts.update.pb.js
routerAdd("PATCH", "/posts/:postId", (c) => {
const postId = c.pathParam("postId");
// Get body data
const body = $apis.requestInfo(c).data;
const status = body.status;
// Find a record by ID on the "posts" collection
const record = $app.dao().findRecordById("posts", postId);
// If the record doesn't exist, return a 404
// Perhaps you can return a 40X if the user doesn't have permission to update the record etc
if (!record) {
return c.json(404, {
error: "Record not found"
});
}
// Update the record with the new status
record.set("status", status);
// Save the record
$app.dao().saveRecord(record);
// Expand record before we return it
$app.dao().expandRecord(record, ["user", "comments"], null);
// Return the record
return c.json(200, {
record
});
});
```
**Find a collection and create a new record**
```
// pb_hooks/posts.create.pb.js
routerAdd("POST", "/posts", (c) => {
// Get body data
const body = $apis.requestInfo(c).data;
// Get values from body
const { postTitle, postDescription } = body;
// Find the collection by name
const postsCollection = $app.dao().findCollectionByNameOrId("posts");
// Create a new post record
const record = new Record(postsCollection, {
title: postTitle,
description: postDescription
});
// Save the record
$app.dao().saveRecord(record);
// Return the record
return c.json(200, {
record
});
});
```
**Listen to record changes on a collection**
In this sample, we react to a user being registered and we create a new customer record in Stripe.
This is not tested, and is a fictional scenario. But the concept behind it is what we're trying to show.
```
// pb_hooks/users.onRegister.pb.js
onRecordAfterCreateRequest((e) => {
// Get the record
const record = e.record;
try {
// Invoke Stripe API to create a new customer
const response = $http.send({
url: "https://api.stripe.com/v1/customers", // Stripe API URL
method: "POST",
body: {
email: record.email
},
headers: {
// Provide Stripe API key or whatever else they require
}
})
if (response) {
console.log("Stripe customer created!", response.newCustomerId);
}
} catch (err) {
console.log(err)
}
}, "users") // This runs when a record is created on the "users" collection
```

View File

@ -18,6 +18,7 @@ export enum FolderNames {
PbData = 'pb_data',
PbStatic = 'pb_static',
PbMigrations = 'pb_migrations',
PbHooks = 'pb_hooks',
PbWorker = 'worker',
}
@ -26,6 +27,7 @@ export const INSTANCE_ROOT_FOLDER_NAMES: FolderNames[] = [
FolderNames.PbStatic,
FolderNames.PbWorker,
FolderNames.PbMigrations,
FolderNames.PbHooks,
]
export function isInstanceRootFolder(name: string): name is FolderNames {

View File

@ -32,6 +32,9 @@
<tr>
<th>pb_migrations</th><td>The PocketBase migrations directory</td>
</tr>
<tr>
<th>pb_hooks</th><td>The PocketBase hooks directory</td>
</tr>
<tr>
<th>worker</th><td>Deno worker (cloud TS/JS functions)</td>
</tr>