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

This commit is contained in:
Ben Allfree 2024-05-30 11:40:21 +00:00
commit dc9f332aa7
34 changed files with 510 additions and 461 deletions

View File

@ -13,7 +13,6 @@ MOTHERSHIP_MIGRATIONS_DIR=/path/to/dist/mothership-app/migrations
MOTHERSHIP_HOOKS_DIR=/path/to/dist/mothership-app/pb_hooks MOTHERSHIP_HOOKS_DIR=/path/to/dist/mothership-app/pb_hooks
DAEMON_DATA_ROOT=/path/to/.pockethost/data DAEMON_DATA_ROOT=/path/to/.pockethost/data
DAEMON_INITIAL_PORT_POOL_SIZE=20 DAEMON_INITIAL_PORT_POOL_SIZE=20
PH_BIN_CACHE=/path/to/.pockethost/pbincache
PH_FTP_PORT=21 PH_FTP_PORT=21
SSL_KEY=/path/to/pockethost.key SSL_KEY=/path/to/pockethost.key
SSL_CERT=/path/to/pockethost.crt SSL_CERT=/path/to/pockethost.crt

4
.gitignore vendored
View File

@ -7,14 +7,10 @@
.idea .idea
**/.env **/.env
**/.env.* **/.env.*
.pbincache
osx osx
pocketbase pocketbase
.svelte-kit .svelte-kit
live-data live-data
dist dist
.pockethost .pockethost
version-cache
// This is needed because Docker bind mounts will copy this file
src/mothership-app/pb_hooks/src/versions.js

View File

@ -9,9 +9,6 @@ build
_site _site
forks forks
// This is needed because Docker bind mounts will copy this file
src/mothership-app/pb_hooks/src/versions.js
src/mothership-app/migrations src/mothership-app/migrations
src/mothership-app/pb_hooks/types/types.d.ts src/mothership-app/pb_hooks/types/types.d.ts
src/instance-app/types/types.d.ts src/instance-app/types/types.d.ts

View File

@ -17,6 +17,7 @@
"frontends", "frontends",
"fullchain", "fullchain",
"getenv", "getenv",
"gobot",
"goja", "goja",
"IPCIDR", "IPCIDR",
"jsonifiable", "jsonifiable",
@ -37,7 +38,6 @@
"opengraph", "opengraph",
"PASV", "PASV",
"pbgo", "pbgo",
"pbincache",
"PBOUNCE", "PBOUNCE",
"pexec", "pexec",
"pocketbase", "pocketbase",
@ -46,6 +46,7 @@
"privkey", "privkey",
"rizzdown", "rizzdown",
"Rpcs", "Rpcs",
"semvers",
"superadmin", "superadmin",
"syslogd", "syslogd",
"tailable", "tailable",

View File

