mirror of
https://github.com/pockethost/pockethost.git
synced 2025-03-30 15:08:30 +00:00
chore: remove attic
This commit is contained in:
parent
328d6a41ee
commit
24abdbf8a2
@ -1,26 +0,0 @@
|
||||
FROM nginx:alpine
|
||||
|
||||
|
||||
RUN apk update
|
||||
RUN apk add -v build-base
|
||||
RUN apk add -v go
|
||||
RUN apk add -v ca-certificates
|
||||
RUN apk add -v git
|
||||
|
||||
COPY ./pocketbase /pocketbase
|
||||
WORKDIR /pocketbase
|
||||
RUN go clean
|
||||
RUN go build
|
||||
RUN chmod +x pocketbase
|
||||
RUN mv pocketbase /usr/local/bin/pocketbase
|
||||
WORKDIR /
|
||||
|
||||
ADD ./data /data
|
||||
ADD ./nginx/conf.d /etc/nginx/conf.d
|
||||
|
||||
# Notify Docker that the container wants to expose a port.
|
||||
EXPOSE 80
|
||||
|
||||
COPY ./run.sh /run.sh
|
||||
RUN chmod +x /run.sh
|
||||
ENTRYPOINT ./run.sh
|
@ -1,37 +0,0 @@
|
||||
FROM nginx:alpine
|
||||
|
||||
# RUN apk add openrc
|
||||
# RUN apt update
|
||||
# RUN apt-get install -y unzip
|
||||
# RUN apt-get install -y nginx
|
||||
# RUN apt-get install -y systemd
|
||||
RUN apk add -v build-base
|
||||
RUN apk add -v go
|
||||
RUN apk add -v ca-certificates
|
||||
|
||||
|
||||
|
||||
# COPY ./pockethost-init.d /etc/init.d/pockethost
|
||||
# RUN chmod +x /etc/init.d/pockethost
|
||||
# RUN service nginx start
|
||||
# RUN service pockethost start
|
||||
|
||||
COPY ./run.sh /run.sh
|
||||
RUN chmod +x /run.sh
|
||||
|
||||
COPY ./pockethost /pockethost
|
||||
WORKDIR /pockethost
|
||||
RUN ls
|
||||
RUN go clean
|
||||
RUN go build
|
||||
RUN chmod +x pockethost
|
||||
RUN mv pockethost /usr/local/bin/pockethost
|
||||
WORKDIR /
|
||||
|
||||
ADD ./data /data
|
||||
ADD ./nginx/conf.d /etc/nginx/conf.d
|
||||
|
||||
# Notify Docker that the container wants to expose a port.
|
||||
EXPOSE 80
|
||||
|
||||
ENTRYPOINT /run.sh
|
@ -1,23 +0,0 @@
|
||||
FROM nginx:latest
|
||||
|
||||
ARG POCKETBASE_VERSION=0.7.2
|
||||
|
||||
RUN apt update
|
||||
RUN apt install -y unzip systemd systemd-sysv
|
||||
RUN apt install -y systemd
|
||||
RUN apt install -y systemd-sysv
|
||||
|
||||
# Download Pocketbase and install it for AMD64
|
||||
ADD https://github.com/pocketbase/pocketbase/releases/download/v${POCKETBASE_VERSION}/pocketbase_${POCKETBASE_VERSION}_linux_amd64.zip /tmp/pocketbase.zip
|
||||
RUN unzip /tmp/pocketbase.zip -d /usr/local/bin/
|
||||
RUN chmod +x /usr/local/bin/pocketbase
|
||||
|
||||
ADD ./data /data
|
||||
ADD ./nginx/conf.d /etc/nginx/conf.d
|
||||
|
||||
COPY ./pockethost-db.service /etc/systemd/system/pockethost-db.service
|
||||
RUN systemctl enable pockethost-db.service
|
||||
# RUN echo "::respawn:/usr/local/bin/pocketbase serve --http '127.0.0.1:8090' --dir /data/pockethost" >> /etc/inittab
|
||||
|
||||
# Notify Docker that the container wants to expose a port.
|
||||
EXPOSE 80
|
@ -1,22 +0,0 @@
|
||||
FROM nginx:alpine
|
||||
|
||||
|
||||
RUN apk update
|
||||
RUN apk add -v build-base
|
||||
RUN apk add -v go
|
||||
RUN apk add -v ca-certificates
|
||||
RUN apk add -v git
|
||||
|
||||
COPY ./pocketbase /pocketbase
|
||||
WORKDIR /pocketbase
|
||||
RUN go clean
|
||||
RUN go build
|
||||
RUN chmod +x pocketbase
|
||||
RUN mv pocketbase /usr/local/bin/pocketbase
|
||||
WORKDIR /
|
||||
|
||||
|
||||
# Notify Docker that the container wants to expose a port.
|
||||
EXPOSE 80
|
||||
|
||||
ENTRYPOINT pocketbase serve --http 127.0.0.1:80
|
@ -1,19 +0,0 @@
|
||||
FROM ubuntu
|
||||
|
||||
RUN apt update
|
||||
RUN apt-get install -y golang-go
|
||||
RUN apt-get install -y ca-certificates
|
||||
|
||||
COPY ./pocketbase /pocketbase
|
||||
WORKDIR /pocketbase
|
||||
RUN go clean
|
||||
RUN go build
|
||||
RUN chmod +x pocketbase
|
||||
RUN mv pocketbase /usr/local/bin/pocketbase
|
||||
WORKDIR /
|
||||
|
||||
ADD ./data /data
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
ENTRYPOINT ["tail", "-f", "/dev/null"]
|
@ -1,2 +0,0 @@
|
||||
apt up
|
||||
apt upgrade -y
|
@ -1,6 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
docker container rm -f pockethost
|
||||
docker image rm -f pockethost
|
||||
docker build -f $1 -t pockethost .
|
||||
docker run --name pockethost -p 80:80 pockethost
|
@ -1,24 +0,0 @@
|
||||
FROM alpine:latest
|
||||
|
||||
RUN apk add -v build-base
|
||||
RUN apk add -v go
|
||||
RUN apk add -v ca-certificates
|
||||
|
||||
ARG PB_VERSION=0.7.4
|
||||
|
||||
RUN apk add --no-cache \
|
||||
unzip \
|
||||
# this is needed only if you want to use scp to copy later your pb_data locally
|
||||
openssh
|
||||
|
||||
# Copy your custom PocketBase and build
|
||||
COPY ./pocketbase-custom /pb
|
||||
WORKDIR /pb
|
||||
RUN go get github.com/pocketbase/pocketbase
|
||||
RUN go build
|
||||
WORKDIR /
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
# start PocketBase
|
||||
CMD ["/pb/pocketbase", "serve", "--http=0.0.0.0:8080"]
|
@ -1,45 +0,0 @@
|
||||
# fly.toml file generated for harvest on 2022-09-19T09:11:29-07:00
|
||||
|
||||
app = "harvest"
|
||||
kill_signal = "SIGINT"
|
||||
kill_timeout = 5
|
||||
processes = []
|
||||
|
||||
[env]
|
||||
|
||||
[build.args]
|
||||
PB_VERSION="0.7.4"
|
||||
|
||||
[experimental]
|
||||
allowed_public_ports = []
|
||||
auto_rollback = true
|
||||
|
||||
[[services]]
|
||||
http_checks = []
|
||||
internal_port = 8080
|
||||
processes = ["app"]
|
||||
protocol = "tcp"
|
||||
script_checks = []
|
||||
[services.concurrency]
|
||||
hard_limit = 25
|
||||
soft_limit = 20
|
||||
type = "connections"
|
||||
|
||||
[[services.ports]]
|
||||
force_https = true
|
||||
handlers = ["http"]
|
||||
port = 80
|
||||
|
||||
[[services.ports]]
|
||||
handlers = ["tls", "http"]
|
||||
port = 443
|
||||
|
||||
[[services.tcp_checks]]
|
||||
grace_period = "1s"
|
||||
interval = "15s"
|
||||
restart_limit = 0
|
||||
timeout = "2s"
|
||||
|
||||
[mounts]
|
||||
destination = "/pb/pb_data"
|
||||
source = "pb_data"
|
@ -1,83 +0,0 @@
|
||||
module pocketbase
|
||||
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/AlecAivazis/survey/v2 v2.3.5 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
|
||||
github.com/aws/aws-sdk-go v1.44.85 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.16.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.17.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.12.14 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.12 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.27 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.18 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.12 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.19 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.13 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.12 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.12 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.27.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.16.13 // indirect
|
||||
github.com/aws/smithy-go v1.12.1 // indirect
|
||||
github.com/disintegration/imaging v1.6.2 // indirect
|
||||
github.com/domodwyer/mailyak/v3 v3.3.4 // indirect
|
||||
github.com/fatih/color v1.13.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.1 // indirect
|
||||
github.com/ganigeorgiev/fexpr v0.1.1 // indirect
|
||||
github.com/go-ozzo/ozzo-validation/v4 v4.3.0 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/google/wire v0.5.0 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.5.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/labstack/echo/v5 v5.0.0-20220201181537-ed2888cfa198 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.15 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
|
||||
github.com/pocketbase/dbx v1.6.0 // indirect
|
||||
github.com/pocketbase/pocketbase v0.7.4 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/cobra v1.5.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.1 // indirect
|
||||
go.opencensus.io v0.23.0 // indirect
|
||||
gocloud.dev v0.26.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220824171710-5757bc0c5503 // indirect
|
||||
golang.org/x/image v0.0.0-20220722155232-062f8c9fd539 // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
golang.org/x/net v0.0.0-20220822230855-b0a4917ee28c // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 // indirect
|
||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 // indirect
|
||||
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect
|
||||
golang.org/x/tools v0.1.12 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect
|
||||
google.golang.org/api v0.94.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc // indirect
|
||||
google.golang.org/grpc v1.49.0 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
lukechampine.com/uint128 v1.2.0 // indirect
|
||||
modernc.org/cc/v3 v3.36.3 // indirect
|
||||
modernc.org/ccgo/v3 v3.16.9 // indirect
|
||||
modernc.org/libc v1.17.0 // indirect
|
||||
modernc.org/mathutil v1.5.0 // indirect
|
||||
modernc.org/memory v1.2.0 // indirect
|
||||
modernc.org/opt v0.1.3 // indirect
|
||||
modernc.org/sqlite v1.18.1 // indirect
|
||||
modernc.org/strutil v1.1.2 // indirect
|
||||
modernc.org/token v1.0.0 // indirect
|
||||
)
|
File diff suppressed because it is too large
Load Diff
@ -1,15 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/pocketbase/pocketbase"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := pocketbase.New()
|
||||
|
||||
if err := app.Start(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
# fly.toml file generated for pockethost on 2022-09-15T20:05:31-07:00
|
||||
|
||||
app = "pockethost"
|
||||
kill_signal = "SIGINT"
|
||||
kill_timeout = 5
|
||||
processes = []
|
||||
|
||||
[env]
|
||||
|
||||
[experimental]
|
||||
allowed_public_ports = []
|
||||
auto_rollback = true
|
||||
|
||||
[[services]]
|
||||
http_checks = []
|
||||
internal_port = 8090
|
||||
processes = ["app"]
|
||||
protocol = "tcp"
|
||||
script_checks = []
|
||||
[services.concurrency]
|
||||
hard_limit = 25
|
||||
soft_limit = 20
|
||||
type = "connections"
|
||||
|
||||
[[services.ports]]
|
||||
force_https = true
|
||||
handlers = ["http"]
|
||||
port = 80
|
||||
|
||||
[[services.ports]]
|
||||
handlers = ["tls", "http"]
|
||||
port = 443
|
||||
|
||||
[[services.tcp_checks]]
|
||||
grace_period = "1s"
|
||||
interval = "15s"
|
||||
restart_limit = 0
|
||||
timeout = "2s"
|
1
attic/js-cloud-funcs/.gitignore
vendored
1
attic/js-cloud-funcs/.gitignore
vendored
@ -1 +0,0 @@
|
||||
dist
|
@ -1,2 +0,0 @@
|
||||
src
|
||||
tsconfig.json
|
@ -1,40 +0,0 @@
|
||||
{
|
||||
"name": "@pockethost/cloud-functions",
|
||||
"version": "0.0.3",
|
||||
"source": "src/index.ts",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
"name": "Ben Allfree",
|
||||
"url": "https://github.com/benallfree"
|
||||
},
|
||||
"repository": {
|
||||
"url": "https://github.com/benallfree/pockethost"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "chokidar '**' --ignore 'dist' -c 'parcel build --no-cache' --initial",
|
||||
"build": "parcel build --no-cache"
|
||||
},
|
||||
"devDependencies": {
|
||||
"parcel": "^2.7.0",
|
||||
"typescript": "^4.8.3"
|
||||
},
|
||||
"targets": {
|
||||
"main": {
|
||||
"isLibrary": true,
|
||||
"context": "browser",
|
||||
"outputFormat": "esmodule",
|
||||
"sourceMap": true,
|
||||
"includeNodeModules": true
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@s-libs/micro-dash": "^14.1.0",
|
||||
"nanoevents": "^7.0.1",
|
||||
"nanoid": "^4.0.0",
|
||||
"svelte": "^3.51.0",
|
||||
"ts-brand": "^0.0.2"
|
||||
}
|
||||
}
|
@ -1,282 +0,0 @@
|
||||
# TS/JS Cloud Functions for PocketBase
|
||||
|
||||
**_Write all your PocketBase server-side logic in TS/JS_**
|
||||
|
||||
PBScript allows you to write [PocketBase](https://pocketbase.io) server-side functions in Typescript or Javascript without recompiling.
|
||||
|
||||
With PBScript, you can:
|
||||
|
||||
- ✅ Write your server-side logic in Typescript or JS
|
||||
- ✅ Access models, collections, transactions, hooks, and all server-side features of PocketBase
|
||||
- ✅ Communicate with PocketBase using a streamlined JavaScript-style API
|
||||
- ✅ Deploy and alter cloud functions without rebuilding _or even restarting_ PocketBase
|
||||
- ✅ Roll back to previous versions
|
||||
- ✅ Use the `pbscript` CLI tool for intelligent dev mode, live deployment, and rollback
|
||||
|
||||
<h3>Table of Contents</h3>
|
||||
|
||||
<!-- @import "[TOC]" {cmd="toc" depthFrom=2 depthTo=6 orderedList=false} -->
|
||||
|
||||
<!-- code_chunk_output -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Getting Started](#getting-started)
|
||||
- [Developing your script](#developing-your-script)
|
||||
- [Building and deploying your script](#building-and-deploying-your-script)
|
||||
- [API](#api)
|
||||
- [`__go.ping()`](#__goping)
|
||||
- [`__go.addRoute()`](#__goaddroute)
|
||||
- [`__go.app`](#__goapp)
|
||||
- [Advanced](#advanced)
|
||||
- [Upgrading an Existing Custom PocketBase](#upgrading-an-existing-custom-pocketbase)
|
||||
|
||||
<!-- /code_chunk_output -->
|
||||
|
||||
## Introduction
|
||||
|
||||
PBScript extends PocketBase with an [ES-5.1 (ECMA 262)](https://262.ecma-international.org/5.1/) scripting engine powered by [goja](https://github.com/dop251/goja).
|
||||
|
||||
Code executes in a secure sandboxed environment without a [Node.js API](https://nodejs.org/docs/latest/api/) or [Web APIs](https://developer.mozilla.org/en-US/docs/Web/API). Instead, the runtime environment is PocketBase-specific, with full access to PocketBase's [native Go extension API](https://pocketbase.io/docs/use-as-framework/) and includes streamlined functions and helper utilities written in JavaScript (@pbscript/core).
|
||||
|
||||
Use `pbscript` command line tool to build and publish cloud functions to any PBScript-enabled PocketBase instance.
|
||||
|
||||
## Getting Started
|
||||
|
||||
<h3>1. Create a PocketBase instance</h3>
|
||||
|
||||
To run JS functions, you need to run a PocketBase instance which has been enhanced with PBScript.
|
||||
|
||||
You can do it any way you like, just as long as you end up with an admin login for the next section.
|
||||
|
||||
**Option 1 (free): run fully managed on [pockethost.io](https://pockethost.io)**
|
||||
|
||||
The absolute easiest way to provision a new PocketBase instance enhanced with PBScript is to use [pockethost.io](https://pockethost.io). You'll be up and running with a PocketBase URL in under 30 seconds. This is as close to a Firebase/Supabase BaaS experience as you can get.
|
||||
|
||||
**Option 2 (free): run self-managed on fly.io**
|
||||
|
||||
If you'd rather manage your resources yourself, you can follow the instructions in [this thread](https://github.com/pocketbase/pocketbase/discussions/537) to get up and running on fly.io.
|
||||
|
||||
This option takes about 30 minutes to set up.
|
||||
|
||||
**Option 3 (free): run a custom build locally**
|
||||
|
||||
If you just want to run locally or have a special use case, you can create your own build.
|
||||
|
||||
Create `pocketbase.go`:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
pocketbase "github.com/benallfree/pbscript/modules/pbscript"
|
||||
)
|
||||
|
||||
|
||||
func main() {
|
||||
app := pocketbase.New()
|
||||
|
||||
if err := app.Start(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
On the command line, run:
|
||||
|
||||
```bash
|
||||
go get github.com/benallfree/pbscript/modules/pbscript
|
||||
go run pocketbase.go serve
|
||||
|
||||
> Server started at: http://127.0.0.1:8090
|
||||
- REST API: http://127.0.0.1:8090/api/
|
||||
- Admin UI: http://127.0.0.1:8090/_/
|
||||
```
|
||||
|
||||
<h3>2. Create a new JS/TS project</h3>
|
||||
|
||||
You can create any type of TS/JS project you want, but here's the `package.json` we recommend. We also have a [sample PBScript project](https://github.com/benallfree/pbscript/tree/master/packages/sample) you can check out.
|
||||
|
||||
The important part is that your script gets bundled as ES5:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "sample",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"@pbscript/core": "^0.0.1"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "parcel build --no-cache",
|
||||
"deploy:local": "pbscript deploy --host 'http://127.0.0.1:8090'",
|
||||
"dev": "chokidar 'src/**' './node_modules/**' -c 'yarn build && yarn deploy:local' --initial"
|
||||
},
|
||||
"targets": {
|
||||
"iife": {
|
||||
"source": "./src/index.ts",
|
||||
"context": "browser",
|
||||
"outputFormat": "global",
|
||||
"sourceMap": {
|
||||
"inline": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"chokidar-cli": "^3.0.0",
|
||||
"parcel": "^2.7.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<h3>3. Use the `pbscript` CLI tool to log in</h3>
|
||||
|
||||
Enter your project directory and log in to your PocketBase instance using the admin account you created in Step #1:
|
||||
|
||||
```
|
||||
npx pbscript login <username> <password> --host <pocketbase URL>
|
||||
```
|
||||
|
||||
This will create a file named `.pbcache`. Add it to `.gitignore`.
|
||||
|
||||
## Developing your script
|
||||
|
||||
In your command shell, run:
|
||||
|
||||
```bash
|
||||
npx pbscript dev
|
||||
```
|
||||
|
||||
PBScript is designed for a fast development cycle. If you used our `package.json`, this command will watch for changes (in `./dist`) and re-deploy your script on every change.
|
||||
|
||||
PBScript updates do not require a PocketBase restart. Old versions of your script are kept in an archive table for easy rollbacks.
|
||||
|
||||
## Building and deploying your script
|
||||
|
||||
`pbscript` knows how to deploy to any PBScript-enabled PocketBase instance.
|
||||
|
||||
**Connect to your live site**
|
||||
|
||||
First, connect to your live site. `pbscript` will remember your credentials for future commands.
|
||||
|
||||
```bash
|
||||
npx pbscript login <username> <password> --host https://yourproject.pockethost.io
|
||||
Saved to .pbcache
|
||||
```
|
||||
|
||||
**Build your `./dist/index.js` bundle**
|
||||
|
||||
You can build your script bundle however you want, just make sure you end up with ONE bundle file in `./dist/index.js`. If you use source maps, inline them. `pbscript` only deploys this one file.
|
||||
|
||||
**Deploy your latest changes**
|
||||
|
||||
You can deploy changes at any time without restarting PocketBase. All realtime connections and users will remain connected.
|
||||
|
||||
```bash
|
||||
pbscript deploy --host <your pocketbase URL>
|
||||
```
|
||||
|
||||
Or, add it to `package.json`:
|
||||
|
||||
```json
|
||||
"scripts": {
|
||||
"deploy": "pbscript deploy --host https://yourproject.pockethost.io"
|
||||
}
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
PBScript runs in a secure sandboxed environment inside PocketBase. A simplified subset of PocketBase's hooks are available. Complete Typescript definitions are included.
|
||||
|
||||
You might be accustomed to using the [NodeJS API](https://nodejs.org/docs/latest/api/) or the browser [Web API](https://developer.mozilla.org/en-US/docs/Web/API), but those APIs are not core features of ECMAScript. They are not safe or allowed in the PocketBase execution environment.
|
||||
|
||||
Instead, your script runs in the `PocketBaseApi` execution environment. `PocketBaseApi` set of API calls to interact with PocketBase. With it, you can do CRUD, transactions, hook into PocketBase events, new API endpoints, and generally extend PocketBase.
|
||||
|
||||
PBScript imports a `__go` variable containing low-level access to the PocketBase native API and other helpers implemented in Go. @pbscript/core uses `__go` internally, but if there is something missing, you may be able to accomplish it yourself by accessing `__go` directly.
|
||||
|
||||
### `__go.ping()`
|
||||
|
||||
Test function that should return `Hello from Go!`
|
||||
|
||||
Example:
|
||||
|
||||
```ts
|
||||
console.log(__go.ping())
|
||||
```
|
||||
|
||||
### `__go.addRoute()`
|
||||
|
||||
Add an API route.
|
||||
|
||||
Example:
|
||||
|
||||
```ts
|
||||
__go.addRoute({
|
||||
method: HttpMethods.Get,
|
||||
path: `/api/hello`
|
||||
handler: (context)=>{
|
||||
context.send(HttpStatus.Ok, `Hello back!`)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### `__go.app`
|
||||
|
||||
Low-level primitive providing direct access to the `PocketBase` app instance. Normally you will not access this directly. The @pbscript/core library is built on top of this.
|
||||
|
||||
## Advanced
|
||||
|
||||
### Upgrading an Existing Custom PocketBase
|
||||
|
||||
The easiest way to get PBScript is to use our custom PocketBase module [github.com/benallfree/pbscript/modules/pocketbase](https://github.com/benallfree/pbscript/modules/pocketbase):
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/benallfree/pbscript/packages/pocketbase" // Notice this is a custom version of the PocketBase module
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := pocketbase.New()
|
||||
|
||||
if err := app.Start(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you are already using a custom PocketBase build, just swap out `github.com/pocketbase/pocketbase` with `github.com/benallfree/pbscript/packages/pocketbase` and everything will work as expected.
|
||||
|
||||
Or, if you prefer, you can do exactly what our custom module does:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase"
|
||||
|
||||
"github.com/benallfree/pbscript/packages/pbscript"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := pocketbase.New()
|
||||
pbscript.StartPBScript(app) // Magic line to enable PBScript
|
||||
|
||||
if err := app.Start(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Changelog
|
||||
|
||||
### 0.0.2
|
||||
|
||||
- Transaction support
|
||||
|
||||
### 0.0.1
|
||||
|
||||
- Initial release
|
@ -1,38 +0,0 @@
|
||||
import { PackedData } from './index'
|
||||
import { assertExists } from './util/assert'
|
||||
import { isFunction } from './util/isFunction'
|
||||
|
||||
// JSON encoder to tokenize functions and store their references
|
||||
|
||||
export type FunctionToken = string
|
||||
export const createFunctionMarshaler = () => {
|
||||
// Create a unique ID for this instance
|
||||
const nanoid = (() => {
|
||||
let i = 0
|
||||
return () => i++
|
||||
})()
|
||||
|
||||
const funcCache: { [_: FunctionToken]: () => any } = {}
|
||||
const encode = (key: string, value: any) => {
|
||||
if (isFunction(value)) {
|
||||
const uuid = `fn_${nanoid()}`
|
||||
funcCache[uuid] = value
|
||||
return uuid
|
||||
}
|
||||
if (value === undefined) {
|
||||
return `ü`
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
const exec = (tok: FunctionToken) => {
|
||||
const fn = funcCache[tok]
|
||||
assertExists(fn, `Function ${tok} does not exist`)
|
||||
const ret = fn()
|
||||
return pack(ret)
|
||||
}
|
||||
|
||||
const pack = (o: any) => JSON.stringify(o, encode) as PackedData
|
||||
|
||||
return { pack, exec }
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
// import { emitter, NativePocketBaseEvents } from './index'
|
||||
|
||||
// export const CoreMiddleware = {
|
||||
// requireAdminOrUserAuth: () => 'RequireAdminOrUserAuth',
|
||||
// }
|
||||
|
||||
// export type JsMiddlewareToken = string
|
||||
|
||||
// export type JsHttpRoutePath = string
|
||||
|
||||
// export type JsAddRouteConfig = {
|
||||
// method: HttpMethods
|
||||
// path: JsHttpRoutePath
|
||||
// handler: (context: HttpRequestContext) => void
|
||||
// middlewares: JsMiddlewareToken[]
|
||||
// }
|
||||
|
||||
// export type OnBeforeServeEvent = {
|
||||
// Router: {
|
||||
// addRoute: (config: JsAddRouteConfig) => void
|
||||
// }
|
||||
// }
|
||||
|
||||
// export const onBeforeServe = (cb: (e: OnBeforeServeEvent) => void) => {
|
||||
// emitter.on(NativePocketBaseEvents.OnBeforeServe, cb)
|
||||
// }
|
||||
|
||||
// export const dispatchObBeforeServe = ()=>{
|
||||
// case NativePocketBaseEvents.OnBeforeServe:
|
||||
// const e: OnBeforeServeEvent = {
|
||||
// Router: {
|
||||
// addRoute: (config) => {
|
||||
// const packed = pack(config)
|
||||
// console.log(`Sending config back ${packed}`)
|
||||
// __go_addRoute(packed)
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
// emitter.emit(eventName, e)
|
||||
// }
|
@ -1,7 +0,0 @@
|
||||
export enum HttpMethods {
|
||||
Get = 'GET',
|
||||
}
|
||||
|
||||
export enum HttpResponseStatuses {
|
||||
Ok = 200,
|
||||
}
|
@ -1,616 +0,0 @@
|
||||
import { createEvent } from './util/event'
|
||||
|
||||
export type ModelBeforeCreateEvent = {}
|
||||
const [onModelBeforeCreate, fireModelBeforeCreate] =
|
||||
createEvent<ModelBeforeCreateEvent>(`OnModelBeforeCreate`)
|
||||
export { onModelBeforeCreate, fireModelBeforeCreate }
|
||||
export { onModelAfterCreate, fireModelAfterCreate }
|
||||
export { onModelBeforeUpdate, fireModelBeforeUpdate }
|
||||
export { onModelAfterUpdate, fireModelAfterUpdate }
|
||||
export { onModelBeforeDelete, fireModelBeforeDelete }
|
||||
export { onModelAfterDelete, fireModelAfterDelete }
|
||||
export {
|
||||
onMailerBeforeAdminResetPasswordSend,
|
||||
fireMailerBeforeAdminResetPasswordSend,
|
||||
}
|
||||
export {
|
||||
onMailerAfterAdminResetPasswordSend,
|
||||
fireMailerAfterAdminResetPasswordSend,
|
||||
}
|
||||
export {
|
||||
onMailerBeforeUserResetPasswordSend,
|
||||
fireMailerBeforeUserResetPasswordSend,
|
||||
}
|
||||
export {
|
||||
onMailerAfterUserResetPasswordSend,
|
||||
fireMailerAfterUserResetPasswordSend,
|
||||
}
|
||||
export {
|
||||
onMailerBeforeUserVerificationSend,
|
||||
fireMailerBeforeUserVerificationSend,
|
||||
}
|
||||
export {
|
||||
onMailerAfterUserVerificationSend,
|
||||
fireMailerAfterUserVerificationSend,
|
||||
}
|
||||
export {
|
||||
onMailerBeforeUserChangeEmailSend,
|
||||
fireMailerBeforeUserChangeEmailSend,
|
||||
}
|
||||
export { onMailerAfterUserChangeEmailSend, fireMailerAfterUserChangeEmailSend }
|
||||
export { onRealtimeConnectRequest, fireRealtimeConnectRequest }
|
||||
export { onRealtimeBeforeSubscribeRequest, fireRealtimeBeforeSubscribeRequest }
|
||||
export { onRealtimeAfterSubscribeRequest, fireRealtimeAfterSubscribeRequest }
|
||||
export { onSettingsListRequest, fireSettingsListRequest }
|
||||
export { onSettingsBeforeUpdateRequest, fireSettingsBeforeUpdateRequest }
|
||||
export { onSettingsAfterUpdateRequest, fireSettingsAfterUpdateRequest }
|
||||
export { onFileDownloadRequest, fireFileDownloadRequest }
|
||||
export { onAdminsListRequest, fireAdminsListRequest }
|
||||
export { onAdminViewRequest, fireAdminViewRequest }
|
||||
export { onAdminBeforeCreateRequest, fireAdminBeforeCreateRequest }
|
||||
export { onAdminAfterCreateRequest, fireAdminAfterCreateRequest }
|
||||
export { onAdminBeforeUpdateRequest, fireAdminBeforeUpdateRequest }
|
||||
export { onAdminAfterUpdateRequest, fireAdminAfterUpdateRequest }
|
||||
export { onAdminBeforeDeleteRequest, fireAdminBeforeDeleteRequest }
|
||||
export { onAdminAfterDeleteRequest, fireAdminAfterDeleteRequest }
|
||||
export { onAdminAuthRequest, fireAdminAuthRequest }
|
||||
export { onUsersListRequest, fireUsersListRequest }
|
||||
export { onUserViewRequest, fireUserViewRequest }
|
||||
export { onUserBeforeCreateRequest, fireUserBeforeCreateRequest }
|
||||
export { onUserAfterCreateRequest, fireUserAfterCreateRequest }
|
||||
export { onUserBeforeUpdateRequest, fireUserBeforeUpdateRequest }
|
||||
export { onUserAfterUpdateRequest, fireUserAfterUpdateRequest }
|
||||
export { onUserBeforeDeleteRequest, fireUserBeforeDeleteRequest }
|
||||
export { onUserAfterDeleteRequest, fireUserAfterDeleteRequest }
|
||||
export { onUserAuthRequest, fireUserAuthRequest }
|
||||
export { onUserListExternalAuths, fireUserListExternalAuths }
|
||||
export {
|
||||
onUserBeforeUnlinkExternalAuthRequest,
|
||||
fireUserBeforeUnlinkExternalAuthRequest,
|
||||
}
|
||||
export {
|
||||
onUserAfterUnlinkExternalAuthRequest,
|
||||
fireUserAfterUnlinkExternalAuthRequest,
|
||||
}
|
||||
export { onRecordsListRequest, fireRecordsListRequest }
|
||||
export { onRecordViewRequest, fireRecordViewRequest }
|
||||
export { onRecordBeforeCreateRequest, fireRecordBeforeCreateRequest }
|
||||
export { onRecordAfterCreateRequest, fireRecordAfterCreateRequest }
|
||||
export { onRecordBeforeUpdateRequest, fireRecordBeforeUpdateRequest }
|
||||
export { onRecordAfterUpdateRequest, fireRecordAfterUpdateRequest }
|
||||
export { onRecordBeforeDeleteRequest, fireRecordBeforeDeleteRequest }
|
||||
export { onRecordAfterDeleteRequest, fireRecordAfterDeleteRequest }
|
||||
export { onCollectionsListRequest, fireCollectionsListRequest }
|
||||
export { onCollectionViewRequest, fireCollectionViewRequest }
|
||||
export { onCollectionBeforeCreateRequest, fireCollectionBeforeCreateRequest }
|
||||
export { onCollectionAfterCreateRequest, fireCollectionAfterCreateRequest }
|
||||
export { onCollectionBeforeUpdateRequest, fireCollectionBeforeUpdateRequest }
|
||||
export { onCollectionAfterUpdateRequest, fireCollectionAfterUpdateRequest }
|
||||
export { onCollectionBeforeDeleteRequest, fireCollectionBeforeDeleteRequest }
|
||||
export { onCollectionAfterDeleteRequest, fireCollectionAfterDeleteRequest }
|
||||
export { onCollectionsBeforeImportRequest, fireCollectionsBeforeImportRequest }
|
||||
export { onCollectionsAfterImportRequest, fireCollectionsAfterImportRequest }
|
||||
export { onBeforeServe, fireBeforeServe }
|
||||
|
||||
// OnModelAfterCreate hook is triggered after successfully
|
||||
// inserting a new entry in the DB.
|
||||
export type ModelAfterCreateEvent = {}
|
||||
const [onModelAfterCreate, fireModelAfterCreate] =
|
||||
createEvent<ModelAfterCreateEvent>(`OnModelAfterCreate`)
|
||||
|
||||
// OnModelBeforeUpdate hook is triggered before updating existing
|
||||
// entry in the DB, allowing you to modify or validate the stored data.
|
||||
export type ModelBeforeUpdateEvent = {}
|
||||
const [onModelBeforeUpdate, fireModelBeforeUpdate] =
|
||||
createEvent<ModelBeforeUpdateEvent>(`OnModelBeforeUpdate`)
|
||||
|
||||
// OnModelAfterUpdate hook is triggered after successfully updating
|
||||
// existing entry in the DB.
|
||||
export type ModelAfterUpdateEvent = {}
|
||||
const [onModelAfterUpdate, fireModelAfterUpdate] =
|
||||
createEvent<ModelAfterUpdateEvent>(`OnModelAfterUpdate`)
|
||||
|
||||
// OnModelBeforeDelete hook is triggered before deleting an
|
||||
// existing entry from the DB.
|
||||
export type ModelBeforeDeleteEvent = {}
|
||||
const [onModelBeforeDelete, fireModelBeforeDelete] =
|
||||
createEvent<ModelBeforeDeleteEvent>(`OnModelBeforeDelete`)
|
||||
|
||||
// OnModelAfterDelete is triggered after successfully deleting an
|
||||
// existing entry from the DB.
|
||||
export type ModelAfterDeleteEvent = {}
|
||||
const [onModelAfterDelete, fireModelAfterDelete] =
|
||||
createEvent<ModelAfterDeleteEvent>(`OnModelAfterDelete`)
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Mailer event hooks
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
// OnMailerBeforeAdminResetPasswordSend hook is triggered right before
|
||||
// sending a password reset email to an admin.
|
||||
//
|
||||
// Could be used to send your own custom email template if
|
||||
// [hook.StopPropagation] is returned in one of its listeners.
|
||||
export type MailerBeforeAdminResetPasswordSendEvent = {}
|
||||
const [
|
||||
onMailerBeforeAdminResetPasswordSend,
|
||||
fireMailerBeforeAdminResetPasswordSend,
|
||||
] = createEvent<MailerBeforeAdminResetPasswordSendEvent>(
|
||||
`OnMailerBeforeAdminResetPasswordSend`
|
||||
)
|
||||
|
||||
// OnMailerAfterAdminResetPasswordSend hook is triggered after
|
||||
// admin password reset email was successfully sent.
|
||||
export type MailerAfterAdminResetPasswordSendEvent = {}
|
||||
const [
|
||||
onMailerAfterAdminResetPasswordSend,
|
||||
fireMailerAfterAdminResetPasswordSend,
|
||||
] = createEvent<MailerAfterAdminResetPasswordSendEvent>(
|
||||
`OnMailerBeforeAdminResetPasswordSend`
|
||||
)
|
||||
|
||||
// OnMailerBeforeUserResetPasswordSend hook is triggered right before
|
||||
// sending a password reset email to a user.
|
||||
//
|
||||
// Could be used to send your own custom email template if
|
||||
// [hook.StopPropagation] is returned in one of its listeners.
|
||||
export type MailerBeforeUserResetPasswordSendEvent = {}
|
||||
const [
|
||||
onMailerBeforeUserResetPasswordSend,
|
||||
fireMailerBeforeUserResetPasswordSend,
|
||||
] = createEvent<MailerBeforeUserResetPasswordSendEvent>(
|
||||
`OnMailerBeforeUserResetPasswordSend`
|
||||
)
|
||||
|
||||
// OnMailerAfterUserResetPasswordSend hook is triggered after
|
||||
// a user password reset email was successfully sent.
|
||||
export type MailerAfterUserResetPasswordSendEvent = {}
|
||||
const [
|
||||
onMailerAfterUserResetPasswordSend,
|
||||
fireMailerAfterUserResetPasswordSend,
|
||||
] = createEvent<MailerAfterUserResetPasswordSendEvent>(
|
||||
`OnMailerAfterUserResetPasswordSend`
|
||||
)
|
||||
|
||||
// OnMailerBeforeUserVerificationSend hook is triggered right before
|
||||
// sending a verification email to a user.
|
||||
//
|
||||
// Could be used to send your own custom email template if
|
||||
// [hook.StopPropagation] is returned in one of its listeners.
|
||||
export type MailerBeforeUserVerificationSendEvent = {}
|
||||
const [
|
||||
onMailerBeforeUserVerificationSend,
|
||||
fireMailerBeforeUserVerificationSend,
|
||||
] = createEvent<MailerBeforeUserVerificationSendEvent>(
|
||||
`OnMailerBeforeUserVerificationSend`
|
||||
)
|
||||
|
||||
// OnMailerAfterUserVerificationSend hook is triggered after a user
|
||||
// verification email was successfully sent.
|
||||
export type MailerAfterUserVerificationSendEvent = {}
|
||||
const [onMailerAfterUserVerificationSend, fireMailerAfterUserVerificationSend] =
|
||||
createEvent<MailerAfterUserVerificationSendEvent>(
|
||||
`OnMailerAfterUserVerificationSend`
|
||||
)
|
||||
|
||||
// OnMailerBeforeUserChangeEmailSend hook is triggered right before
|
||||
// sending a confirmation new address email to a a user.
|
||||
//
|
||||
// Could be used to send your own custom email template if
|
||||
// [hook.StopPropagation] is returned in one of its listeners.
|
||||
export type MailerBeforeUserChangeEmailSendEvent = {}
|
||||
const [onMailerBeforeUserChangeEmailSend, fireMailerBeforeUserChangeEmailSend] =
|
||||
createEvent<MailerBeforeUserChangeEmailSendEvent>(
|
||||
`OnMailerBeforeUserChangeEmailSend`
|
||||
)
|
||||
|
||||
// OnMailerAfterUserChangeEmailSend hook is triggered after a user
|
||||
// change address email was successfully sent.
|
||||
export type MailerAfterUserChangeEmailSendEvent = {}
|
||||
const [onMailerAfterUserChangeEmailSend, fireMailerAfterUserChangeEmailSend] =
|
||||
createEvent<MailerAfterUserChangeEmailSendEvent>(
|
||||
`OnMailerAfterUserChangeEmailSend`
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Realtime API event hooks
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
// OnRealtimeConnectRequest hook is triggered right before establishing
|
||||
// the SSE client connection.
|
||||
export type RealtimeConnectRequestEvent = {}
|
||||
const [onRealtimeConnectRequest, fireRealtimeConnectRequest] =
|
||||
createEvent<RealtimeConnectRequestEvent>(`OnRealtimeConnectRequest`)
|
||||
|
||||
// OnRealtimeBeforeSubscribeRequest hook is triggered before changing
|
||||
// the client subscriptions, allowing you to further validate and
|
||||
// modify the submitted change.
|
||||
export type RealtimeBeforeSubscribeRequestEvent = {}
|
||||
const [onRealtimeBeforeSubscribeRequest, fireRealtimeBeforeSubscribeRequest] =
|
||||
createEvent<RealtimeBeforeSubscribeRequestEvent>(
|
||||
`OnRealtimeBeforeSubscribeRequest`
|
||||
)
|
||||
|
||||
// OnRealtimeAfterSubscribeRequest hook is triggered after the client
|
||||
// subscriptions were successfully changed.
|
||||
export type RealtimeAfterSubscribeRequestEvent = {}
|
||||
const [onRealtimeAfterSubscribeRequest, fireRealtimeAfterSubscribeRequest] =
|
||||
createEvent<RealtimeAfterSubscribeRequestEvent>(
|
||||
`OnRealtimeAfterSubscribeRequest`
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Settings API event hooks
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
// OnSettingsListRequest hook is triggered on each successful
|
||||
// API Settings list request.
|
||||
//
|
||||
// Could be used to validate or modify the response before
|
||||
// returning it to the client.
|
||||
export type SettingsListRequestEvent = {}
|
||||
const [onSettingsListRequest, fireSettingsListRequest] =
|
||||
createEvent<SettingsListRequestEvent>(`OnSettingsListRequest`)
|
||||
|
||||
// OnSettingsBeforeUpdateRequest hook is triggered before each API
|
||||
// Settings update request (after request data load and before settings persistence).
|
||||
//
|
||||
// Could be used to additionally validate the request data or
|
||||
// implement completely different persistence behavior
|
||||
// (returning [hook.StopPropagation]).
|
||||
export type SettingsBeforeUpdateRequestEvent = {}
|
||||
const [onSettingsBeforeUpdateRequest, fireSettingsBeforeUpdateRequest] =
|
||||
createEvent<SettingsBeforeUpdateRequestEvent>(`OnSettingsBeforeUpdateRequest`)
|
||||
|
||||
// OnSettingsAfterUpdateRequest hook is triggered after each
|
||||
// successful API Settings update request.
|
||||
export type SettingsAfterUpdateRequestEvent = {}
|
||||
const [onSettingsAfterUpdateRequest, fireSettingsAfterUpdateRequest] =
|
||||
createEvent<SettingsAfterUpdateRequestEvent>(`OnSettingsAfterUpdateRequest`)
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// File API event hooks
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
// OnFileDownloadRequest hook is triggered before each API File download request.
|
||||
//
|
||||
// Could be used to validate or modify the file response before
|
||||
// returning it to the client.
|
||||
export type FileDownloadRequestEvent = {}
|
||||
const [onFileDownloadRequest, fireFileDownloadRequest] =
|
||||
createEvent<FileDownloadRequestEvent>(`OnFileDownloadRequest`)
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Admin API event hooks
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
// OnAdminsListRequest hook is triggered on each API Admins list request.
|
||||
//
|
||||
// Could be used to validate or modify the response before returning it to the client.
|
||||
export type AdminsListRequestEvent = {}
|
||||
const [onAdminsListRequest, fireAdminsListRequest] =
|
||||
createEvent<AdminsListRequestEvent>(`OnAdminsListRequest`)
|
||||
|
||||
// OnAdminViewRequest hook is triggered on each API Admin view request.
|
||||
//
|
||||
// Could be used to validate or modify the response before returning it to the client.
|
||||
export type AdminViewRequestEvent = {}
|
||||
const [onAdminViewRequest, fireAdminViewRequest] =
|
||||
createEvent<AdminViewRequestEvent>(`OnAdminViewRequest`)
|
||||
|
||||
// OnAdminBeforeCreateRequest hook is triggered before each API
|
||||
// Admin create request (after request data load and before model persistence).
|
||||
//
|
||||
// Could be used to additionally validate the request data or implement
|
||||
// completely different persistence behavior (returning [hook.StopPropagation]).
|
||||
export type AdminBeforeCreateRequestEvent = {}
|
||||
const [onAdminBeforeCreateRequest, fireAdminBeforeCreateRequest] =
|
||||
createEvent<AdminBeforeCreateRequestEvent>(`OnAdminBeforeCreateRequest`)
|
||||
|
||||
// OnAdminAfterCreateRequest hook is triggered after each
|
||||
// successful API Admin create request.
|
||||
export type AdminAfterCreateRequestEvent = {}
|
||||
const [onAdminAfterCreateRequest, fireAdminAfterCreateRequest] =
|
||||
createEvent<AdminAfterCreateRequestEvent>(`OnAdminAfterCreateRequest`)
|
||||
|
||||
// OnAdminBeforeUpdateRequest hook is triggered before each API
|
||||
// Admin update request (after request data load and before model persistence).
|
||||
//
|
||||
// Could be used to additionally validate the request data or implement
|
||||
// completely different persistence behavior (returning [hook.StopPropagation]).
|
||||
export type AdminBeforeUpdateRequestEvent = {}
|
||||
const [onAdminBeforeUpdateRequest, fireAdminBeforeUpdateRequest] =
|
||||
createEvent<AdminBeforeUpdateRequestEvent>(`OnAdminBeforeUpdateRequest`)
|
||||
|
||||
// OnAdminAfterUpdateRequest hook is triggered after each
|
||||
// successful API Admin update request.
|
||||
export type AdminAfterUpdateRequestEvent = {}
|
||||
const [onAdminAfterUpdateRequest, fireAdminAfterUpdateRequest] =
|
||||
createEvent<AdminAfterUpdateRequestEvent>(`OnAdminAfterUpdateRequest`)
|
||||
|
||||
// OnAdminBeforeDeleteRequest hook is triggered before each API
|
||||
// Admin delete request (after model load and before actual deletion).
|
||||
//
|
||||
// Could be used to additionally validate the request data or implement
|
||||
// completely different delete behavior (returning [hook.StopPropagation]).
|
||||
export type AdminBeforeDeleteRequestEvent = {}
|
||||
const [onAdminBeforeDeleteRequest, fireAdminBeforeDeleteRequest] =
|
||||
createEvent<AdminBeforeDeleteRequestEvent>(`OnAdminBeforeDeleteRequest`)
|
||||
|
||||
// OnAdminAfterDeleteRequest hook is triggered after each
|
||||
// successful API Admin delete request.
|
||||
export type AdminAfterDeleteRequestEvent = {}
|
||||
const [onAdminAfterDeleteRequest, fireAdminAfterDeleteRequest] =
|
||||
createEvent<AdminAfterDeleteRequestEvent>(`OnAdminAfterDeleteRequest`)
|
||||
|
||||
// OnAdminAuthRequest hook is triggered on each successful API Admin
|
||||
// authentication request (sign-in, token refresh, etc.).
|
||||
//
|
||||
// Could be used to additionally validate or modify the
|
||||
// authenticated admin data and token.
|
||||
export type AdminAuthRequestEvent = {}
|
||||
const [onAdminAuthRequest, fireAdminAuthRequest] =
|
||||
createEvent<AdminAuthRequestEvent>(`OnAdminAuthRequest`)
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// User API event hooks
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
// OnUsersListRequest hook is triggered on each API Users list request.
|
||||
//
|
||||
// Could be used to validate or modify the response before returning it to the client.
|
||||
export type UsersListRequestEvent = {}
|
||||
const [onUsersListRequest, fireUsersListRequest] =
|
||||
createEvent<UsersListRequestEvent>(`OnUsersListRequest`)
|
||||
|
||||
// OnUserViewRequest hook is triggered on each API User view request.
|
||||
//
|
||||
// Could be used to validate or modify the response before returning it to the client.
|
||||
export type UserViewRequestEvent = {}
|
||||
const [onUserViewRequest, fireUserViewRequest] =
|
||||
createEvent<UserViewRequestEvent>(`OnUserViewRequest`)
|
||||
|
||||
// OnUserBeforeCreateRequest hook is triggered before each API User
|
||||
// create request (after request data load and before model persistence).
|
||||
//
|
||||
// Could be used to additionally validate the request data or implement
|
||||
// completely different persistence behavior (returning [hook.StopPropagation]).
|
||||
export type UserBeforeCreateRequestEvent = {}
|
||||
const [onUserBeforeCreateRequest, fireUserBeforeCreateRequest] =
|
||||
createEvent<UserBeforeCreateRequestEvent>(`OnUserBeforeCreateRequest`)
|
||||
|
||||
// OnUserAfterCreateRequest hook is triggered after each
|
||||
// successful API User create request.
|
||||
export type UserAfterCreateRequestEvent = {}
|
||||
const [onUserAfterCreateRequest, fireUserAfterCreateRequest] =
|
||||
createEvent<UserAfterCreateRequestEvent>(`OnUserAfterCreateRequest`)
|
||||
|
||||
// OnUserBeforeUpdateRequest hook is triggered before each API User
|
||||
// update request (after request data load and before model persistence).
|
||||
//
|
||||
// Could be used to additionally validate the request data or implement
|
||||
// completely different persistence behavior (returning [hook.StopPropagation]).
|
||||
export type UserBeforeUpdateRequestEvent = {}
|
||||
const [onUserBeforeUpdateRequest, fireUserBeforeUpdateRequest] =
|
||||
createEvent<UserBeforeUpdateRequestEvent>(`OnUserBeforeUpdateRequest`)
|
||||
|
||||
// OnUserAfterUpdateRequest hook is triggered after each
|
||||
// successful API User update request.
|
||||
export type UserAfterUpdateRequestEvent = {}
|
||||
const [onUserAfterUpdateRequest, fireUserAfterUpdateRequest] =
|
||||
createEvent<UserAfterUpdateRequestEvent>(`OnUserAfterUpdateRequest`)
|
||||
|
||||
// OnUserBeforeDeleteRequest hook is triggered before each API User
|
||||
// delete request (after model load and before actual deletion).
|
||||
//
|
||||
// Could be used to additionally validate the request data or implement
|
||||
// completely different delete behavior (returning [hook.StopPropagation]).
|
||||
export type UserBeforeDeleteRequestEvent = {}
|
||||
const [onUserBeforeDeleteRequest, fireUserBeforeDeleteRequest] =
|
||||
createEvent<UserBeforeDeleteRequestEvent>(`OnUserBeforeDeleteRequest`)
|
||||
|
||||
// OnUserAfterDeleteRequest hook is triggered after each
|
||||
// successful API User delete request.
|
||||
export type UserAfterDeleteRequestEvent = {}
|
||||
const [onUserAfterDeleteRequest, fireUserAfterDeleteRequest] =
|
||||
createEvent<UserAfterDeleteRequestEvent>(`OnUserAfterDeleteRequest`)
|
||||
|
||||
// OnUserAuthRequest hook is triggered on each successful API User
|
||||
// authentication request (sign-in, token refresh, etc.).
|
||||
//
|
||||
// Could be used to additionally validate or modify the
|
||||
// authenticated user data and token.
|
||||
export type UserAuthRequestEvent = {}
|
||||
const [onUserAuthRequest, fireUserAuthRequest] =
|
||||
createEvent<UserAuthRequestEvent>(`OnUserAuthRequest`)
|
||||
|
||||
// OnUserListExternalAuths hook is triggered on each API user's external auths list request.
|
||||
//
|
||||
// Could be used to validate or modify the response before returning it to the client.
|
||||
export type UserListExternalAuthsEvent = {}
|
||||
const [onUserListExternalAuths, fireUserListExternalAuths] =
|
||||
createEvent<UserListExternalAuthsEvent>(`OnUserListExternalAuths`)
|
||||
|
||||
// OnUserBeforeUnlinkExternalAuthRequest hook is triggered before each API user's
|
||||
// external auth unlink request (after models load and before the actual relation deletion).
|
||||
//
|
||||
// Could be used to additionally validate the request data or implement
|
||||
// completely different delete behavior (returning [hook.StopPropagation]).
|
||||
export type UserBeforeUnlinkExternalAuthRequestEvent = {}
|
||||
const [
|
||||
onUserBeforeUnlinkExternalAuthRequest,
|
||||
fireUserBeforeUnlinkExternalAuthRequest,
|
||||
] = createEvent<UserBeforeUnlinkExternalAuthRequestEvent>(
|
||||
`OnUserBeforeUnlinkExternalAuthRequest`
|
||||
)
|
||||
|
||||
// OnUserAfterUnlinkExternalAuthRequest hook is triggered after each
|
||||
// successful API user's external auth unlink request.
|
||||
export type UserAfterUnlinkExternalAuthRequestEvent = {}
|
||||
const [
|
||||
onUserAfterUnlinkExternalAuthRequest,
|
||||
fireUserAfterUnlinkExternalAuthRequest,
|
||||
] = createEvent<UserAfterUnlinkExternalAuthRequestEvent>(
|
||||
`OnUserAfterUnlinkExternalAuthRequest`
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Record API event hooks
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
// OnRecordsListRequest hook is triggered on each API Records list request.
|
||||
//
|
||||
// Could be used to validate or modify the response before returning it to the client.
|
||||
export type RecordsListRequestEvent = {}
|
||||
const [onRecordsListRequest, fireRecordsListRequest] =
|
||||
createEvent<RecordsListRequestEvent>(`OnRecordsListRequest`)
|
||||
|
||||
// OnRecordViewRequest hook is triggered on each API Record view request.
|
||||
//
|
||||
// Could be used to validate or modify the response before returning it to the client.
|
||||
export type RecordViewRequestEvent = {}
|
||||
const [onRecordViewRequest, fireRecordViewRequest] =
|
||||
createEvent<RecordViewRequestEvent>(`OnRecordViewRequest`)
|
||||
|
||||
// OnRecordBeforeCreateRequest hook is triggered before each API Record
|
||||
// create request (after request data load and before model persistence).
|
||||
//
|
||||
// Could be used to additionally validate the request data or implement
|
||||
// completely different persistence behavior (returning [hook.StopPropagation]).
|
||||
export type RecordBeforeCreateRequestEvent = {}
|
||||
const [onRecordBeforeCreateRequest, fireRecordBeforeCreateRequest] =
|
||||
createEvent<RecordBeforeCreateRequestEvent>(`OnRecordBeforeCreateRequest`)
|
||||
|
||||
// OnRecordAfterCreateRequest hook is triggered after each
|
||||
// successful API Record create request.
|
||||
export type RecordAfterCreateRequestEvent = {}
|
||||
const [onRecordAfterCreateRequest, fireRecordAfterCreateRequest] =
|
||||
createEvent<RecordAfterCreateRequestEvent>(`OnRecordAfterCreateRequest`)
|
||||
|
||||
// OnRecordBeforeUpdateRequest hook is triggered before each API Record
|
||||
// update request (after request data load and before model persistence).
|
||||
//
|
||||
// Could be used to additionally validate the request data or implement
|
||||
// completely different persistence behavior (returning [hook.StopPropagation]).
|
||||
export type RecordBeforeUpdateRequestEvent = {}
|
||||
const [onRecordBeforeUpdateRequest, fireRecordBeforeUpdateRequest] =
|
||||
createEvent<RecordBeforeUpdateRequestEvent>(`OnRecordBeforeUpdateRequest`)
|
||||
|
||||
// OnRecordAfterUpdateRequest hook is triggered after each
|
||||
// successful API Record update request.
|
||||
export type RecordAfterUpdateRequestEvent = {}
|
||||
const [onRecordAfterUpdateRequest, fireRecordAfterUpdateRequest] =
|
||||
createEvent<RecordAfterUpdateRequestEvent>(`OnRecordAfterUpdateRequest`)
|
||||
|
||||
// OnRecordBeforeDeleteRequest hook is triggered before each API Record
|
||||
// delete request (after model load and before actual deletion).
|
||||
//
|
||||
// Could be used to additionally validate the request data or implement
|
||||
// completely different delete behavior (returning [hook.StopPropagation]).
|
||||
export type RecordBeforeDeleteRequestEvent = {}
|
||||
const [onRecordBeforeDeleteRequest, fireRecordBeforeDeleteRequest] =
|
||||
createEvent<RecordBeforeDeleteRequestEvent>(`OnRecordBeforeDeleteRequest`)
|
||||
|
||||
// OnRecordAfterDeleteRequest hook is triggered after each
|
||||
// successful API Record delete request.
|
||||
export type RecordAfterDeleteRequestEvent = {}
|
||||
const [onRecordAfterDeleteRequest, fireRecordAfterDeleteRequest] =
|
||||
createEvent<RecordAfterDeleteRequestEvent>(`OnRecordAfterDeleteRequest`)
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Collection API event hooks
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
// OnCollectionsListRequest hook is triggered on each API Collections list request.
|
||||
//
|
||||
// Could be used to validate or modify the response before returning it to the client.
|
||||
export type CollectionsListRequestEvent = {}
|
||||
const [onCollectionsListRequest, fireCollectionsListRequest] =
|
||||
createEvent<CollectionsListRequestEvent>(`OnCollectionsListRequest`)
|
||||
|
||||
// OnCollectionViewRequest hook is triggered on each API Collection view request.
|
||||
//
|
||||
// Could be used to validate or modify the response before returning it to the client.
|
||||
export type CollectionViewRequestEvent = {}
|
||||
const [onCollectionViewRequest, fireCollectionViewRequest] =
|
||||
createEvent<CollectionViewRequestEvent>(`OnCollectionViewRequest`)
|
||||
|
||||
// OnCollectionBeforeCreateRequest hook is triggered before each API Collection
|
||||
// create request (after request data load and before model persistence).
|
||||
//
|
||||
// Could be used to additionally validate the request data or implement
|
||||
// completely different persistence behavior (returning [hook.StopPropagation]).
|
||||
export type CollectionBeforeCreateRequestEvent = {}
|
||||
const [onCollectionBeforeCreateRequest, fireCollectionBeforeCreateRequest] =
|
||||
createEvent<CollectionBeforeCreateRequestEvent>(
|
||||
`OnCollectionBeforeCreateRequest`
|
||||
)
|
||||
|
||||
// OnCollectionAfterCreateRequest hook is triggered after each
|
||||
// successful API Collection create request.
|
||||
export type CollectionAfterCreateRequestEvent = {}
|
||||
const [onCollectionAfterCreateRequest, fireCollectionAfterCreateRequest] =
|
||||
createEvent<CollectionAfterCreateRequestEvent>(
|
||||
`OnCollectionAfterCreateRequest`
|
||||
)
|
||||
|
||||
// OnCollectionBeforeUpdateRequest hook is triggered before each API Collection
|
||||
// update request (after request data load and before model persistence).
|
||||
//
|
||||
// Could be used to additionally validate the request data or implement
|
||||
// completely different persistence behavior (returning [hook.StopPropagation]).
|
||||
export type CollectionBeforeUpdateRequestEvent = {}
|
||||
const [onCollectionBeforeUpdateRequest, fireCollectionBeforeUpdateRequest] =
|
||||
createEvent<CollectionBeforeUpdateRequestEvent>(
|
||||
`OnCollectionBeforeUpdateRequest`
|
||||
)
|
||||
|
||||
// OnCollectionAfterUpdateRequest hook is triggered after each
|
||||
// successful API Collection update request.
|
||||
export type CollectionAfterUpdateRequestEvent = {}
|
||||
const [onCollectionAfterUpdateRequest, fireCollectionAfterUpdateRequest] =
|
||||
createEvent<CollectionAfterUpdateRequestEvent>(
|
||||
`OnCollectionAfterUpdateRequest`
|
||||
)
|
||||
|
||||
// OnCollectionBeforeDeleteRequest hook is triggered before each API
|
||||
// Collection delete request (after model load and before actual deletion).
|
||||
//
|
||||
// Could be used to additionally validate the request data or implement
|
||||
// completely different delete behavior (returning [hook.StopPropagation]).
|
||||
export type CollectionBeforeDeleteRequestEvent = {}
|
||||
const [onCollectionBeforeDeleteRequest, fireCollectionBeforeDeleteRequest] =
|
||||
createEvent<CollectionBeforeDeleteRequestEvent>(
|
||||
`OnCollectionBeforeDeleteRequest`
|
||||
)
|
||||
|
||||
// OnCollectionAfterDeleteRequest hook is triggered after each
|
||||
// successful API Collection delete request.
|
||||
export type CollectionAfterDeleteRequestEvent = {}
|
||||
const [onCollectionAfterDeleteRequest, fireCollectionAfterDeleteRequest] =
|
||||
createEvent<CollectionAfterDeleteRequestEvent>(
|
||||
`OnCollectionAfterDeleteRequest`
|
||||
)
|
||||
|
||||
// OnCollectionsBeforeImportRequest hook is triggered before each API
|
||||
// collections import request (after request data load and before the actual import).
|
||||
//
|
||||
// Could be used to additionally validate the imported collections or
|
||||
// to implement completely different import behavior (returning [hook.StopPropagation]).
|
||||
export type CollectionsBeforeImportRequestEvent = {}
|
||||
const [onCollectionsBeforeImportRequest, fireCollectionsBeforeImportRequest] =
|
||||
createEvent<CollectionsBeforeImportRequestEvent>(
|
||||
`OnCollectionsBeforeImportRequest`
|
||||
)
|
||||
|
||||
// OnCollectionsAfterImportRequest hook is triggered after each
|
||||
// successful API collections import request.
|
||||
export type CollectionsAfterImportRequestEvent = {}
|
||||
const [onCollectionsAfterImportRequest, fireCollectionsAfterImportRequest] =
|
||||
createEvent<CollectionsAfterImportRequestEvent>(
|
||||
`OnCollectionsAfterImportRequest`
|
||||
)
|
||||
|
||||
export type BeforeServeEvent = {}
|
||||
const [onBeforeServe, fireBeforeServe] =
|
||||
createEvent<BeforeServeEvent>(`OnBeforeServe`)
|
@ -1,11 +0,0 @@
|
||||
export * from './routes'
|
||||
export * from './transaction'
|
||||
export * from './types'
|
||||
|
||||
import { PBScriptApi } from './types/PBScriptApi'
|
||||
|
||||
const api: PBScriptApi = {
|
||||
ping: () => 'Hello from PBScript!',
|
||||
}
|
||||
|
||||
registerJsFuncs(api)
|
@ -1,71 +0,0 @@
|
||||
import {
|
||||
EchoHttpMethods,
|
||||
EchoHttpResponseStatuses,
|
||||
EchoMiddlewareFunc,
|
||||
EchoRoute,
|
||||
User,
|
||||
} from './types'
|
||||
|
||||
export type HandlerApi = {
|
||||
ok: (s: string) => void
|
||||
error: (s: string) => void
|
||||
user: () => User
|
||||
}
|
||||
|
||||
export type HandlerFunc = (api: HandlerApi) => void
|
||||
|
||||
export type Route = {
|
||||
method: EchoHttpMethods
|
||||
path: string
|
||||
handler: HandlerFunc
|
||||
middlewares: EchoMiddlewareFunc[]
|
||||
}
|
||||
|
||||
export const addRoute = (route: Route) => {
|
||||
// Ensure path begins with `/api/`
|
||||
const { path } = route
|
||||
if (!path.startsWith(`/api/`)) {
|
||||
console.log(`API error ${path}`)
|
||||
throw new Error(`All routes must take the form /api/<path...>`)
|
||||
}
|
||||
|
||||
const _route: EchoRoute = {
|
||||
method: route.method,
|
||||
path: route.path,
|
||||
handler: (c) => {
|
||||
const api: HandlerApi = {
|
||||
ok: (message) => {
|
||||
c.string(EchoHttpResponseStatuses.Ok, message)
|
||||
},
|
||||
error: (message) => {
|
||||
c.string(EchoHttpResponseStatuses.Error, message)
|
||||
},
|
||||
user: () => c.get<User>('user'),
|
||||
}
|
||||
route.handler(api)
|
||||
},
|
||||
middlewares: route.middlewares,
|
||||
}
|
||||
return __go.addRoute(_route)
|
||||
}
|
||||
|
||||
export const auth = __go.requireAdminOrUserAuth()
|
||||
|
||||
export const get = (
|
||||
path: string,
|
||||
handler: HandlerFunc,
|
||||
middlewares?: EchoMiddlewareFunc[]
|
||||
) => {
|
||||
addRoute({
|
||||
method: EchoHttpMethods.Get,
|
||||
path: `/api${path}`,
|
||||
handler: (api) => {
|
||||
try {
|
||||
handler(api)
|
||||
} catch (e) {
|
||||
api.error(`${e}`)
|
||||
}
|
||||
},
|
||||
middlewares: middlewares || [],
|
||||
})
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
export type TransactionApi = {
|
||||
execute: (sql: string) => void
|
||||
all: <TRow>(sql: string) => TRow[]
|
||||
one: <TRow>(sql: string) => TRow
|
||||
}
|
||||
|
||||
export type TransactionCallback = (api: TransactionApi) => void
|
||||
|
||||
export const runInTransaction = (cb: TransactionCallback) => {
|
||||
__go.app.dao().runInTransaction((txDao) => {
|
||||
const execute = (sql: string) => {
|
||||
const q = txDao.dB().newQuery(sql)
|
||||
return q.execute()
|
||||
}
|
||||
const all = <TRow>(sql: string): TRow[] => {
|
||||
const q = txDao.dB().newQuery(sql)
|
||||
const rowPtr = __go.newNullStringMapArrayPtr<TRow>()
|
||||
q.all(rowPtr)
|
||||
console.log({ rowPtr })
|
||||
return []
|
||||
}
|
||||
const one = <TRow>(sql: string): TRow => {
|
||||
const q = txDao.dB().newQuery(sql)
|
||||
const row = __go.newNullStringMap<TRow>()
|
||||
q.one(row)
|
||||
return row
|
||||
}
|
||||
|
||||
const api: TransactionApi = {
|
||||
execute,
|
||||
all,
|
||||
one,
|
||||
}
|
||||
cb(api)
|
||||
})
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
export type ConsoleApi = {
|
||||
log: (...args: any) => void
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
import { Dao } from './go-namespaces/Dao'
|
||||
import { EchoMiddlewareFunc, EchoRoute } from './go-namespaces/Echo'
|
||||
|
||||
export type GoApi = {
|
||||
app: {
|
||||
dao: () => Dao
|
||||
}
|
||||
addRoute: (route: EchoRoute) => void
|
||||
ping: () => string
|
||||
onModelBeforeCreate: any
|
||||
requireAdminAuth: () => EchoMiddlewareFunc
|
||||
requireAdminAuthOnlyIfAny: () => EchoMiddlewareFunc
|
||||
requireAdminOrOwnerAuth: () => EchoMiddlewareFunc
|
||||
requireAdminOrUserAuth: () => EchoMiddlewareFunc
|
||||
newNullStringMapArrayPtr: <TFields>() => TFields[]
|
||||
newNullStringMap: <TFields>() => TFields
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
export type PingResult = string
|
||||
export type PBScriptApi = {
|
||||
ping: () => PingResult
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
import { ConsoleApi } from './ConsoleApi'
|
||||
import { GoApi } from './GoApi'
|
||||
import { PBScriptApi } from './PBScriptApi'
|
||||
|
||||
declare global {
|
||||
let console: ConsoleApi
|
||||
function registerJsFuncs(api: PBScriptApi): void
|
||||
let __go: GoApi
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
import { IsoDate, RecordId, Url } from '.'
|
||||
|
||||
export type ProfileId = RecordId
|
||||
export type Email = string
|
||||
export type UserId = RecordId
|
||||
export type Token = string
|
||||
export type PasswordHash = string
|
||||
|
||||
export type User = {
|
||||
baseAccount: {
|
||||
baseModel: {
|
||||
id: UserId
|
||||
created: IsoDate
|
||||
updated: IsoDate
|
||||
}
|
||||
id: UserId
|
||||
created: IsoDate
|
||||
updated: IsoDate
|
||||
email: Email
|
||||
tokenKey: Token
|
||||
passwordHash: PasswordHash
|
||||
lastResetSentAt: IsoDate
|
||||
}
|
||||
baseModel: {
|
||||
id: UserId
|
||||
created: IsoDate
|
||||
updated: IsoDate
|
||||
}
|
||||
id: UserId
|
||||
created: IsoDate
|
||||
updated: IsoDate
|
||||
email: Email
|
||||
tokenKey: Token
|
||||
passwordHash: PasswordHash
|
||||
lastResetSentAt: IsoDate
|
||||
verified: boolean
|
||||
lastVerificationSentAt: IsoDate
|
||||
profile: {
|
||||
avatar: Url
|
||||
created: IsoDate
|
||||
|
||||
id: ProfileId
|
||||
name: string
|
||||
updated: IsoDate
|
||||
userId: UserId
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
export type RecordId = string
|
||||
export type IsoDate = string
|
||||
export type Url = string
|
||||
|
||||
export * from './User'
|
@ -1,9 +0,0 @@
|
||||
import { DbxBuilder } from './Dbx'
|
||||
|
||||
export type DaoTransactionCallback = (txDao: Dao) => void
|
||||
|
||||
export type Dao = {
|
||||
// https://pkg.go.dev/github.com/pocketbase/pocketbase@v0.7.9/daos
|
||||
runInTransaction: (cb: DaoTransactionCallback) => void
|
||||
dB: () => DbxBuilder
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
import { SqlResult } from './Sql'
|
||||
|
||||
export type DbxQuery = {
|
||||
// https://pkg.go.dev/github.com/pocketbase/dbx#Query
|
||||
// https://pkg.go.dev/github.com/pocketbase/dbx#Query.Execute
|
||||
execute: () => SqlResult
|
||||
all: <TRow>(rows: TRow[]) => void
|
||||
one: <TRow>(row: TRow) => void
|
||||
}
|
||||
|
||||
export type DbxBuilder = {
|
||||
// https://pkg.go.dev/github.com/pocketbase/dbx#Builder
|
||||
newQuery: (sql: string) => DbxQuery
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
export enum EchoHttpMethods {
|
||||
Get = 'GET',
|
||||
}
|
||||
|
||||
export enum EchoHttpResponseStatuses {
|
||||
Ok = 200,
|
||||
Error = 400,
|
||||
}
|
||||
|
||||
export type EchoHandlerFunc = (context: EchoContext) => void
|
||||
|
||||
export type EchoMiddlewareFunc = (next: EchoHandlerFunc) => EchoHandlerFunc
|
||||
|
||||
export type EchoContext = {
|
||||
get: <T>(key: string) => T
|
||||
string: (code: number, s: string) => void
|
||||
json: (status: EchoHttpResponseStatuses, data: object) => void
|
||||
}
|
||||
|
||||
export type EchoRoute = {
|
||||
method: EchoHttpMethods
|
||||
path: string
|
||||
handler: EchoHandlerFunc
|
||||
middlewares: EchoMiddlewareFunc[]
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
export type SqlResult = {
|
||||
// https://pkg.go.dev/database/sql#Result
|
||||
// statements varies.
|
||||
lastInsertId: () => number
|
||||
|
||||
// RowsAffected returns the number of rows affected by an
|
||||
// update, insert, or delete. Not every database or database
|
||||
// driver may support this.
|
||||
rowsAffected: () => number
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
export * from './Dao'
|
||||
export * from './Dbx'
|
||||
export * from './Echo'
|
||||
export * from './Sql'
|
@ -1,5 +0,0 @@
|
||||
export * from './database'
|
||||
export * from './go-namespaces'
|
||||
export * from './GoApi'
|
||||
export * from './PBScriptApi'
|
||||
export * from './__global'
|
@ -1,8 +0,0 @@
|
||||
export function assertExists<TType>(
|
||||
v: TType,
|
||||
message = `Value does not exist`
|
||||
): asserts v is NonNullable<TType> {
|
||||
if (typeof v === 'undefined') {
|
||||
throw new Error(message)
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
import { createNanoEvents } from 'nanoevents'
|
||||
|
||||
const emitter = createNanoEvents()
|
||||
|
||||
export type Event<TPayload extends any = void> = TPayload
|
||||
|
||||
export type EventListenerCallback<TEvent extends Event<any>> = (
|
||||
event: TEvent
|
||||
) => void
|
||||
|
||||
export type EventDispatcher<TEvent extends Event<any> = Event> = (
|
||||
event: TEvent
|
||||
) => void
|
||||
|
||||
export type EventUnsubscriber = () => void
|
||||
|
||||
export type EventSubscriber<TEvent extends Event<any>> = (
|
||||
callback: EventListenerCallback<TEvent>
|
||||
) => EventUnsubscriber
|
||||
|
||||
export const createEvent = <TEvent extends Event<any>>(
|
||||
eventName: string
|
||||
): [EventSubscriber<TEvent>, EventDispatcher<TEvent>] => {
|
||||
const fire: EventDispatcher<TEvent> = (event) => {
|
||||
emitter.emit(eventName, event)
|
||||
}
|
||||
|
||||
const listen: EventSubscriber<TEvent> = (cb) => {
|
||||
const unsub = emitter.on(eventName, cb)
|
||||
return unsub
|
||||
}
|
||||
|
||||
return [listen, fire]
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
export function isFunction(value: any) {
|
||||
return typeof value === 'function'
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"module": "ES2015",
|
||||
"moduleResolution": "node",
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"strictNullChecks": true,
|
||||
"typeRoots": ["./node_modules/@types"],
|
||||
"inlineSourceMap": true,
|
||||
"lib": ["ES2015"]
|
||||
},
|
||||
"include": ["./src"]
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name db.*;
|
||||
|
||||
access_log /data/nginx/access.log main;
|
||||
error_log /data/nginx/error.log;
|
||||
|
||||
location / {
|
||||
# check http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive
|
||||
proxy_set_header Connection '';
|
||||
proxy_http_version 1.1;
|
||||
proxy_read_timeout 180s;
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
proxy_pass http://127.0.0.1:8090;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name www.*;
|
||||
|
||||
access_log /data/nginx/access.log main;
|
||||
error_log /data/nginx/error.log;
|
||||
|
||||
location / {
|
||||
root /data/pockethost_html;
|
||||
index index.html index.htm;
|
||||
}
|
||||
|
||||
#error_page 404 /404.html;
|
||||
|
||||
# redirect server error pages to the static page /50x.html
|
||||
#
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /data/pockethost_html;
|
||||
}
|
||||
|
||||
# deny access to .htaccess files, if Apache's document root
|
||||
# concurs with nginx's one
|
||||
#
|
||||
#location ~ /\.ht {
|
||||
# deny all;
|
||||
#}
|
||||
}
|
||||
|
@ -1,16 +0,0 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name example.org;
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name example.org;
|
||||
|
||||
location / {
|
||||
proxy_pass http://example.org; #for demo purposes
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
user nginx;
|
||||
worker_processes auto;
|
||||
|
||||
error_log /var/log/nginx/error.log notice;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log /var/log/nginx/access.log main;
|
||||
|
||||
sendfile on;
|
||||
#tcp_nopush on;
|
||||
|
||||
keepalive_timeout 65;
|
||||
|
||||
#gzip on;
|
||||
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
}
|
||||
|
@ -1,39 +0,0 @@
|
||||
import EventSourceClass from 'eventsource'
|
||||
import PocketBase from 'pocketbase'
|
||||
|
||||
require('ssl-root-cas')
|
||||
.inject()
|
||||
.addFile(__dirname + '/packages/docker/src/nginx/ssl/ca.crt')
|
||||
|
||||
global.EventSource = EventSourceClass
|
||||
|
||||
const POCKETBASE_URL = 'https://able-actor.pockethost.test'
|
||||
const ADMIN_LOGIN = 'able-actor@benallfree.com'
|
||||
const ADMIN_PASSWORD = 'zpA6w9DXYYECj4Y'
|
||||
|
||||
if (!POCKETBASE_URL) {
|
||||
throw new Error(`POCKETBASE_URL must be defined.`)
|
||||
}
|
||||
|
||||
if (!ADMIN_LOGIN) {
|
||||
throw new Error(`ADMIN_LOGIN must be defined.`)
|
||||
}
|
||||
|
||||
if (!ADMIN_PASSWORD) {
|
||||
throw new Error(`ADMIN_PASSWORD must be defined.`)
|
||||
}
|
||||
|
||||
;(async () => {
|
||||
console.log(`Connecting to ${POCKETBASE_URL} with ${ADMIN_LOGIN}`)
|
||||
const client = new PocketBase(POCKETBASE_URL)
|
||||
try {
|
||||
await client.admins.authWithPassword(ADMIN_LOGIN, ADMIN_PASSWORD)
|
||||
console.log(`Successfully logged in.`)
|
||||
await client.collection('orders').subscribe('*', (data) => {
|
||||
console.log(`Got a data record`, data)
|
||||
})
|
||||
console.log(`Watching orders`)
|
||||
} catch (e) {
|
||||
console.error(e, JSON.stringify(e))
|
||||
}
|
||||
})()
|
@ -1,376 +0,0 @@
|
||||
package engine
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"unsafe"
|
||||
|
||||
"github.com/benallfree/pbscript/modules/pbscript/event"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
|
||||
"github.com/dop251/goja"
|
||||
"github.com/labstack/echo/v5"
|
||||
"github.com/pocketbase/dbx"
|
||||
"github.com/pocketbase/pocketbase"
|
||||
"github.com/pocketbase/pocketbase/apis"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
"github.com/pocketbase/pocketbase/daos"
|
||||
"github.com/pocketbase/pocketbase/models"
|
||||
"github.com/pocketbase/pocketbase/models/schema"
|
||||
)
|
||||
|
||||
var app *pocketbase.PocketBase
|
||||
var router *echo.Echo
|
||||
var vm *goja.Runtime
|
||||
var cleanups = []func(){}
|
||||
var __go_apis *goja.Object
|
||||
|
||||
const (
|
||||
colorReset = "\033[0m"
|
||||
colorRed = "\033[31m"
|
||||
colorGreen = "\033[32m"
|
||||
colorYellow = "\033[33m"
|
||||
colorBlue = "\033[34m"
|
||||
colorPurple = "\033[35m"
|
||||
colorCyan = "\033[36m"
|
||||
colorWhite = "\033[37m"
|
||||
)
|
||||
|
||||
func logErrorf(format string, args ...any) (n int, err error) {
|
||||
|
||||
s := append(args, string(colorReset))
|
||||
fmt.Print(colorRed)
|
||||
res, err := fmt.Printf(format, s...)
|
||||
fmt.Print(colorReset)
|
||||
return res, err
|
||||
}
|
||||
|
||||
func bindApis() {
|
||||
__go_apis = vm.NewObject()
|
||||
__go_apis.Set("addRoute", func(route echo.Route) {
|
||||
method := route.Method
|
||||
path := route.Path
|
||||
fmt.Printf("Adding route: %s %s\n", method, path)
|
||||
|
||||
router.AddRoute(route)
|
||||
cleanup(
|
||||
fmt.Sprintf("route %s %s", method, path),
|
||||
func() {
|
||||
router.Router().Remove(method, path)
|
||||
})
|
||||
})
|
||||
__go_apis.Set("onModelBeforeCreate", func(cb func(e *core.ModelEvent)) {
|
||||
fmt.Println("Listening in Go for onModelBeforeCreate")
|
||||
unsub := event.On(event.EVT_ON_MODEL_BEFORE_CREATE, func(e *event.UnknownPayload) {
|
||||
// fmt.Println("syntheticevent: OnModelBeforeCreate")
|
||||
// fmt.Println("e", e)
|
||||
// fmt.Println("cb", cb)
|
||||
cb((*core.ModelEvent)(unsafe.Pointer(e)))
|
||||
})
|
||||
cleanup("onModelBeforeCreate", unsub)
|
||||
})
|
||||
__go_apis.Set("onModelAfterCreate", func(cb func(e *core.ModelEvent)) {
|
||||
fmt.Println("Listening in Go for onModelAfterCreate")
|
||||
unsub := event.On(event.EVT_ON_MODEL_AFTER_CREATE, func(e *event.UnknownPayload) {
|
||||
// fmt.Println("syntheticevent: OnModelAfterCreate")
|
||||
// fmt.Println("e", e)
|
||||
// fmt.Println("cb", cb)
|
||||
cb((*core.ModelEvent)(unsafe.Pointer(e)))
|
||||
})
|
||||
cleanup("onModelAfterCreate", unsub)
|
||||
})
|
||||
|
||||
// type TransactionApi struct {
|
||||
// Execute func(sql string)
|
||||
// }
|
||||
// __go_apis.Set("withTransaction", func(cb func(e *TransactionApi)) {
|
||||
// app.Dao().RunInTransaction(func(txDao *daos.Dao) error {
|
||||
// var api = TransactionApi{
|
||||
// Execute: func(sql string) error {
|
||||
// res, err := txDao.DB().Select().NewQuery(sql).Execute()
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// }}
|
||||
// })
|
||||
|
||||
// })
|
||||
|
||||
__go_apis.Set("requireAdminAuth", apis.RequireAdminAuth)
|
||||
__go_apis.Set("requireAdminAuthOnlyIfAny", apis.RequireAdminAuthOnlyIfAny)
|
||||
__go_apis.Set("requireAdminOrOwnerAuth", apis.RequireAdminOrOwnerAuth)
|
||||
__go_apis.Set("requireAdminOrUserAuth", apis.RequireAdminOrUserAuth)
|
||||
__go_apis.Set("app", app)
|
||||
__go_apis.Set("ping", func() string {
|
||||
return "Hello from Go!"
|
||||
})
|
||||
__go_apis.Set("newNullStringMapArrayPtr", func() *[]dbx.NullStringMap {
|
||||
var users2 []dbx.NullStringMap
|
||||
return &users2
|
||||
})
|
||||
__go_apis.Set("newNullStringMap", func() dbx.NullStringMap {
|
||||
var users2 dbx.NullStringMap
|
||||
return users2
|
||||
})
|
||||
}
|
||||
|
||||
func cleanup(msg string, cb func()) {
|
||||
fmt.Printf("adding cleanup: %s\n", msg)
|
||||
cleanups = append(cleanups, func() {
|
||||
fmt.Printf("executing cleanup: %s\n", msg)
|
||||
cb()
|
||||
})
|
||||
}
|
||||
|
||||
func loadActiveScript() (string, error) {
|
||||
|
||||
collection, err := app.Dao().FindCollectionByNameOrId("pbscript")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
recs, err := app.Dao().FindRecordsByExpr(collection, dbx.HashExp{"type": "script", "isActive": true})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(recs) > 1 {
|
||||
return "", fmt.Errorf("expected one active script record but got %d", len(recs))
|
||||
}
|
||||
if len(recs) == 0 {
|
||||
return "", nil // Empty script
|
||||
}
|
||||
rec := recs[0]
|
||||
jsonData := rec.GetStringDataValue("data")
|
||||
type Data struct {
|
||||
Source string `json:"source"`
|
||||
}
|
||||
var json_map Data
|
||||
err = json.Unmarshal([]byte(jsonData), &json_map)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
script := json_map.Source
|
||||
fmt.Printf("Script has been loaded.\n")
|
||||
return script, nil
|
||||
|
||||
}
|
||||
|
||||
func reloadVm() error {
|
||||
fmt.Println("Initializing PBScript engine")
|
||||
vm = goja.New()
|
||||
vm.SetFieldNameMapper(goja.UncapFieldNameMapper())
|
||||
|
||||
// Clean up all handlers
|
||||
fmt.Println("Executing cleanups")
|
||||
for i := 0; i < len(cleanups); i++ {
|
||||
cleanups[i]()
|
||||
}
|
||||
cleanups = nil
|
||||
|
||||
// Load the main script
|
||||
fmt.Println("Loading JS")
|
||||
script, err := loadActiveScript()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Console proxy
|
||||
fmt.Println("Creating console proxy")
|
||||
console := vm.NewObject()
|
||||
console.Set("log", func(s ...goja.Value) {
|
||||
for _, v := range s {
|
||||
fmt.Printf("%s ", v.String())
|
||||
}
|
||||
fmt.Print("\n")
|
||||
})
|
||||
vm.Set("console", console)
|
||||
|
||||
fmt.Println("Creating apis proxy")
|
||||
bindApis()
|
||||
vm.Set("__go", __go_apis)
|
||||
|
||||
fmt.Println("Go initialization complete. Running script.")
|
||||
source := fmt.Sprintf(`
|
||||
console.log('Top of PBScript bootstrap')
|
||||
let __jsfuncs = {ping: ()=>'Hello from PBScript!'}
|
||||
function registerJsFuncs(funcs) {
|
||||
__jsfuncs = {__jsfuncs, ...funcs }
|
||||
}
|
||||
%s
|
||||
console.log('Pinging Go')
|
||||
console.log('Pinging Go succeeded with:', __go.ping())
|
||||
console.log('Bottom of PBScript bootstrap')
|
||||
`, script)
|
||||
_, err = vm.RunString(source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// js api wireup
|
||||
fmt.Println("Wiring up JS API")
|
||||
type S struct {
|
||||
Ping func() (string, *goja.Exception) `json:"ping"`
|
||||
}
|
||||
jsFuncs := S{}
|
||||
err = vm.ExportTo(vm.Get("__jsfuncs"), &jsFuncs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
{
|
||||
fmt.Println("Pinging JS")
|
||||
res, err := jsFuncs.Ping()
|
||||
if err != nil {
|
||||
return fmt.Errorf("ping() failed with %s", err.Value().Export())
|
||||
} else {
|
||||
fmt.Printf("Ping succeeded with: %s\n", res)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func migrate() error {
|
||||
fmt.Println("Finding collection")
|
||||
_, err := app.Dao().FindCollectionByNameOrId("anything")
|
||||
fmt.Println("Finished collection")
|
||||
if err != nil {
|
||||
err = app.Dao().SaveCollection(&models.Collection{
|
||||
Name: "pbscript",
|
||||
Schema: schema.NewSchema(
|
||||
&schema.SchemaField{
|
||||
Type: schema.FieldTypeText,
|
||||
Name: "type",
|
||||
},
|
||||
&schema.SchemaField{
|
||||
Type: schema.FieldTypeBool,
|
||||
Name: "isActive",
|
||||
},
|
||||
&schema.SchemaField{
|
||||
Type: schema.FieldTypeJson,
|
||||
Name: "data",
|
||||
},
|
||||
),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func watchForScriptChanges() {
|
||||
app.OnModelAfterUpdate().Add(func(e *core.ModelEvent) error {
|
||||
if e.Model.TableName() == "pbscript" {
|
||||
reloadVm()
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
app.OnModelAfterCreate().Add(func(e *core.ModelEvent) error {
|
||||
if e.Model.TableName() == "pbscript" {
|
||||
reloadVm()
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
|
||||
// add new "GET /api/hello" route
|
||||
|
||||
e.Router.AddRoute(echo.Route{
|
||||
Method: http.MethodPost,
|
||||
Path: "/api/pbscript/deploy",
|
||||
Handler: func(c echo.Context) error {
|
||||
json_map := make(map[string]interface{})
|
||||
err := json.NewDecoder(c.Request().Body).Decode(&json_map)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//json_map has the JSON Payload decoded into a map
|
||||
src := json_map["source"]
|
||||
|
||||
err = app.Dao().RunInTransaction(func(txDao *daos.Dao) error {
|
||||
fmt.Println("Deactivating active script")
|
||||
_, err := txDao.DB().
|
||||
NewQuery("UPDATE pbscript SET isActive=false WHERE type='script'").Execute()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("Packaging new record data")
|
||||
bytes, err := json.Marshal(dbx.Params{"source": src})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_json := string(bytes)
|
||||
|
||||
fmt.Println("Saving new model")
|
||||
collection, err := txDao.FindCollectionByNameOrId("pbscript")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
record := models.NewRecord(collection)
|
||||
record.SetDataValue("type", "script")
|
||||
record.SetDataValue("isActive", "true")
|
||||
record.SetDataValue("data", _json)
|
||||
err = txDao.SaveRecord(record)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(("Record saved"))
|
||||
// _, err = txDao.DB().
|
||||
// NewQuery("INSERT INTO pbscript (type,isActive,data) values ('script', true, {data})").Bind(dbx.Params{"data": _json}).Execute()
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.String(http.StatusOK, "ok")
|
||||
|
||||
},
|
||||
Middlewares: []echo.MiddlewareFunc{
|
||||
apis.RequireAdminAuth(),
|
||||
},
|
||||
})
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func initAppEvents() {
|
||||
app.OnModelBeforeCreate().Add(func(e *core.ModelEvent) error {
|
||||
fmt.Println("event: OnModelBeforeCreate")
|
||||
event.Fire(event.EVT_ON_MODEL_BEFORE_CREATE, (*event.UnknownPayload)(unsafe.Pointer(e)))
|
||||
return nil
|
||||
})
|
||||
app.OnModelAfterCreate().Add(func(e *core.ModelEvent) error {
|
||||
fmt.Println("event: OnModelAfterCreate")
|
||||
event.Fire(event.EVT_ON_MODEL_AFTER_CREATE, (*event.UnknownPayload)(unsafe.Pointer(e)))
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func StartPBScript(_app *pocketbase.PocketBase) error {
|
||||
app = _app
|
||||
|
||||
watchForScriptChanges()
|
||||
|
||||
app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
|
||||
migrate()
|
||||
initAppEvents()
|
||||
router = e.Router
|
||||
err := reloadVm()
|
||||
if err != nil {
|
||||
logErrorf("Error loading VM: %s\n", err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
return nil
|
||||
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
package event
|
||||
|
||||
import "fmt"
|
||||
|
||||
type UnknownPayload any
|
||||
|
||||
var inc = 0
|
||||
var events = map[string]map[int]func(payload *UnknownPayload){}
|
||||
|
||||
const (
|
||||
EVT_ON_MODEL_BEFORE_CREATE = "OnModelBeforeCreate"
|
||||
EVT_ON_MODEL_AFTER_CREATE = "OnModelAfterCreate"
|
||||
)
|
||||
|
||||
func isValid(eventName string) bool {
|
||||
return eventName == EVT_ON_MODEL_BEFORE_CREATE || eventName== EVT_ON_MODEL_AFTER_CREATE
|
||||
}
|
||||
|
||||
func ensureEvent(eventName string) {
|
||||
if !isValid((eventName)) {
|
||||
panic(fmt.Sprintf("%s is not a valid event name", eventName))
|
||||
}
|
||||
if _, ok := events[eventName]; !ok {
|
||||
fmt.Printf("Creating collection for %s\n", eventName)
|
||||
events[eventName] = make(map[int]func(payload *UnknownPayload))
|
||||
}
|
||||
}
|
||||
|
||||
func On(eventName string, cb func(payload *UnknownPayload)) func() {
|
||||
ensureEvent(eventName)
|
||||
|
||||
inc++
|
||||
idx := inc
|
||||
events[eventName][idx] = cb
|
||||
fmt.Printf("Adding %d to %s\n", idx, eventName)
|
||||
return func() {
|
||||
delete(events[eventName], idx)
|
||||
}
|
||||
}
|
||||
|
||||
func Fire(eventName string, payload *UnknownPayload) {
|
||||
ensureEvent(eventName)
|
||||
|
||||
fmt.Printf("Firing %s\n", eventName)
|
||||
for fnId, v := range events[eventName] {
|
||||
fmt.Printf("Dispatching %s to %d\n", eventName, fnId)
|
||||
v(payload)
|
||||
}
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
module github.com/benallfree/pbscript/modules/pbscript
|
||||
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/dop251/goja v0.0.0-20220927172339-ea66e911853d
|
||||
github.com/goccy/go-json v0.9.11
|
||||
github.com/labstack/echo/v5 v5.0.0-20220201181537-ed2888cfa198
|
||||
github.com/pocketbase/dbx v1.6.0
|
||||
github.com/pocketbase/pocketbase v0.7.5
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/AlecAivazis/survey/v2 v2.3.5 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
|
||||
github.com/aws/aws-sdk-go v1.44.85 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.16.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.17.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.12.14 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.12 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.27 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.18 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.12 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.19 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.13 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.12 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.12 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.27.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.16.13 // indirect
|
||||
github.com/aws/smithy-go v1.12.1 // indirect
|
||||
github.com/disintegration/imaging v1.6.2 // indirect
|
||||
github.com/dlclark/regexp2 v1.7.0 // indirect
|
||||
github.com/domodwyer/mailyak/v3 v3.3.4 // indirect
|
||||
github.com/fatih/color v1.13.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.1 // indirect
|
||||
github.com/ganigeorgiev/fexpr v0.1.1 // indirect
|
||||
github.com/go-ozzo/ozzo-validation/v4 v4.3.0 // indirect
|
||||
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/google/wire v0.5.0 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.5.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.15 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/cobra v1.5.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.1 // indirect
|
||||
go.opencensus.io v0.23.0 // indirect
|
||||
gocloud.dev v0.26.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220824171710-5757bc0c5503 // indirect
|
||||
golang.org/x/image v0.0.0-20220722155232-062f8c9fd539 // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
golang.org/x/net v0.0.0-20220822230855-b0a4917ee28c // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 // indirect
|
||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 // indirect
|
||||
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect
|
||||
golang.org/x/tools v0.1.12 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect
|
||||
google.golang.org/api v0.94.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc // indirect
|
||||
google.golang.org/grpc v1.49.0 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
lukechampine.com/uint128 v1.2.0 // indirect
|
||||
modernc.org/cc/v3 v3.36.3 // indirect
|
||||
modernc.org/ccgo/v3 v3.16.9 // indirect
|
||||
modernc.org/libc v1.17.0 // indirect
|
||||
modernc.org/mathutil v1.5.0 // indirect
|
||||
modernc.org/memory v1.2.0 // indirect
|
||||
modernc.org/opt v0.1.3 // indirect
|
||||
modernc.org/sqlite v1.18.1 // indirect
|
||||
modernc.org/strutil v1.1.2 // indirect
|
||||
modernc.org/token v1.0.0 // indirect
|
||||
)
|
File diff suppressed because it is too large
Load Diff
@ -1,12 +0,0 @@
|
||||
package pocketbase
|
||||
|
||||
import (
|
||||
"github.com/benallfree/pbscript/modules/pbscript/engine"
|
||||
"github.com/pocketbase/pocketbase"
|
||||
)
|
||||
|
||||
func New() *pocketbase.PocketBase {
|
||||
app := pocketbase.New()
|
||||
engine.StartPBScript(app)
|
||||
return app
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
[Unit]
|
||||
Description=Pockethost DB Service
|
||||
|
||||
[Service]
|
||||
StandardOutput = append:/data/pockethost/logs/errors.log
|
||||
StandardError = append:/data/pockethost/logs/errors.log
|
||||
ExecStart=/usr/local/bin/pockethost serve --http '127.0.0.1:8090' --dir /data/pockethost
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
|
||||
[Unit]
|
||||
Description = pocketbase
|
||||
|
@ -1,23 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: pockethost
|
||||
# Short-Description: starts the pockethost db server
|
||||
# Description: starts the pockethost db server
|
||||
### END INIT INFO
|
||||
|
||||
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
||||
NAME=pockethost
|
||||
DESC=pockethost
|
||||
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo "Starting $DESC" "$NAME"
|
||||
pockethost serve --http '127.0.0.1:8090' --dir /data/pockethost &
|
||||
|
||||
;;
|
||||
stop)
|
||||
echo "Stopping $DESC" "$NAME"
|
||||
|
||||
esac
|
@ -1,11 +0,0 @@
|
||||
#!/sbin/openrc-run
|
||||
|
||||
description="Pockethost server"
|
||||
extra_commands=""
|
||||
extra_started_commands=""
|
||||
|
||||
|
||||
start_pre() {
|
||||
einfo "Starting pockethost"
|
||||
/usr/local/bin/pocketbase serve --http '127.0.0.1:8090' --dir /data/pockethost
|
||||
}
|
1
attic/pockethost/.gitignore
vendored
1
attic/pockethost/.gitignore
vendored
@ -1 +0,0 @@
|
||||
pockethost
|
@ -1,83 +0,0 @@
|
||||
module pockethost
|
||||
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/AlecAivazis/survey/v2 v2.3.5 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
|
||||
github.com/aws/aws-sdk-go v1.44.85 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.16.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.17.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.12.14 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.12 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.27 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.18 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.12 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.19 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.13 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.12 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.12 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.27.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.16.13 // indirect
|
||||
github.com/aws/smithy-go v1.12.1 // indirect
|
||||
github.com/disintegration/imaging v1.6.2 // indirect
|
||||
github.com/domodwyer/mailyak/v3 v3.3.4 // indirect
|
||||
github.com/fatih/color v1.13.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.1 // indirect
|
||||
github.com/ganigeorgiev/fexpr v0.1.1 // indirect
|
||||
github.com/go-ozzo/ozzo-validation/v4 v4.3.0 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/google/wire v0.5.0 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.5.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/labstack/echo/v5 v5.0.0-20220201181537-ed2888cfa198 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.15 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
|
||||
github.com/pocketbase/dbx v1.6.0 // indirect
|
||||
github.com/pocketbase/pocketbase v0.7.2 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/cobra v1.5.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.1 // indirect
|
||||
go.opencensus.io v0.23.0 // indirect
|
||||
gocloud.dev v0.26.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220824171710-5757bc0c5503 // indirect
|
||||
golang.org/x/image v0.0.0-20220722155232-062f8c9fd539 // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
golang.org/x/net v0.0.0-20220822230855-b0a4917ee28c // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 // indirect
|
||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 // indirect
|
||||
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect
|
||||
golang.org/x/tools v0.1.12 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect
|
||||
google.golang.org/api v0.94.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc // indirect
|
||||
google.golang.org/grpc v1.49.0 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
lukechampine.com/uint128 v1.2.0 // indirect
|
||||
modernc.org/cc/v3 v3.36.3 // indirect
|
||||
modernc.org/ccgo/v3 v3.16.9 // indirect
|
||||
modernc.org/libc v1.17.0 // indirect
|
||||
modernc.org/mathutil v1.5.0 // indirect
|
||||
modernc.org/memory v1.2.0 // indirect
|
||||
modernc.org/opt v0.1.3 // indirect
|
||||
modernc.org/sqlite v1.18.1 // indirect
|
||||
modernc.org/strutil v1.1.2 // indirect
|
||||
modernc.org/token v1.0.0 // indirect
|
||||
)
|
File diff suppressed because it is too large
Load Diff
@ -1,15 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/pocketbase/pocketbase"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := pocketbase.New()
|
||||
|
||||
if err := app.Start(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
nginx
|
||||
pocketbase serve
|
@ -1,10 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
PORT=8090
|
||||
SUBDOMAIN=db
|
||||
|
||||
sudo certbot certonly --agree-tos --nginx --email pockethost@benallfree.com -d $SUBDOMAIN.pockethost.io
|
||||
|
||||
NGINX_CONFIG=envsubst < nginx-template.conf
|
||||
|
||||
echo $NGINX_CONFIG
|
@ -1 +0,0 @@
|
||||
sudo certbot certonly --agree-tos --nginx --email pockethost@benallfree.com -d $SUBDOMAIN.pockethost.io
|
@ -1 +0,0 @@
|
||||
pocketbase serve --dir ~/pocketbase-microservice/data/$SUBDOMAIN/pb_data --http 127.0.0.1:$PORT &
|
@ -1,28 +0,0 @@
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name $SUBDOMAIN.pockethost.io;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/$SUBDOMAIN.pockethost.io/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/$SUBDOMAIN.pockethost.io/privkey.pem;
|
||||
|
||||
access_log /home/pockethost/pockethost-microservice/data/$SUBDOMAIN/logs/access.log;
|
||||
error_log /home/pockethost/pockethost-microservice/data/$SUBDOMAIN/logs/error.log;
|
||||
|
||||
location / {
|
||||
proxy_read_timeout 180s;
|
||||
|
||||
# WebSocket support
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
proxy_pass http://127.0.0.1:$PORT;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user