@ -22,9 +22,9 @@ module.exports = {
script: 'pnpm prod:cli mothership serve', script: 'pnpm prod:cli mothership serve',
}, },
{ {
name: `downloader`, name: `updater`,
restart_delay: 60 * 60 * 1000, // 1 hour restart_delay: 60 * 60 * 1000, // 1 hour
script: 'pnpm prod:cli download', script: 'pnpm prod:cli mothership update',
}, },
{ {
name: `health`, name: `health`,

View File

@ -23,7 +23,7 @@ Key updates in this release:
# Overview (experimental) # Overview (experimental)
Here is what AI decided based on the change log (powered by [rizzdown](https://benallfree/rizzdown))... Here is what AI decided based on the change log (powered by [rizzdown](https://github.com/benallfree/rizzdown))...
The release of PocketHost v0.11.0 introduces essential refinements designed to uplift the developer experience. The enhancement of debug logging in InstanceService presents a granular understanding of the system's inner workings. The refactoring of FTP physical and virtual directory names, together with the PocketBase (pb) launcher, contributes to elevating performance levels - a paramount advantage for restricted bandwidth environments or large projects. The release of PocketHost v0.11.0 introduces essential refinements designed to uplift the developer experience. The enhancement of debug logging in InstanceService presents a granular understanding of the system's inner workings. The refactoring of FTP physical and virtual directory names, together with the PocketBase (pb) launcher, contributes to elevating performance levels - a paramount advantage for restricted bandwidth environments or large projects.

View File

@ -8,7 +8,7 @@ PocketHost instances can use a custom domain (CNAME) instead of `*.pockethost.io
We recommand Cloudflare because they support [CNAME flattening](https://developers.cloudflare.com/dns/cname-flattening/) which means you can use `mydomain.com` instead of `foo.mydomain.com`. We recommand Cloudflare because they support [CNAME flattening](https://developers.cloudflare.com/dns/cname-flattening/) which means you can use `mydomain.com` instead of `foo.mydomain.com`.
Once you have configured your CNAME, you'll need to contact us to get it activated. Once you have configured your CNAME, go to your PocketHost Dashboard and the Settings tab of your instance to add it (Pro feature only).
Example: Example:

View File

@ -20,7 +20,7 @@
"buildtool": "tsx buildtool/index.ts", "buildtool": "tsx buildtool/index.ts",
"build-frontends": "concurrently 'pnpm:build:frontend:*'", "build-frontends": "concurrently 'pnpm:build:frontend:*'",
"build:frontend:dashboard": "cd frontends/dashboard && pnpm build", "build:frontend:dashboard": "cd frontends/dashboard && pnpm build",
"build:docker": "docker build . -t pockethost-instance:1.0.0 -t pockethost-instance:latest", "build:docker": "cd src/services/PocketBaseService && docker build . -t pockethost-instance:1.0.0 -t pockethost-instance:latest",
"build:frontend:lander": "cd frontends/lander && pnpm build", "build:frontend:lander": "cd frontends/lander && pnpm build",
"build:frontend:superadmin": "cd frontends/superadmin && pnpm build", "build:frontend:superadmin": "cd frontends/superadmin && pnpm build",
"dev:cli": "NODE_ENV=development tsx src/cli/index.ts", "dev:cli": "NODE_ENV=development tsx src/cli/index.ts",
@ -69,6 +69,8 @@
"ftp-srv": "github:pockethost/ftp-srv#0fc708bae0d5d7a55ce948767f082d6fcfb2af59", "ftp-srv": "github:pockethost/ftp-srv#0fc708bae0d5d7a55ce948767f082d6fcfb2af59",
"get-port": "^6.1.2", "get-port": "^6.1.2",
"glob": "^10.3.10", "glob": "^10.3.10",
"gobot": "1.0.0-alpha.40",
"gobot-pocketbase": "0.22.8-alpha.22",
"http-proxy": "^1.18.1", "http-proxy": "^1.18.1",
"http-proxy-middleware": "^2.0.6", "http-proxy-middleware": "^2.0.6",
"ip-cidr": "^3.1.0", "ip-cidr": "^3.1.0",
@ -78,7 +80,6 @@
"nanoid": "^5.0.2", "nanoid": "^5.0.2",
"node-fetch": "^3.3.2", "node-fetch": "^3.3.2",
"node-os-utils": "^1.3.7", "node-os-utils": "^1.3.7",
"pbgo": "1.0.0-alpha.3",
"pocketbase": "^0.20.1", "pocketbase": "^0.20.1",
"rimraf": "^5.0.5", "rimraf": "^5.0.5",
"semver": "^7.5.4", "semver": "^7.5.4",
@ -145,6 +146,5 @@
"tsx": "^3.14.0", "tsx": "^3.14.0",
"type-fest": "^4.6.0", "type-fest": "^4.6.0",
"typescript": "^5.2.2" "typescript": "^5.2.2"
}, }
"packageManager": "pnpm@9.1.2"
} }

286
pnpm-lock.yaml generated
View File

@ -80,6 +80,12 @@ importers:
glob: glob:
specifier: ^10.3.10 specifier: ^10.3.10
version: 10.3.10 version: 10.3.10
gobot:
specifier: 1.0.0-alpha.40
version: 1.0.0-alpha.40
gobot-pocketbase:
specifier: 0.22.8-alpha.22
version: 0.22.8-alpha.22
http-proxy: http-proxy:
specifier: ^1.18.1 specifier: ^1.18.1
version: 1.18.1 version: 1.18.1
@ -107,9 +113,6 @@ importers:
node-os-utils: node-os-utils:
specifier: ^1.3.7 specifier: ^1.3.7
version: 1.3.7 version: 1.3.7
pbgo:
specifier: 1.0.0-alpha.3
version: 1.0.0-alpha.3
pocketbase: pocketbase:
specifier: ^0.20.1 specifier: ^0.20.1
version: 0.20.1 version: 0.20.1
@ -958,6 +961,9 @@ packages:
'@s-libs/micro-dash@16.1.0': '@s-libs/micro-dash@16.1.0':
resolution: {integrity: sha512-GmmtRb/vNl1RxErvm/d+ITfjbo4og/CXyYdqs4vpeFrJla0uSEbXwf9aJUXYvgORQDgXV6h9tdgDY6T88FRU3Q==} resolution: {integrity: sha512-GmmtRb/vNl1RxErvm/d+ITfjbo4og/CXyYdqs4vpeFrJla0uSEbXwf9aJUXYvgORQDgXV6h9tdgDY6T88FRU3Q==}
'@s-libs/micro-dash@17.1.0':
resolution: {integrity: sha512-vnrChv6KQG/kgRSNmxH0IqcGx4gYlvnmkfzuKotQNZZMBTnDZOzHYr487LPRq1Rr0ohRDuDsz6WssSolyoowQg==}
'@sindresorhus/is@4.6.0': '@sindresorhus/is@4.6.0':
resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -1483,6 +1489,10 @@ packages:
assert-never@1.2.1: assert-never@1.2.1:
resolution: {integrity: sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==} resolution: {integrity: sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==}
astral-regex@2.0.0:
resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==}
engines: {node: '>=8'}
async@3.2.4: async@3.2.4:
resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==}
@ -1838,6 +1848,10 @@ packages:
resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==}
engines: {node: '>=16'} engines: {node: '>=16'}
commander@12.1.0:
resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==}
engines: {node: '>=18'}
commander@2.20.3: commander@2.20.3:
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
@ -2021,6 +2035,14 @@ packages:
decode-named-character-reference@1.0.2: decode-named-character-reference@1.0.2:
resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==}
decompress-bzip2@4.0.0:
resolution: {integrity: sha512-RwEcbZWaM7F5EiYfsAXUmZ/KLEVAPjYXfGbb5bztXZQ3d5PMpXYxa/1j04QL/gjotRdmzpHh++/cxz+rNZ4AZg==}
engines: {node: '>=4'}
decompress-gz@0.0.1:
resolution: {integrity: sha512-YMdCWdxHvPplsTbV1tvr2oFJOtAFNxqVMFnKWEmePBXl+LKG5z5bFrowzc12Jzd7O29nnzI/D1M95Asx0Qa1fg==}
engines: {node: '>=4'}
decompress-response@6.0.0: decompress-response@6.0.0:
resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -2037,6 +2059,10 @@ packages:
resolution: {integrity: sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==} resolution: {integrity: sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==}
engines: {node: '>=4'} engines: {node: '>=4'}
decompress-unzip@4.0.1:
resolution: {integrity: sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==}
engines: {node: '>=4'}
decompress-unzip@https://codeload.github.com/pockethost/decompress-unzip/tar.gz/6ef397b9a2df11d39c7b26ce779e123833844751: decompress-unzip@https://codeload.github.com/pockethost/decompress-unzip/tar.gz/6ef397b9a2df11d39c7b26ce779e123833844751:
resolution: {tarball: https://codeload.github.com/pockethost/decompress-unzip/tar.gz/6ef397b9a2df11d39c7b26ce779e123833844751} resolution: {tarball: https://codeload.github.com/pockethost/decompress-unzip/tar.gz/6ef397b9a2df11d39c7b26ce779e123833844751}
version: 4.0.1 version: 4.0.1
@ -2400,6 +2426,9 @@ packages:
resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==}
engines: {node: '>=8.6.0'} engines: {node: '>=8.6.0'}
fast-safe-stringify@2.1.1:
resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==}
fastparse@1.1.2: fastparse@1.1.2:
resolution: {integrity: sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==} resolution: {integrity: sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==}
@ -2429,10 +2458,18 @@ packages:
resolution: {integrity: sha512-hlDw5Ev+9e883s0pwUsuuYNu4tD7GgpUnOvykjv1Gya0ZIjuKumthDRua90VUn6/nlRKAjcxLUnHNTIUWwWIiw==} resolution: {integrity: sha512-hlDw5Ev+9e883s0pwUsuuYNu4tD7GgpUnOvykjv1Gya0ZIjuKumthDRua90VUn6/nlRKAjcxLUnHNTIUWwWIiw==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
file-type@19.0.0:
resolution: {integrity: sha512-s7cxa7/leUWLiXO78DVVfBVse+milos9FitauDLG1pI7lNaJ2+5lzPnr2N24ym+84HVwJL6hVuGfgVE+ALvU8Q==}
engines: {node: '>=18'}
file-type@3.9.0: file-type@3.9.0:
resolution: {integrity: sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==} resolution: {integrity: sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
file-type@4.4.0:
resolution: {integrity: sha512-f2UbFQEk7LXgWpi5ntcO86OeA/cC80fuDDDaX/fZ2ZGel+AF7leRQqBBW1eJNiiQkrZlAoM6P+VYP5P6bOlDEQ==}
engines: {node: '>=4'}
file-type@5.2.0: file-type@5.2.0:
resolution: {integrity: sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==} resolution: {integrity: sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==}
engines: {node: '>=4'} engines: {node: '>=4'}
@ -2479,6 +2516,10 @@ packages:
resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
find-up@7.0.0:
resolution: {integrity: sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==}
engines: {node: '>=18'}
find-versions@5.1.0: find-versions@5.1.0:
resolution: {integrity: sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==} resolution: {integrity: sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==}
engines: {node: '>=12'} engines: {node: '>=12'}
@ -2614,6 +2655,10 @@ packages:
resolution: {integrity: sha512-BrGGraKm2uPqurfGVj/z97/zv8dPleC6x9JBNRTrDNtCkkRF4rPwrQXFgL7+I+q8QSdU4ntLQX2D7KIxSy8nGw==} resolution: {integrity: sha512-BrGGraKm2uPqurfGVj/z97/zv8dPleC6x9JBNRTrDNtCkkRF4rPwrQXFgL7+I+q8QSdU4ntLQX2D7KIxSy8nGw==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
get-stream@2.3.1:
resolution: {integrity: sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==}
engines: {node: '>=0.10.0'}
get-stream@3.0.0: get-stream@3.0.0:
resolution: {integrity: sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==} resolution: {integrity: sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==}
engines: {node: '>=4'} engines: {node: '>=4'}
@ -2650,6 +2695,7 @@ packages:
glob@6.0.4: glob@6.0.4:
resolution: {integrity: sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==} resolution: {integrity: sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==}
deprecated: Glob versions prior to v9 are no longer supported
glob@7.1.6: glob@7.1.6:
resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==} resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==}
@ -2683,6 +2729,14 @@ packages:
resolution: {integrity: sha512-mTCC51QFadK75MvAhrL5nPVIP291NjML1guo10Sa7Yj04tJU4V++Vgm780NIddg9etQD9D8FM67hFGqM8EE2HQ==} resolution: {integrity: sha512-mTCC51QFadK75MvAhrL5nPVIP291NjML1guo10Sa7Yj04tJU4V++Vgm780NIddg9etQD9D8FM67hFGqM8EE2HQ==}
engines: {node: '>= 0.2.5'} engines: {node: '>= 0.2.5'}
gobot-pocketbase@0.22.8-alpha.22:
resolution: {integrity: sha512-beNLlDjonodEiNNcPIxAY4yYAzxcNC0i4KUrinYboR2KtAfbeMb0zijeswVKkZBnopDYQAWqasBEFhsFO7oiUg==}
hasBin: true
gobot@1.0.0-alpha.40:
resolution: {integrity: sha512-bV+QO3VZamsnKLH5Pqt0tFZ2CD90JT2QjQIs6tvMP1H2w8QJApbRPVkpJ4O56nXGgyj6f0udelDrsd4tm1F6CQ==}
hasBin: true
gopd@1.0.1: gopd@1.0.1:
resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
@ -2830,9 +2884,6 @@ packages:
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
hasBin: true hasBin: true
immediate@3.0.6:
resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
immutable@4.3.4: immutable@4.3.4:
resolution: {integrity: sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==} resolution: {integrity: sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==}
@ -3038,6 +3089,10 @@ packages:
resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
engines: {node: '>=8'} engines: {node: '>=8'}
is-stream@4.0.1:
resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==}
engines: {node: '>=18'}
is-typedarray@1.0.0: is-typedarray@1.0.0:
resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==}
@ -3128,9 +3183,6 @@ packages:
jstransformer@1.0.0: jstransformer@1.0.0:
resolution: {integrity: sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==} resolution: {integrity: sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==}
jszip@3.10.1:
resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==}
junk@1.0.3: junk@1.0.3:
resolution: {integrity: sha512-3KF80UaaSSxo8jVnRYtMKNGFOoVPBdkkVPsw+Ad0y4oxKXPduS6G6iHkrf69yJVff/VAaYXkV42rtZ7daJxU3w==} resolution: {integrity: sha512-3KF80UaaSSxo8jVnRYtMKNGFOoVPBdkkVPsw+Ad0y4oxKXPduS6G6iHkrf69yJVff/VAaYXkV42rtZ7daJxU3w==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -3181,9 +3233,6 @@ packages:
resolution: {integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==} resolution: {integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==}
engines: {node: '>=14.16'} engines: {node: '>=14.16'}
lie@3.3.0:
resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==}
liftoff@4.0.0: liftoff@4.0.0:
resolution: {integrity: sha512-rMGwYF8q7g2XhG2ulBmmJgWv25qBsqRbDn5gH0+wnuyeFt7QBJlHJmtg5qEdn4pN6WVAUMgXnIxytMFRX9c1aA==} resolution: {integrity: sha512-rMGwYF8q7g2XhG2ulBmmJgWv25qBsqRbDn5gH0+wnuyeFt7QBJlHJmtg5qEdn4pN6WVAUMgXnIxytMFRX9c1aA==}
engines: {node: '>=10.13.0'} engines: {node: '>=10.13.0'}
@ -3246,6 +3295,9 @@ packages:
lodash.throttle@4.1.1: lodash.throttle@4.1.1:
resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==} resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==}
lodash.truncate@4.4.2:
resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==}
lodash@4.17.21: lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
@ -3291,6 +3343,11 @@ packages:
resolution: {integrity: sha512-tFWBiv3h7z+T/tDaoxA8rqTxy1CHV6gHS//QdaH4pulbq/JuBSGgQspQQqcgnwdAx6pNI7cmvz5Sv/addzHmUg==} resolution: {integrity: sha512-tFWBiv3h7z+T/tDaoxA8rqTxy1CHV6gHS//QdaH4pulbq/JuBSGgQspQQqcgnwdAx6pNI7cmvz5Sv/addzHmUg==}
engines: {node: '>=12'} engines: {node: '>=12'}
lzma-native@8.0.6:
resolution: {integrity: sha512-09xfg67mkL2Lz20PrrDeNYZxzeW7ADtpYFbwSQh9U8+76RIzx5QsJBMy8qikv3hbUPfpy6hqwxt6FcGK81g9AA==}
engines: {node: '>=10.0.0'}
hasBin: true
magic-string@0.27.0: magic-string@0.27.0:
resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==}
engines: {node: '>=12'} engines: {node: '>=12'}
@ -3332,6 +3389,9 @@ packages:
resolution: {integrity: sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==} resolution: {integrity: sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==}
hasBin: true hasBin: true
markdown-table@3.0.3:
resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==}
marked@9.1.5: marked@9.1.5:
resolution: {integrity: sha512-14QG3shv8Kg/xc0Yh6TNkMj90wXH9mmldi5941I2OevfJ/FQAFLEwtwU2/FfgSAOMlWHrEukWSGQf8MiVYNG2A==} resolution: {integrity: sha512-14QG3shv8Kg/xc0Yh6TNkMj90wXH9mmldi5941I2OevfJ/FQAFLEwtwU2/FfgSAOMlWHrEukWSGQf8MiVYNG2A==}
engines: {node: '>= 16'} engines: {node: '>= 16'}
@ -3629,6 +3689,9 @@ packages:
resolution: {integrity: sha512-SQkEP4hmNWjlniS5zdnfIXTk1x7Ome85RDzHlTbBtzE97Gfwz/Ipw4v/Ryk20DWIy3yCNVLVlGKApCnmvYoJbA==} resolution: {integrity: sha512-SQkEP4hmNWjlniS5zdnfIXTk1x7Ome85RDzHlTbBtzE97Gfwz/Ipw4v/Ryk20DWIy3yCNVLVlGKApCnmvYoJbA==}
engines: {node: '>=10'} engines: {node: '>=10'}
node-addon-api@3.2.1:
resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==}
node-addon-api@4.3.0: node-addon-api@4.3.0:
resolution: {integrity: sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==} resolution: {integrity: sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==}
@ -3652,6 +3715,10 @@ packages:
resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
node-gyp-build@4.8.1:
resolution: {integrity: sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==}
hasBin: true
node-gyp@8.4.1: node-gyp@8.4.1:
resolution: {integrity: sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==} resolution: {integrity: sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==}
engines: {node: '>= 10.12.0'} engines: {node: '>= 10.12.0'}
@ -3853,9 +3920,6 @@ packages:
resolution: {integrity: sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==} resolution: {integrity: sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==}
engines: {node: '>=14.16'} engines: {node: '>=14.16'}
pako@1.0.11:
resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==}
param-case@3.0.4: param-case@3.0.4:
resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==}
@ -3936,10 +4000,6 @@ packages:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'} engines: {node: '>=8'}
pbgo@1.0.0-alpha.3:
resolution: {integrity: sha512-rL4as8mm9i4rRldtJHPCaRqXBzQi/HmnkcmNf36SzVBgBvlrz9pxkkz1FQNZUpmz3qzaQxKoYwrWOEhRazWmuA==}
hasBin: true
peek-readable@5.0.0: peek-readable@5.0.0:
resolution: {integrity: sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A==} resolution: {integrity: sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A==}
engines: {node: '>=14.16'} engines: {node: '>=14.16'}
@ -3968,6 +4028,14 @@ packages:
resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==}
engines: {node: '>=4'} engines: {node: '>=4'}
pinkie-promise@2.0.1:
resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==}
engines: {node: '>=0.10.0'}
pinkie@2.0.4:
resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==}
engines: {node: '>=0.10.0'}
pirates@4.0.6: pirates@4.0.6:
resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
engines: {node: '>= 6'} engines: {node: '>= 6'}
@ -4397,6 +4465,11 @@ packages:
engines: {node: '>=10'} engines: {node: '>=10'}
hasBin: true hasBin: true
semver@7.6.2:
resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==}
engines: {node: '>=10'}
hasBin: true
send@0.18.0: send@0.18.0:
resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==}
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
@ -4418,9 +4491,6 @@ packages:
resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
setimmediate@1.0.5:
resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
setprototypeof@1.2.0: setprototypeof@1.2.0:
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
@ -4486,6 +4556,10 @@ packages:
resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==}
engines: {node: '>=12'} engines: {node: '>=12'}
slice-ansi@4.0.0:
resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==}
engines: {node: '>=10'}
slugify@1.6.6: slugify@1.6.6:
resolution: {integrity: sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==} resolution: {integrity: sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==}
engines: {node: '>=8.0.0'} engines: {node: '>=8.0.0'}
@ -4735,6 +4809,10 @@ packages:
resolution: {integrity: sha512-FI6xGyKM9dRdNCrCWiEy1QhRZskDYkW+lUNAIXkFeht0/XCsSdZ7UsPANFLk0h8b+8Is6Ll8bllUNjME+XCANA==} resolution: {integrity: sha512-FI6xGyKM9dRdNCrCWiEy1QhRZskDYkW+lUNAIXkFeht0/XCsSdZ7UsPANFLk0h8b+8Is6Ll8bllUNjME+XCANA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
table@6.8.2:
resolution: {integrity: sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==}
engines: {node: '>=10.0.0'}
tail@2.2.6: tail@2.2.6:
resolution: {integrity: sha512-IQ6G4wK/t8VBauYiGPLx+d3fA5XjSVagjWV5SIYzvEvglbQjwEcukeYI68JOPpdydjxhZ9sIgzRlSmwSpphHyw==} resolution: {integrity: sha512-IQ6G4wK/t8VBauYiGPLx+d3fA5XjSVagjWV5SIYzvEvglbQjwEcukeYI68JOPpdydjxhZ9sIgzRlSmwSpphHyw==}
engines: {node: '>= 6.0.0'} engines: {node: '>= 6.0.0'}
@ -4803,6 +4881,10 @@ packages:
resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==} resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==}
engines: {node: '>=8.17.0'} engines: {node: '>=8.17.0'}
tmp@0.2.3:
resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==}
engines: {node: '>=14.14'}
to-buffer@1.1.1: to-buffer@1.1.1:
resolution: {integrity: sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==} resolution: {integrity: sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==}
@ -4920,6 +5002,10 @@ packages:
resolution: {integrity: sha512-cSb4bPFd5qgR7qr2jYAi0hlX9n5YKK2ONKkLFkxl+v/9BvC0sOpZjBHDBSXc5lWAf5ty9oZdRXytBIHzgUcerw==} resolution: {integrity: sha512-cSb4bPFd5qgR7qr2jYAi0hlX9n5YKK2ONKkLFkxl+v/9BvC0sOpZjBHDBSXc5lWAf5ty9oZdRXytBIHzgUcerw==}
engines: {node: '>=14.0'} engines: {node: '>=14.0'}
unicorn-magic@0.1.0:
resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==}
engines: {node: '>=18'}
unique-filename@1.1.1: unique-filename@1.1.1:
resolution: {integrity: sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==} resolution: {integrity: sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==}
@ -5562,7 +5648,7 @@ snapshots:
'@npmcli/fs@1.1.1': '@npmcli/fs@1.1.1':
dependencies: dependencies:
'@gar/promisify': 1.1.3 '@gar/promisify': 1.1.3
semver: 7.5.4 semver: 7.6.2
optional: true optional: true
'@npmcli/move-file@1.1.2': '@npmcli/move-file@1.1.2':
@ -5595,6 +5681,11 @@ snapshots:
tslib: 2.6.2 tslib: 2.6.2
utility-types: 3.10.0 utility-types: 3.10.0
'@s-libs/micro-dash@17.1.0':
dependencies:
tslib: 2.6.2
utility-types: 3.10.0
'@sindresorhus/is@4.6.0': {} '@sindresorhus/is@4.6.0': {}
'@sindresorhus/is@5.6.0': {} '@sindresorhus/is@5.6.0': {}
@ -6114,6 +6205,8 @@ snapshots:
assert-never@1.2.1: {} assert-never@1.2.1: {}
astral-regex@2.0.0: {}
async@3.2.4: {} async@3.2.4: {}
asynckit@0.4.0: {} asynckit@0.4.0: {}
@ -6169,7 +6262,7 @@ snapshots:
bin-version-check@5.1.0: bin-version-check@5.1.0:
dependencies: dependencies:
bin-version: 6.0.0 bin-version: 6.0.0
semver: 7.5.4 semver: 7.6.2
semver-truncate: 3.0.0 semver-truncate: 3.0.0
bin-version@6.0.0: bin-version@6.0.0:
@ -6555,6 +6648,8 @@ snapshots:
commander@11.1.0: {} commander@11.1.0: {}
commander@12.1.0: {}
commander@2.20.3: {} commander@2.20.3: {}
commander@4.1.1: {} commander@4.1.1: {}
@ -6748,6 +6843,15 @@ snapshots:
dependencies: dependencies:
character-entities: 2.0.2 character-entities: 2.0.2
decompress-bzip2@4.0.0:
dependencies:
file-type: 4.4.0
seek-bzip: 1.0.6
decompress-gz@0.0.1:
dependencies:
file-type: 5.2.0
decompress-response@6.0.0: decompress-response@6.0.0:
dependencies: dependencies:
mimic-response: 3.1.0 mimic-response: 3.1.0
@ -6772,6 +6876,13 @@ snapshots:
file-type: 5.2.0 file-type: 5.2.0
is-stream: 1.1.0 is-stream: 1.1.0
decompress-unzip@4.0.1:
dependencies:
file-type: 3.9.0
get-stream: 2.3.1
pify: 2.3.0
yauzl: 2.10.0
decompress-unzip@https://codeload.github.com/pockethost/decompress-unzip/tar.gz/6ef397b9a2df11d39c7b26ce779e123833844751: decompress-unzip@https://codeload.github.com/pockethost/decompress-unzip/tar.gz/6ef397b9a2df11d39c7b26ce779e123833844751:
dependencies: dependencies:
file-type: 3.9.0 file-type: 3.9.0
@ -7208,6 +7319,8 @@ snapshots:
merge2: 1.4.1 merge2: 1.4.1
micromatch: 4.0.5 micromatch: 4.0.5
fast-safe-stringify@2.1.1: {}
fastparse@1.1.2: {} fastparse@1.1.2: {}
fastq@1.15.0: fastq@1.15.0:
@ -7237,8 +7350,16 @@ snapshots:
strtok3: 7.0.0 strtok3: 7.0.0
token-types: 5.0.1 token-types: 5.0.1
file-type@19.0.0:
dependencies:
readable-web-to-node-stream: 3.0.2
strtok3: 7.0.0
token-types: 5.0.1
file-type@3.9.0: {} file-type@3.9.0: {}
file-type@4.4.0: {}
file-type@5.2.0: {} file-type@5.2.0: {}
file-type@6.2.0: {} file-type@6.2.0: {}
@ -7293,6 +7414,12 @@ snapshots:
locate-path: 7.2.0 locate-path: 7.2.0
path-exists: 5.0.0 path-exists: 5.0.0
find-up@7.0.0:
dependencies:
locate-path: 7.2.0
path-exists: 5.0.0
unicorn-magic: 0.1.0
find-versions@5.1.0: find-versions@5.1.0:
dependencies: dependencies:
semver-regex: 4.0.5 semver-regex: 4.0.5
@ -7430,6 +7557,11 @@ snapshots:
get-port@6.1.2: {} get-port@6.1.2: {}
get-stream@2.3.1:
dependencies:
object-assign: 4.1.1
pinkie-promise: 2.0.1
get-stream@3.0.0: {} get-stream@3.0.0: {}
get-stream@5.2.0: get-stream@5.2.0:
@ -7521,6 +7653,39 @@ snapshots:
glossy@0.1.7: {} glossy@0.1.7: {}
gobot-pocketbase@0.22.8-alpha.22:
dependencies:
gobot: 1.0.0-alpha.40
gobot@1.0.0-alpha.40:
dependencies:
'@s-libs/micro-dash': 17.1.0
bottleneck: 2.19.5
commander: 12.1.0
decompress: 4.2.1
decompress-bzip2: 4.0.0
decompress-gz: 0.0.1
decompress-tar: 4.1.1
decompress-tarbz2: 4.1.1
decompress-targz: 4.1.1
decompress-unzip: 4.0.1
env-paths: 3.0.0
fast-safe-stringify: 2.1.1
file-type: 19.0.0
find-up: 7.0.0
glob: 10.3.10
is-stream: 4.0.1
json-stringify-safe: 5.0.1
lzma-native: 8.0.6
markdown-table: 3.0.3
node-fetch: 3.3.2
rimraf: 5.0.5
semver: 7.6.2
table: 6.8.2
tar-stream: 1.6.2
tmp: 0.2.3
unbzip2-stream: 1.4.3
gopd@1.0.1: gopd@1.0.1:
dependencies: dependencies:
get-intrinsic: 1.2.2 get-intrinsic: 1.2.2
@ -7700,8 +7865,6 @@ snapshots:
dependencies: dependencies:
queue: 6.0.2 queue: 6.0.2
immediate@3.0.6: {}
immutable@4.3.4: {} immutable@4.3.4: {}
import-fresh@3.3.0: import-fresh@3.3.0:
@ -7873,6 +8036,8 @@ snapshots:
is-stream@2.0.1: {} is-stream@2.0.1: {}
is-stream@4.0.1: {}
is-typedarray@1.0.0: {} is-typedarray@1.0.0: {}
is-unc-path@1.0.0: is-unc-path@1.0.0:
@ -7944,13 +8109,6 @@ snapshots:
is-promise: 2.2.2 is-promise: 2.2.2
promise: 7.3.1 promise: 7.3.1
jszip@3.10.1:
dependencies:
lie: 3.3.0
pako: 1.0.11
readable-stream: 2.3.8
setimmediate: 1.0.5
junk@1.0.3: {} junk@1.0.3: {}
keyv@4.5.4: keyv@4.5.4:
@ -7988,10 +8146,6 @@ snapshots:
dependencies: dependencies:
package-json: 8.1.1 package-json: 8.1.1
lie@3.3.0:
dependencies:
immediate: 3.0.6
liftoff@4.0.0: liftoff@4.0.0:
dependencies: dependencies:
extend: 3.0.2 extend: 3.0.2
@ -8050,6 +8204,8 @@ snapshots:
lodash.throttle@4.1.1: {} lodash.throttle@4.1.1: {}
lodash.truncate@4.4.2: {}
lodash@4.17.21: {} lodash@4.17.21: {}
log-symbols@4.1.0: log-symbols@4.1.0:
@ -8097,6 +8253,12 @@ snapshots:
luxon@3.4.3: {} luxon@3.4.3: {}
lzma-native@8.0.6:
dependencies:
node-addon-api: 3.2.1
node-gyp-build: 4.8.1
readable-stream: 3.6.2
magic-string@0.27.0: magic-string@0.27.0:
dependencies: dependencies:
'@jridgewell/sourcemap-codec': 1.4.15 '@jridgewell/sourcemap-codec': 1.4.15
@ -8157,6 +8319,8 @@ snapshots:
mdurl: 1.0.1 mdurl: 1.0.1
uc.micro: 1.0.6 uc.micro: 1.0.6
markdown-table@3.0.3: {}
marked@9.1.5: {} marked@9.1.5: {}
maximatch@0.1.0: maximatch@0.1.0:
@ -8496,7 +8660,9 @@ snapshots:
node-abi@3.51.0: node-abi@3.51.0:
dependencies: dependencies:
semver: 7.5.4 semver: 7.6.2
node-addon-api@3.2.1: {}
node-addon-api@4.3.0: {} node-addon-api@4.3.0: {}
@ -8516,6 +8682,8 @@ snapshots:
fetch-blob: 3.2.0 fetch-blob: 3.2.0
formdata-polyfill: 4.0.10 formdata-polyfill: 4.0.10
node-gyp-build@4.8.1: {}
node-gyp@8.4.1: node-gyp@8.4.1:
dependencies: dependencies:
env-paths: 2.2.1 env-paths: 2.2.1
@ -8773,9 +8941,7 @@ snapshots:
got: 12.6.1 got: 12.6.1
registry-auth-token: 5.0.2 registry-auth-token: 5.0.2
registry-url: 6.0.1 registry-url: 6.0.1
semver: 7.5.4 semver: 7.6.2
pako@1.0.11: {}
param-case@3.0.4: param-case@3.0.4:
dependencies: dependencies:
@ -8844,12 +9010,6 @@ snapshots:
path-type@4.0.0: {} path-type@4.0.0: {}
pbgo@1.0.0-alpha.3:
dependencies:
env-paths: 3.0.0
jszip: 3.10.1
node-fetch: 3.3.2
peek-readable@5.0.0: {} peek-readable@5.0.0: {}
pend@1.2.0: {} pend@1.2.0: {}
@ -8870,6 +9030,12 @@ snapshots:
pify@3.0.0: {} pify@3.0.0: {}
pinkie-promise@2.0.1:
dependencies:
pinkie: 2.0.4
pinkie@2.0.4: {}
pirates@4.0.6: {} pirates@4.0.6: {}
please-upgrade-node@3.2.0: please-upgrade-node@3.2.0:
@ -9337,13 +9503,13 @@ snapshots:
semver-diff@4.0.0: semver-diff@4.0.0:
dependencies: dependencies:
semver: 7.5.4 semver: 7.6.2
semver-regex@4.0.5: {} semver-regex@4.0.5: {}
semver-truncate@3.0.0: semver-truncate@3.0.0:
dependencies: dependencies:
semver: 7.5.4 semver: 7.6.2
semver@6.3.1: {} semver@6.3.1: {}
@ -9351,6 +9517,8 @@ snapshots:
dependencies: dependencies:
lru-cache: 6.0.0 lru-cache: 6.0.0
semver@7.6.2: {}
send@0.18.0: send@0.18.0:
dependencies: dependencies:
debug: 2.6.9 debug: 2.6.9
@ -9395,8 +9563,6 @@ snapshots:
gopd: 1.0.1 gopd: 1.0.1
has-property-descriptors: 1.0.1 has-property-descriptors: 1.0.1
setimmediate@1.0.5: {}
setprototypeof@1.2.0: {} setprototypeof@1.2.0: {}
sharp@0.32.6: sharp@0.32.6:
@ -9462,6 +9628,12 @@ snapshots:
slash@4.0.0: {} slash@4.0.0: {}
slice-ansi@4.0.0:
dependencies:
ansi-styles: 4.3.0
astral-regex: 2.0.0
is-fullwidth-code-point: 3.0.0
slugify@1.6.6: {} slugify@1.6.6: {}
smart-buffer@4.2.0: smart-buffer@4.2.0:
@ -9729,6 +9901,14 @@ snapshots:
syslog-parse@2.0.0: {} syslog-parse@2.0.0: {}
table@6.8.2:
dependencies:
ajv: 8.12.0
lodash.truncate: 4.4.2
slice-ansi: 4.0.0
string-width: 4.2.3
strip-ansi: 6.0.1
tail@2.2.6: {} tail@2.2.6: {}
tailwindcss@3.3.5: tailwindcss@3.3.5:
@ -9842,6 +10022,8 @@ snapshots:
dependencies: dependencies:
rimraf: 3.0.2 rimraf: 3.0.2
tmp@0.2.3: {}
to-buffer@1.1.1: {} to-buffer@1.1.1: {}
to-fast-properties@2.0.0: {} to-fast-properties@2.0.0: {}
@ -9934,6 +10116,8 @@ snapshots:
dependencies: dependencies:
'@fastify/busboy': 2.0.0 '@fastify/busboy': 2.0.0
unicorn-magic@0.1.0: {}
unique-filename@1.1.1: unique-filename@1.1.1:
dependencies: dependencies:
unique-slug: 2.0.2 unique-slug: 2.0.2

View File

@ -1,13 +0,0 @@
import { PocketbaseReleaseDownloadService } from '$services'
import { LoggerService } from '$shared'
import { discordAlert } from '$util'
export const download = async () => {
const logger = LoggerService().create(`download.ts`)
const { dbg, error, info, warn } = logger
info(`Starting`)
const { check } = PocketbaseReleaseDownloadService({})
await check().catch(discordAlert)
}

View File

@ -1,15 +0,0 @@
import { Command } from 'commander'
import { download } from './download'
type Options = {
debug: boolean
}
export const DownloadCommand = () => {
const cmd = new Command(`download`)
.description(`Download PocketBase versions`)
.action(async () => {
await download()
})
return cmd
}

View File

@ -1,4 +1,3 @@
import { PocketbaseReleaseVersionService } from '$services'
import { Command } from 'commander' import { Command } from 'commander'
import { daemon } from './daemon' import { daemon } from './daemon'
@ -10,7 +9,6 @@ export const ServeCommand = () => {
const cmd = new Command(`serve`) const cmd = new Command(`serve`)
.description(`Run an edge daemon server`) .description(`Run an edge daemon server`)
.action(async (options: Options) => { .action(async (options: Options) => {
await PocketbaseReleaseVersionService({})
await daemon() await daemon()
}) })
return cmd return cmd

View File

@ -1,28 +1,20 @@
import { import {
DATA_ROOT,
DEBUG, DEBUG,
IS_DEV, IS_DEV,
LS_WEBHOOK_SECRET, LS_WEBHOOK_SECRET,
mkContainerHomePath,
MOTHERSHIP_APP_DIR,
MOTHERSHIP_DATA_ROOT, MOTHERSHIP_DATA_ROOT,
MOTHERSHIP_HOOKS_DIR, MOTHERSHIP_HOOKS_DIR,
MOTHERSHIP_MIGRATIONS_DIR, MOTHERSHIP_MIGRATIONS_DIR,
MOTHERSHIP_NAME,
MOTHERSHIP_PORT, MOTHERSHIP_PORT,
MOTHERSHIP_SEMVER, MOTHERSHIP_SEMVER,
PH_VERSIONS, mkContainerHomePath,
} from '$constants' } from '$constants'
import { import { PortService } from '$services'
PocketbaseReleaseVersionService,
PocketbaseService,
PortService,
} from '$services'
import { LoggerService } from '$shared' import { LoggerService } from '$shared'
import { gracefulExit } from '$util'
import copyfiles from 'copyfiles' import copyfiles from 'copyfiles'
import { run } from 'pbgo' import { GobotOptions, gobot } from 'gobot'
import { rimraf } from 'rimraf' import { rimraf } from 'rimraf'
import { freshenPocketbaseVersions } from '../freshenPocketbaseVersions'
export type MothershipConfig = { isolate: boolean } export type MothershipConfig = { isolate: boolean }
@ -59,42 +51,19 @@ export async function mothership(cfg: MothershipConfig) {
/** Launch central database */ /** Launch central database */
info(`Serving`) info(`Serving`)
if (isolate) { const env = {
await PocketbaseReleaseVersionService({})
const pbService = await PocketbaseService({})
const { url, exitCode } = await pbService.spawn({
version: MOTHERSHIP_SEMVER(),
subdomain: MOTHERSHIP_NAME(),
instanceId: MOTHERSHIP_NAME(),
port: MOTHERSHIP_PORT(),
dev: DEBUG(),
env: {
DATA_ROOT: mkContainerHomePath(`data`), DATA_ROOT: mkContainerHomePath(`data`),
LS_WEBHOOK_SECRET: LS_WEBHOOK_SECRET(), LS_WEBHOOK_SECRET: LS_WEBHOOK_SECRET(),
}, }
extraBinds: [ dbg(env)
`${DATA_ROOT()}:${mkContainerHomePath(`data`)}`,
`${MOTHERSHIP_HOOKS_DIR()}:${mkContainerHomePath(`pb_hooks`)}`,
`${PH_VERSIONS()}:${mkContainerHomePath(`pb_hooks`, `versions.js`)}`,
`${MOTHERSHIP_MIGRATIONS_DIR()}:${mkContainerHomePath(
`pb_migrations`,
)}`,
`${MOTHERSHIP_APP_DIR()}:${mkContainerHomePath(`ph_app`)}`,
],
})
info(`Mothership URL for this session is ${url}`)
exitCode.then((c) => {
gracefulExit(c)
})
} else {
await rimraf(MOTHERSHIP_DATA_ROOT(`pb_hooks`)) await rimraf(MOTHERSHIP_DATA_ROOT(`pb_hooks`))
await _copy(MOTHERSHIP_HOOKS_DIR(`**/*`), MOTHERSHIP_DATA_ROOT(`pb_hooks`)) await _copy(MOTHERSHIP_HOOKS_DIR(`**/*`), MOTHERSHIP_DATA_ROOT(`pb_hooks`))
await _copy(PH_VERSIONS(), MOTHERSHIP_DATA_ROOT(`pb_hooks`))
await rimraf(MOTHERSHIP_DATA_ROOT(`pb_migrations`)) await rimraf(MOTHERSHIP_DATA_ROOT(`pb_migrations`))
await _copy( await _copy(
MOTHERSHIP_MIGRATIONS_DIR(`**/*`), MOTHERSHIP_MIGRATIONS_DIR(`**/*`),
MOTHERSHIP_DATA_ROOT(`pb_migrations`), MOTHERSHIP_DATA_ROOT(`pb_migrations`),
) )
await freshenPocketbaseVersions()
const args = [ const args = [
`serve`, `serve`,
`--http`, `--http`,
@ -111,14 +80,12 @@ export async function mothership(cfg: MothershipConfig) {
if (IS_DEV()) { if (IS_DEV()) {
args.push(`--dev`) args.push(`--dev`)
} }
dbg(args) const options: Partial<GobotOptions> = {
const process = run(args, {
env: {
DATA_ROOT: DATA_ROOT(),
LS_WEBHOOK_SECRET: LS_WEBHOOK_SECRET(),
},
version: MOTHERSHIP_SEMVER(), version: MOTHERSHIP_SEMVER(),
debug: DEBUG(), env,
})
} }
dbg(`args`, args)
dbg(`options`, options)
const bot = await gobot(`pocketbase`, options)
bot.run(args, { env })
} }

View File

@ -0,0 +1,14 @@
import { Command } from 'commander'
import { freshenPocketbaseVersions } from '../freshenPocketbaseVersions'
type Options = {}
export const UpdateCommand = () => {
const cmd = new Command(`update`)
.description(`Update known PocketBase versions`)
.action(async (options: Options) => {
const cjs = await freshenPocketbaseVersions()
console.log(cjs)
})
return cmd
}

View File

@ -1,3 +1,7 @@
import { MOTHERSHIP_DATA_ROOT } from '$constants'
import { writeFileSync } from 'fs'
import { gobot } from 'gobot'
function compareSemVer(a: string, b: string): number { function compareSemVer(a: string, b: string): number {
// Consider wildcards as higher than any version number, hence represented by a large number for comparison // Consider wildcards as higher than any version number, hence represented by a large number for comparison
let splitA = a let splitA = a
@ -18,7 +22,7 @@ function compareSemVer(a: string, b: string): number {
return 0 return 0
} }
export function expandAndSortSemVers(semvers: string[]): string[] { function expandAndSortSemVers(semvers: string[]): string[] {
let expandedVersions = new Set<string>() // Use a set to avoid duplicates let expandedVersions = new Set<string>() // Use a set to avoid duplicates
// Helper function to add wildcard versions // Helper function to add wildcard versions
@ -44,3 +48,12 @@ export function expandAndSortSemVers(semvers: string[]): string[] {
// Convert the set to an array and sort it using the custom semver comparison function // Convert the set to an array and sort it using the custom semver comparison function
return Array.from(expandedVersions).sort(compareSemVer) return Array.from(expandedVersions).sort(compareSemVer)
} }
export async function freshenPocketbaseVersions() {
const bot = await gobot(`pocketbase`)
const rawVersions = await bot.versions()
const versions = expandAndSortSemVers(rawVersions)
const cjs = `module.exports = ${JSON.stringify(versions, null, 2)}`
writeFileSync(MOTHERSHIP_DATA_ROOT(`pb_hooks`, `versions.cjs`), cjs)
return cjs
}

View File

@ -1,5 +1,6 @@
import { Command } from 'commander' import { Command } from 'commander'
import { ServeCommand } from './ServeCommand' import { ServeCommand } from './ServeCommand'
import { UpdateCommand } from './UpdateCommand'
type Options = { type Options = {
debug: boolean debug: boolean
@ -9,5 +10,6 @@ export const MothershipCommand = () => {
const cmd = new Command(`mothership`) const cmd = new Command(`mothership`)
.description(`Mothership commands`) .description(`Mothership commands`)
.addCommand(ServeCommand()) .addCommand(ServeCommand())
.addCommand(UpdateCommand())
return cmd return cmd
} }

View File

@ -4,7 +4,6 @@ import { DEBUG, DefaultSettingsService, SETTINGS } from '$constants'
import { LogLevelName, LoggerService } from '$shared' import { LogLevelName, LoggerService } from '$shared'
import { program } from 'commander' import { program } from 'commander'
import EventSource from 'eventsource' import EventSource from 'eventsource'
import { DownloadCommand } from './commands/DownloadCommand'
import { EdgeCommand } from './commands/EdgeCommand' import { EdgeCommand } from './commands/EdgeCommand'
import { FirewallCommand } from './commands/FirewallCommand' import { FirewallCommand } from './commands/FirewallCommand'
import { HealthCommand } from './commands/HealthCommand' import { HealthCommand } from './commands/HealthCommand'
@ -33,7 +32,6 @@ export const main = async () => {
.addCommand(FirewallCommand()) .addCommand(FirewallCommand())
.addCommand(SendMailCommand()) .addCommand(SendMailCommand())
.addCommand(ServeCommand()) .addCommand(ServeCommand())
.addCommand(DownloadCommand())
await program.parseAsync() await program.parseAsync()
} }

View File

@ -44,13 +44,14 @@ export const _MOTHERSHIP_NAME =
export const _MOTHERSHIP_APP_ROOT = (...paths: string[]) => export const _MOTHERSHIP_APP_ROOT = (...paths: string[]) =>
join( join(
process.env.PH_MOTHERSHIP_APP_ROOT || process.env.PH_MOTHERSHIP_APP_ROOT ||
join(_PH_PROJECT_ROOT, 'mothership-app'), join(_PH_PROJECT_ROOT, `src`, 'mothership-app'),
...paths, ...paths,
) )
export const _INSTANCE_APP_ROOT = (...paths: string[]) => export const _INSTANCE_APP_ROOT = (...paths: string[]) =>
join( join(
process.env.PH_INSTANCE_APP_ROOT || join(_PH_PROJECT_ROOT, 'instance-app'), process.env.PH_INSTANCE_APP_ROOT ||
join(_PH_PROJECT_ROOT, `src`, 'instance-app'),
...paths, ...paths,
) )
@ -67,7 +68,6 @@ export const SETTINGS = {
UPGRADE_MODE: mkBoolean(false), UPGRADE_MODE: mkBoolean(false),
PH_HOME: mkPath(_PH_HOME), PH_HOME: mkPath(_PH_HOME),
PH_VERSIONS: mkPath(join(_PH_HOME, `versions.js`), { required: false }),
PH_PROJECT_ROOT: mkPath(_PH_PROJECT_ROOT), PH_PROJECT_ROOT: mkPath(_PH_PROJECT_ROOT),
DEBUG: mkBoolean(_IS_DEV), DEBUG: mkBoolean(_IS_DEV),
@ -95,7 +95,7 @@ export const SETTINGS = {
MOTHERSHIP_APP_DIR: mkPath(_MOTHERSHIP_APP_ROOT(`ph_app`), { MOTHERSHIP_APP_DIR: mkPath(_MOTHERSHIP_APP_ROOT(`ph_app`), {
required: false, required: false,
}), }),
MOTHERSHIP_SEMVER: mkString(''), MOTHERSHIP_SEMVER: mkString('*'),
MOTHERSHIP_PORT: mkNumber(8091), MOTHERSHIP_PORT: mkNumber(8091),
INITIAL_PORT_POOL_SIZE: mkNumber(20), INITIAL_PORT_POOL_SIZE: mkNumber(20),
@ -103,7 +103,6 @@ export const SETTINGS = {
NODE_ENV: mkString(`production`), NODE_ENV: mkString(`production`),
IS_DEV: mkBoolean(_IS_DEV), IS_DEV: mkBoolean(_IS_DEV),
TRACE: mkBoolean(false), TRACE: mkBoolean(false),
PH_BIN_CACHE: mkPath(join(_PH_HOME, '.pbincache'), { create: true }),
PH_FTP_PORT: mkNumber(21), PH_FTP_PORT: mkNumber(21),
SSL_KEY: mkPath(join(_SSL_HOME, `${TLS_PFX}.key`)), SSL_KEY: mkPath(join(_SSL_HOME, `${TLS_PFX}.key`)),
@ -190,7 +189,6 @@ export const instanceLogger = () => ioc.service('instanceLogger')
export const UPGRADE_MODE = () => settings().UPGRADE_MODE export const UPGRADE_MODE = () => settings().UPGRADE_MODE
export const PH_HOME = () => settings().PH_HOME export const PH_HOME = () => settings().PH_HOME
export const PH_VERSIONS = () => settings().PH_VERSIONS
export const PH_PROJECT_ROOT = () => settings().PH_PROJECT_ROOT export const PH_PROJECT_ROOT = () => settings().PH_PROJECT_ROOT
export const DEBUG = () => settings().DEBUG export const DEBUG = () => settings().DEBUG
@ -229,7 +227,6 @@ export const DATA_ROOT = () => settings().DATA_ROOT
export const NODE_ENV = () => settings().NODE_ENV export const NODE_ENV = () => settings().NODE_ENV
export const IS_DEV = () => settings().IS_DEV export const IS_DEV = () => settings().IS_DEV
export const TRACE = () => settings().TRACE export const TRACE = () => settings().TRACE
export const PH_BIN_CACHE = () => settings().PH_BIN_CACHE
export const PH_FTP_PORT = () => settings().PH_FTP_PORT export const PH_FTP_PORT = () => settings().PH_FTP_PORT
export const SSL_KEY = () => settings().SSL_KEY export const SSL_KEY = () => settings().SSL_KEY

View File

@ -8,7 +8,9 @@ routerAdd(
'/api/instance', '/api/instance',
(c) => { (c) => {
const dao = $app.dao() const dao = $app.dao()
const { audit, mkLog } = /** @type {Lib} */ (require(`${__hooks}/lib.js`)) const { audit, mkLog, versions } = /** @type {Lib} */ (
require(`${__hooks}/lib.js`)
)
const log = mkLog(`POST:instance`) const log = mkLog(`POST:instance`)
@ -45,8 +47,6 @@ routerAdd(
) )
} }
const { versions } = require(`${__hooks}/versions.js`)
const collection = dao.findCollectionByNameOrId('instances') const collection = dao.findCollectionByNameOrId('instances')
const record = new Record(collection) const record = new Record(collection)
record.set('uid', authRecord.getId()) record.set('uid', authRecord.getId())

View File

@ -1,12 +1,13 @@
/** Migrate version numbers */ /** Migrate version numbers */
onAfterBootstrap((e) => { onAfterBootstrap((e) => {
const dao = $app.dao() const dao = $app.dao()
const { audit, mkLog } = /** @type {Lib} */ (require(`${__hooks}/lib.js`)) const { audit, mkLog, versions } = /** @type {Lib} */ (
require(`${__hooks}/lib.js`)
)
const log = mkLog(`bootstrap`) const log = mkLog(`bootstrap`)
const records = dao.findRecordsByFilter(`instances`, '1=1') const records = dao.findRecordsByFilter(`instances`, '1=1')
const { versions } = require(`${__hooks}/versions.js`)
const unrecognized = [] const unrecognized = []
records.forEach((record) => { records.forEach((record) => {
const v = record.get('version').trim() const v = record.get('version').trim()

View File

@ -2,8 +2,9 @@
/** Validate instance version */ /** Validate instance version */
onModelBeforeCreate((e) => { onModelBeforeCreate((e) => {
const { versions } = /** @type {Lib} */ (require(`${__hooks}/lib.js`))
const dao = e.dao || $app.dao() const dao = e.dao || $app.dao()
const { versions } = require(`${__hooks}/versions.js`)
const version = e.model.get('version') const version = e.model.get('version')
if (!versions.includes(version)) { if (!versions.includes(version)) {

View File

@ -3,7 +3,7 @@
/** Validate instance version */ /** Validate instance version */
onModelBeforeUpdate((e) => { onModelBeforeUpdate((e) => {
const dao = e.dao || $app.dao() const dao = e.dao || $app.dao()
const { versions } = require(`${__hooks}/versions.js`) const { versions } = /** @type {Lib} */ (require(`${__hooks}/lib.js`))
const version = e.model.get('version') const version = e.model.get('version')
if (!versions.includes(version)) { if (!versions.includes(version)) {

View File

@ -162,10 +162,14 @@ function removeEmptyKeys(obj) {
return sanitized return sanitized
} }
/** @type {Lib['versions']} */
const versions = require(`${__hooks}/versions.cjs`)
module.exports = { module.exports = {
audit, audit,
processNotification, processNotification,
mkLog, mkLog,
enqueueNotification, enqueueNotification,
removeEmptyKeys, removeEmptyKeys,
versions,
} }

View File

@ -102,6 +102,8 @@ routerAdd(
'POST', 'POST',
'/api/signup', '/api/signup',
(c) => { (c) => {
const { versions } = /** @type {Lib} */ (require(`${__hooks}/lib.js`))
const dao = $app.dao() const dao = $app.dao()
const parsed = (() => { const parsed = (() => {
const rawBody = readerToString(c.request().body) const rawBody = readerToString(c.request().body)
@ -192,7 +194,6 @@ routerAdd(
instance.set('status', 'idle') instance.set('status', 'idle')
instance.set('notifyMaintenanceMode', true) instance.set('notifyMaintenanceMode', true)
instance.set('syncAdmin', true) instance.set('syncAdmin', true)
const { versions } = require(`${__hooks}/versions.js`)
instance.set('version', versions[0]) instance.set('version', versions[0])
txDao.saveRecord(instance) txDao.saveRecord(instance)
} catch (e) { } catch (e) {

View File

@ -5,7 +5,7 @@ routerAdd(
'GET', 'GET',
'/api/versions', '/api/versions',
(c) => { (c) => {
const { versions } = require(`${__hooks}/versions.js`) const { versions } = /** @type {Lib} */ (require(`${__hooks}/lib.js`))
return c.json(200, { versions }) return c.json(200, { versions })
} /* optional middlewares */, } /* optional middlewares */,

View File

@ -0,0 +1,159 @@
module.exports = [
"0.22.*",
"0.22.12",
"0.22.11",
"0.22.10",
"0.22.9",
"0.22.8",
"0.22.7",
"0.22.6",
"0.22.5",
"0.22.4",
"0.22.3",
"0.22.2",
"0.22.1",
"0.22.0",
"0.21.*",
"0.21.3",
"0.21.2",
"0.21.1",
"0.21.0",
"0.20.*",
"0.20.7",
"0.20.6",
"0.20.5",
"0.20.4",
"0.20.3",
"0.20.2",
"0.20.1",
"0.20.0",
"0.20.0-rc3",
"0.20.0-rc2",
"0.20.0-rc",
"0.19.*",
"0.19.4",
"0.19.3",
"0.19.2",
"0.19.1",
"0.19.0",
"0.18.*",
"0.18.10",
"0.18.9",
"0.18.8",
"0.18.7",
"0.18.6",
"0.18.5",
"0.18.4",
"0.18.3",
"0.18.2",
"0.18.1",
"0.18.0",
"0.17.*",
"0.17.7",
"0.17.6",
"0.17.5",
"0.17.4",
"0.17.3",
"0.17.2",
"0.17.1",
"0.17.0",
"0.16.*",
"0.16.10",
"0.16.9",
"0.16.8",
"0.16.7",
"0.16.6",
"0.16.5",
"0.16.4",
"0.16.3",
"0.16.2",
"0.16.1",
"0.16.0",
"0.15.*",
"0.15.3",
"0.15.2",
"0.15.1",
"0.15.0",
"0.14.*",
"0.14.5",
"0.14.4",
"0.14.3",
"0.14.2",
"0.14.1",
"0.14.0",
"0.13.*",
"0.13.4",
"0.13.3",
"0.13.2",
"0.13.1",
"0.13.0",
"0.12.*",
"0.12.3",
"0.12.2",
"0.12.1",
"0.12.0",
"0.11.*",
"0.11.4",
"0.11.3",
"0.11.2",
"0.11.1",
"0.11.0",
"0.10.*",
"0.10.4",
"0.10.3",
"0.10.2",
"0.10.1",
"0.10.0",
"0.9.*",
"0.9.2",
"0.9.1",
"0.9.0",
"0.8.*",
"0.8.0",
"0.8.0-rc4",
"0.8.0-rc3",
"0.8.0-rc2",
"0.8.0-rc1",
"0.7.*",
"0.7.10",
"0.7.9",
"0.7.8",
"0.7.7",
"0.7.6",
"0.7.5",
"0.7.4",
"0.7.3",
"0.7.2",
"0.7.1",
"0.7.0",
"0.6.*",
"0.6.0",
"0.5.*",
"0.5.2",
"0.5.1",
"0.5.0",
"0.4.*",
"0.4.2",
"0.4.1",
"0.4.0",
"0.3.*",
"0.3.4",
"0.3.3",
"0.3.2",
"0.3.1",
"0.3.0",
"0.2.*",
"0.2.8",
"0.2.7",
"0.2.6",
"0.2.5",
"0.2.4",
"0.2.3",
"0.2.2",
"0.2.1",
"0.2.0",
"0.1.*",
"0.1.2",
"0.1.1",
"0.1.0"
]

View File

@ -52,4 +52,5 @@ interface Lib {
}, },
) => void ) => void
removeEmptyKeys: <T>(obj: T) => T removeEmptyKeys: <T>(obj: T) => T
versions: string[]
} }

View File

@ -457,6 +457,9 @@ export const instanceService = mkSingleton(
} }
}) })
if (instance) { if (instance) {
if (!instance.cname_active) {
throw new Error(`CNAME blocked.`)
}
dbg(`${host} is a cname`) dbg(`${host} is a cname`)
cache.setItem(instance) cache.setItem(instance)
return instance return instance

View File

@ -16,11 +16,11 @@ import { asyncExitHook, mkInternalUrl, SyslogLogger, tryFetch } from '$util'
import { map } from '@s-libs/micro-dash' import { map } from '@s-libs/micro-dash'
import Docker, { Container, ContainerCreateOptions } from 'dockerode' import Docker, { Container, ContainerCreateOptions } from 'dockerode'
import { existsSync } from 'fs' import { existsSync } from 'fs'
import { gobot } from 'gobot'
import MemoryStream from 'memorystream' import MemoryStream from 'memorystream'
import { gte } from 'semver' import { gte } from 'semver'
import { EventEmitter } from 'stream' import { EventEmitter } from 'stream'
import { AsyncReturnType } from 'type-fest' import { AsyncReturnType } from 'type-fest'
import { PocketbaseReleaseVersionService } from '../PocketbaseReleaseVersionService'
export type Env = { [_: string]: string } export type Env = { [_: string]: string }
export type SpawnConfig = { export type SpawnConfig = {
@ -54,9 +54,11 @@ export const createPocketbaseService = async (
const _serviceLogger = LoggerService().create('PocketbaseService') const _serviceLogger = LoggerService().create('PocketbaseService')
const { dbg, error, warn, abort } = _serviceLogger const { dbg, error, warn, abort } = _serviceLogger
const { getLatestVersion, getVersion } = const bot = await gobot(`pocketbase`, { os: 'linux' })
await PocketbaseReleaseVersionService() const maxVersion = (await bot.versions())[0]
const maxVersion = getLatestVersion() if (!maxVersion) {
throw new Error(`No max version found for PocketBase`)
}
const _spawn = async (cfg: SpawnConfig) => { const _spawn = async (cfg: SpawnConfig) => {
const cm = createCleanupManager() const cm = createCleanupManager()
@ -98,8 +100,11 @@ export const createPocketbaseService = async (
}) })
const _version = version || maxVersion // If _version is blank, we use the max version available const _version = version || maxVersion // If _version is blank, we use the max version available
const realVersion = await getVersion(_version) const realVersion = await bot.maxSatisfyingVersion(_version)
const binPath = realVersion.binPath if (!realVersion) {
throw new Error(`No PocketBase version satisfying ${_version}`)
}
const binPath = await bot.getBinaryPath(realVersion)
if (!existsSync(binPath)) { if (!existsSync(binPath)) {
throw new Error( throw new Error(
`PocketBase binary (${binPath}) not found. Contact pockethost.io.`, `PocketBase binary (${binPath}) not found. Contact pockethost.io.`,
@ -138,7 +143,7 @@ export const createPocketbaseService = async (
Env: map( Env: map(
{ {
...env, ...env,
DEV: dev && gte(realVersion.version, `0.20.1`), DEV: dev && gte(realVersion, `0.20.1`),
PH_APEX_DOMAIN: APEX_DOMAIN(), PH_APEX_DOMAIN: APEX_DOMAIN(),
}, },
(v, k) => `${k}=${v}`, (v, k) => `${k}=${v}`,

View File

@ -1,128 +0,0 @@
import { PH_BIN_CACHE, PH_VERSIONS } from '$constants'
import { LoggerService, SingletonBaseConfig, mkSingleton } from '$shared'
import { downloadAndExtract, mergeConfig, smartFetch } from '$util'
import { keys } from '@s-libs/micro-dash'
import Bottleneck from 'bottleneck'
import { chmodSync, existsSync, writeFileSync } from 'fs'
import { join } from 'path'
import { rsort } from 'semver'
import { expandAndSortSemVers } from './expandAndSortSemVers'
type Release = {
url: string
tag_name: string
prerelease: string
assets: {
name: string
browser_download_url: string
}[]
}
type Releases = Release[]
export type PocketbaseReleaseDownloadServiceConfig = SingletonBaseConfig & {
onlyOne: boolean
binCachePath: string
versionsCachePath: string
}
export const PocketbaseReleaseDownloadService = mkSingleton(
(config: Partial<PocketbaseReleaseDownloadServiceConfig> = {}) => {
const { binCachePath, versionsCachePath, onlyOne } = mergeConfig(
{
binCachePath: PH_BIN_CACHE(),
versionsCachePath: PH_VERSIONS(),
onlyOne: false,
},
config,
)
const _serviceLogger = LoggerService().create(
'PocketbaseReleaseDownloadService',
)
const { dbg, info, error, warn, abort } = _serviceLogger
dbg(`Initializing`)
const osName = 'linux' // type().toLowerCase()
const cpuArchitecture = process.arch === 'x64' ? 'amd64' : process.arch
dbg({ osName, cpuArchitecture })
const binPaths: { [_: string]: string } = {}
let maxVersion = ''
const check = async () => {
info(`Fetching info for PocketBase releases...`)
let releases = await smartFetch<Releases>(
`https://api.github.com/repos/pocketbase/pocketbase/releases?per_page=100`,
join(binCachePath, `releases.json`),
)
// dbg({ releases })
type Defined<T> = Exclude<T, undefined>
type NoUndefinedProperties<T> = {
[K in keyof T]: Defined<T[K]>
}
const filteredReleases = releases
.filter((release) => !release.prerelease)
.map((release) => {
const { tag_name, assets } = release
const sanitizedTagName = tag_name.slice(1)
const path = join(binCachePath, tag_name)
const url = assets.find((v) => {
// dbg(v.name)
return v.name.includes(osName) && v.name.includes(cpuArchitecture)
})?.browser_download_url
return { url, sanitizedTagName, path }
})
.filter(
(release): release is NoUndefinedProperties<typeof release> =>
!!release.url,
)
if (filteredReleases.length === 0) return
const limiter = new Bottleneck({ maxConcurrent: 5 })
const promises = (
onlyOne ? [filteredReleases[0]!] : filteredReleases
).map((release) =>
limiter.schedule(async () => {
const { url, sanitizedTagName, path } = release
const binPath = join(path, `pocketbase`)
info(`Checking ${binPath}`)
if (existsSync(binPath)) {
chmodSync(binPath, 0o775)
} else {
info(`Downloading ${url}...`)
await downloadAndExtract(url, binPath, _serviceLogger)
}
binPaths[sanitizedTagName] = binPath
}),
)
await Promise.all(promises)
console.log(`***keys`, keys(binPaths))
const sortedSemVers = expandAndSortSemVers(keys(binPaths))
writeFileSync(
versionsCachePath,
`module.exports = ${JSON.stringify({ versions: sortedSemVers })}`,
)
info(`Saved to ${versionsCachePath}`, sortedSemVers)
if (keys(binPaths).length === 0) {
throw new Error(
`No version found, probably mismatched architecture and OS (${osName}/${cpuArchitecture})`,
)
}
maxVersion = `~${rsort(keys(binPaths))[0]}`
info(`Highest PocketBase version is ${maxVersion}`)
}
return {
check,
}
},
)

View File

@ -1,86 +0,0 @@
import { PH_BIN_CACHE } from '$constants'
import {
createTimerManager,
LoggerService,
mkSingleton,
SingletonBaseConfig,
} from '$shared'
import { mergeConfig } from '$util'
import { keys } from '@s-libs/micro-dash'
import { chmodSync, existsSync } from 'fs'
import { glob } from 'glob'
import { basename, join } from 'path'
import { maxSatisfying, rsort } from 'semver'
export type PocketbaseReleaseVersionService = SingletonBaseConfig & {
cachePath: string
checkIntervalMs: number
}
export const PocketbaseReleaseVersionService = mkSingleton(
async (config: Partial<PocketbaseReleaseVersionService> = {}) => {
const _serviceLogger = LoggerService().create(
'PocketbaseReleaseVersionService',
)
const { dbg, error, warn, abort } = _serviceLogger
dbg(`Initializing`)
const { cachePath, checkIntervalMs } = mergeConfig(
{
cachePath: PH_BIN_CACHE(),
checkIntervalMs: 1000 * 5 * 60,
},
config,
)
const binPaths: { [_: string]: string } = {}
let maxVersion = ''
const tm = createTimerManager()
const check = async () => {
const versions = await glob(join(cachePath, `v*/`))
versions.forEach((path) => {
const version = basename(path)
const sanitizedTagName = version.slice(1)
dbg(`Found a version ${sanitizedTagName}`)
const binPath = join(path, `pocketbase`)
dbg(`Checking ${binPath}`)
if (existsSync(binPath)) {
chmodSync(binPath, 0o775)
}
binPaths[sanitizedTagName] = binPath
})
maxVersion = `~${rsort(keys(binPaths))[0]}`
dbg({ maxVersion })
return true
}
await check().catch(error)
tm.repeat(check, checkIntervalMs, false)
const getLatestVersion = () => maxVersion
const getVersion = (semVer = maxVersion) => {
const version = maxSatisfying(keys(binPaths), semVer)
if (!version)
throw new Error(
`No version satisfies ${semVer} (${keys(binPaths).join(', ')})`,
)
const binPath = binPaths[version]
if (!binPath) throw new Error(`binPath for ${version} not found`)
return {
version,
binPath,
}
}
return {
getLatestVersion,
getVersion,
}
},
)

View File

@ -3,8 +3,6 @@ export * from './InstanceLoggerService'
export * from './InstanceService' export * from './InstanceService'
export * from './MothershipAdminClientService' export * from './MothershipAdminClientService'
export * from './PocketBaseService' export * from './PocketBaseService'
export * from './PocketbaseReleaseDownloadService'
export * from './PocketbaseReleaseVersionService'
export * from './PortService' export * from './PortService'
export * from './ProxyService' export * from './ProxyService'
export * from './RealtimeLog' export * from './RealtimeLog'

View File

@ -1,47 +0,0 @@
import { Logger, singletonAsyncExecutionGuard } from '$shared'
import decompress from 'decompress'
import decompressUnzip from 'decompress-unzip'
import { chmodSync, createWriteStream } from 'fs'
import fetch from 'node-fetch'
import { dirname } from 'path'
import { assert } from './assert'
const downloadFile = async (url: string, path: string) => {
const { body } = await fetch(url)
assert(body, `Body is null`)
const fileStream = createWriteStream(path)
await new Promise<void>((resolve, reject) => {
body.pipe(fileStream)
body.on('error', reject)
fileStream.on('finish', resolve)
})
}
const _unsafe_downloadAndExtract = async (
url: string,
binPath: string,
logger: Logger,
) => {
const { dbg, info, error } = logger.create('downloadAndExtract')
dbg(`Fetching ${url}`)
const res = await fetch(url)
const { body } = res
if (!body) {
throw new Error(`Body expected for ${url}`)
}
const versionPath = dirname(binPath)
const zipPath = `${versionPath}.zip`
dbg(`Downloading ${url} to ${zipPath}`)
await downloadFile(url, zipPath)
// const tmpPath = tmpNameSync({ dir: TMP_DIR })
dbg(`Extracting ${zipPath} to ${versionPath}`)
await decompress(zipPath, versionPath, { plugins: [decompressUnzip()] })
// renameSync(tmpPath, versionPath)
chmodSync(binPath, 0o775)
}
export const downloadAndExtract = singletonAsyncExecutionGuard(
_unsafe_downloadAndExtract,
(url) => url,
)

View File

@ -3,7 +3,6 @@ export * from './Settings'
export * from './SyslogLogger' export * from './SyslogLogger'
export * from './assert' export * from './assert'
export * from './discordAlert' export * from './discordAlert'
export * from './downloadAndExtract'
export * from './env' export * from './env'
export * from './exit' export * from './exit'
export * from './internal' export * from './internal'