pockethost 1.7.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +119 -86
- package/README.md +96 -0
- package/dist/cli.js +21542 -0
- package/package.json +55 -55
- package/changesetx.ts +0 -110
- package/common.ts +0 -1
- package/core.ts +0 -1
- package/readme.md +0 -129
- package/src/cli/commands/ConfigCommand/index.ts +0 -28
- package/src/cli/commands/PluginCommand/index.ts +0 -113
- package/src/cli/commands/PluginCommand/plugin-template/package.json +0 -38
- package/src/cli/commands/PluginCommand/plugin-template/readme.md +0 -33
- package/src/cli/commands/PluginCommand/plugin-template/src/constants.ts +0 -22
- package/src/cli/commands/PluginCommand/plugin-template/src/db.ts +0 -30
- package/src/cli/commands/PluginCommand/plugin-template/src/index.ts +0 -3
- package/src/cli/commands/PluginCommand/plugin-template/src/log.ts +0 -5
- package/src/cli/commands/PluginCommand/plugin-template/src/plugin.ts +0 -58
- package/src/cli/commands/PluginCommand/util.ts +0 -140
- package/src/cli/commands/ServeCommand/index.ts +0 -36
- package/src/cli/index.ts +0 -70
- package/src/common/CleanupManager.ts +0 -65
- package/src/common/Logger.ts +0 -174
- package/src/common/ResourceAllocator.ts +0 -49
- package/src/common/TimerManager.ts +0 -64
- package/src/common/assert.ts +0 -26
- package/src/common/debug.ts +0 -8
- package/src/common/error.ts +0 -16
- package/src/common/events.ts +0 -53
- package/src/common/index.ts +0 -12
- package/src/common/mergeConfig.ts +0 -27
- package/src/common/mkSingleton.ts +0 -28
- package/src/common/plugin/action.ts +0 -164
- package/src/common/plugin/filter.ts +0 -197
- package/src/common/plugin/index.ts +0 -21
- package/src/common/promiseSerializer.ts +0 -22
- package/src/common/schema/BaseFields.ts +0 -10
- package/src/common/schema/Instance.ts +0 -46
- package/src/common/schema/InstanceLog.ts +0 -12
- package/src/common/schema/index.ts +0 -3
- package/src/common/schema/util.ts +0 -7
- package/src/constants.ts +0 -70
- package/src/core/Settings.ts +0 -119
- package/src/core/asyncExecutionGuard.ts +0 -49
- package/src/core/config.ts +0 -108
- package/src/core/exit.ts +0 -11
- package/src/core/index.ts +0 -8
- package/src/core/internal.ts +0 -3
- package/src/core/smartFetch.ts +0 -32
- package/src/core/tryFetch.ts +0 -69
- package/src/plugin.ts +0 -54
- package/src/server.ts +0 -129
- /package/{src/cli/commands/PluginCommand/plugin-template/LICENSE.md → LICENSE.md} +0 -0
package/package.json
CHANGED
|
@@ -1,69 +1,69 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pockethost",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
"
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "The PocketHost CLI: deploy, sync, and tail logs for your PocketHost instances",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/pockethost/pockethost.git",
|
|
8
|
+
"directory": "packages/cli"
|
|
7
9
|
},
|
|
10
|
+
"homepage": "https://pockethost.io",
|
|
11
|
+
"keywords": [
|
|
12
|
+
"cli",
|
|
13
|
+
"pocketbase",
|
|
14
|
+
"pockethost"
|
|
15
|
+
],
|
|
16
|
+
"author": "Ben Allfree",
|
|
8
17
|
"license": "MIT",
|
|
9
|
-
"
|
|
10
|
-
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/pockethost/pockethost/issues"
|
|
20
|
+
},
|
|
11
21
|
"type": "module",
|
|
12
22
|
"bin": {
|
|
13
|
-
"pockethost": "
|
|
23
|
+
"pockethost": "dist/cli.js"
|
|
24
|
+
},
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=20"
|
|
14
27
|
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"CHANGELOG.md",
|
|
31
|
+
"README.md"
|
|
32
|
+
],
|
|
15
33
|
"dependencies": {
|
|
16
|
-
"
|
|
17
|
-
"ajv": "^8.12.0",
|
|
18
|
-
"boolean": "^3.2.0",
|
|
19
|
-
"bottleneck": "^2.19.5",
|
|
20
|
-
"chalk": "^5.3.0",
|
|
21
|
-
"commander": "^11.1.0",
|
|
22
|
-
"dotenv": "^16.3.1",
|
|
23
|
-
"env-paths": "^3.0.0",
|
|
24
|
-
"exit-hook": "^4.0.0",
|
|
25
|
-
"express": "^4.18.2",
|
|
26
|
-
"express-async-errors": "^3.1.1",
|
|
27
|
-
"get-port": "^6.1.2",
|
|
28
|
-
"http-proxy": "^1.18.1",
|
|
29
|
-
"immer": "^10.1.1",
|
|
30
|
-
"inflection": "^3.0.0",
|
|
31
|
-
"json-stringify-safe": "^5.0.1",
|
|
32
|
-
"listr2": "^8.2.3",
|
|
33
|
-
"minimist": "^1.2.8",
|
|
34
|
-
"nanoid": "^5.0.2",
|
|
35
|
-
"node-fetch": "^3.3.2",
|
|
36
|
-
"node-plop": "^0.32.0",
|
|
37
|
-
"pocketbase": "^0.21.3",
|
|
38
|
-
"rimraf": "^5.0.5",
|
|
39
|
-
"semver": "^7.6.2",
|
|
40
|
-
"tmp": "^0.2.1",
|
|
41
|
-
"tsx": "^4.15.7",
|
|
42
|
-
"type-fest": "^4.6.0",
|
|
43
|
-
"typescript": "^5.4.5",
|
|
44
|
-
"update-notifier": "^7.0.0",
|
|
45
|
-
"url-pattern": "^1.0.3",
|
|
46
|
-
"@pockethost/plugin-auto-admin": "^0.2.0",
|
|
47
|
-
"@pockethost/plugin-console-logger": "^0.3.0",
|
|
48
|
-
"@pockethost/plugin-launcher-spawn": "^0.4.0"
|
|
34
|
+
"ssh2-sftp-client": "^12.1.1"
|
|
49
35
|
},
|
|
50
36
|
"devDependencies": {
|
|
51
|
-
"@
|
|
52
|
-
"@
|
|
53
|
-
"@types/
|
|
54
|
-
"@types/
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
37
|
+
"@inquirer/prompts": "^8.5.2",
|
|
38
|
+
"@microsoft/fetch-event-source": "github:pockethost/fetch-event-source#ebe3b7122647b48b93fd11effbbfb915d98956b0",
|
|
39
|
+
"@types/node": "^20.0.0",
|
|
40
|
+
"@types/ssh2-sftp-client": "^9.0.6",
|
|
41
|
+
"bottleneck": "^2.19.5",
|
|
42
|
+
"chokidar": "^5.0.0",
|
|
43
|
+
"commander": "^15.0.0",
|
|
44
|
+
"env-paths": "^4.0.0",
|
|
45
|
+
"env-var": "^7.5.0",
|
|
46
|
+
"esbuild": "^0.28.1",
|
|
47
|
+
"glob": "^13.0.6",
|
|
48
|
+
"multimatch": "^8.0.0",
|
|
49
|
+
"ora": "^9.4.0",
|
|
50
|
+
"pocketbase": "^0.27.0",
|
|
51
|
+
"pretty-bytes": "^7.1.0",
|
|
52
|
+
"pretty-ms": "^9.3.0",
|
|
53
|
+
"tsx": "^4.22.4",
|
|
54
|
+
"typescript": "^6.0.3",
|
|
55
|
+
"vitest": "^4.1.8"
|
|
56
|
+
},
|
|
57
|
+
"prettier": {
|
|
58
|
+
"semi": false,
|
|
59
|
+
"singleQuote": true,
|
|
60
|
+
"trailingComma": "es5"
|
|
62
61
|
},
|
|
63
62
|
"scripts": {
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"dev": "
|
|
67
|
-
"start": "tsx ./src/cli
|
|
63
|
+
"build": "node scripts/build.mjs",
|
|
64
|
+
"check:types": "tsc --noEmit",
|
|
65
|
+
"dev": "node --import tsx ./src/cli.ts",
|
|
66
|
+
"start": "node --import tsx ./src/cli.ts",
|
|
67
|
+
"test": "vitest run"
|
|
68
68
|
}
|
|
69
69
|
}
|
package/changesetx.ts
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env tsx
|
|
2
|
-
import { execSync } from 'child_process'
|
|
3
|
-
import { sync } from 'conventional-commits-parser'
|
|
4
|
-
import fs, { readFileSync } from 'fs'
|
|
5
|
-
import minimist from 'minimist'
|
|
6
|
-
import { dirname, join } from 'path'
|
|
7
|
-
import { fileURLToPath } from 'url'
|
|
8
|
-
|
|
9
|
-
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
10
|
-
const repoRootDir = join(__dirname, `../..`)
|
|
11
|
-
|
|
12
|
-
const argv = minimist(process.argv.slice(2))
|
|
13
|
-
const commitMessage = argv._[0]!
|
|
14
|
-
const { type, subject } = sync(commitMessage)
|
|
15
|
-
if (!type) {
|
|
16
|
-
console.log('Invalid commit message type')
|
|
17
|
-
process.exit(1)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function getStagedPackageNames(filePaths: string[]): string[] {
|
|
21
|
-
const packageNames = new Set<string>()
|
|
22
|
-
|
|
23
|
-
filePaths.forEach((filePath) => {
|
|
24
|
-
const packageName = getPackageName(filePath)
|
|
25
|
-
if (packageName) {
|
|
26
|
-
packageNames.add(packageName)
|
|
27
|
-
}
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
return Array.from(packageNames)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function getPackageName(filePath: string): string | null {
|
|
34
|
-
const packagePath = filePath.split('/').slice(0, 2).join('/')
|
|
35
|
-
const packageJsonPath = join(repoRootDir, `${packagePath}/package.json`)
|
|
36
|
-
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'))
|
|
37
|
-
try {
|
|
38
|
-
return packageJson.name
|
|
39
|
-
} catch (error) {
|
|
40
|
-
return null
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function getStagedFileNames(): string[] {
|
|
45
|
-
const output = execSync('git diff --name-only --cached').toString()
|
|
46
|
-
const fileNames = output
|
|
47
|
-
.trim()
|
|
48
|
-
.split('\n')
|
|
49
|
-
.filter((fileName) => fileName.startsWith(`packages/`))
|
|
50
|
-
return fileNames
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
async function createChangesetFile() {
|
|
54
|
-
const fileNames = getStagedFileNames()
|
|
55
|
-
const packageNames = getStagedPackageNames(fileNames)
|
|
56
|
-
|
|
57
|
-
if (packageNames.length === 0) {
|
|
58
|
-
console.log('No packages staged for commit')
|
|
59
|
-
process.exit(0)
|
|
60
|
-
}
|
|
61
|
-
console.log('Staged packages:', packageNames)
|
|
62
|
-
|
|
63
|
-
const prefixMap = {
|
|
64
|
-
feat: 'minor',
|
|
65
|
-
enh: 'minor',
|
|
66
|
-
fix: 'patch',
|
|
67
|
-
docs: 'patch',
|
|
68
|
-
chore: 'patch',
|
|
69
|
-
} as const
|
|
70
|
-
|
|
71
|
-
if (!(type! in prefixMap)) {
|
|
72
|
-
console.log('Invalid prefix found in commit message')
|
|
73
|
-
process.exit(1)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const versionType = prefixMap[type as keyof typeof prefixMap]
|
|
77
|
-
|
|
78
|
-
const changesetFile = [
|
|
79
|
-
`---`,
|
|
80
|
-
...packageNames.map((packageName) => `'${packageName}': ${versionType}`),
|
|
81
|
-
`---`,
|
|
82
|
-
``,
|
|
83
|
-
subject,
|
|
84
|
-
].join('\n')
|
|
85
|
-
return changesetFile
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
async function writeChangesetFile(changesetFile: string) {
|
|
89
|
-
const filePath = join(repoRootDir, `.changeset`, `${+new Date()}.md`)
|
|
90
|
-
try {
|
|
91
|
-
fs.writeFileSync(filePath, changesetFile)
|
|
92
|
-
console.log(`Changeset file written successfully at ${filePath}`)
|
|
93
|
-
execSync(`git add ${filePath}`)
|
|
94
|
-
console.log(`Changeset file added to git`)
|
|
95
|
-
} catch (error) {
|
|
96
|
-
console.error(`Error writing changeset file: ${error}`)
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function commit() {
|
|
101
|
-
execSync(`git commit -m "${commitMessage}"`)
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
async function main() {
|
|
105
|
-
const changesetFile = await createChangesetFile()
|
|
106
|
-
await writeChangesetFile(changesetFile)
|
|
107
|
-
commit()
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
main()
|
package/common.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './src/common'
|
package/core.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './src/core'
|
package/readme.md
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
# PocketHost
|
|
2
|
-
|
|
3
|
-
PocketHost is the open source multi-tenant PocketBase server. PocketHost can run dozens, hundreds, even thousands of PocketBase instances on a single server or across a global cloud.
|
|
4
|
-
|
|
5
|
-
Extend PocketHost with its Plugin ecosystem. Start with the bare-bones dev server and add plugins to grow your enterprise into a global cloud.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
### Sponsored by https://pockethost.io. Instantly host your PocketBase projects.
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
<!-- @import "[TOC]" {cmd="toc" depthFrom=2 depthTo=2 orderedList=false} -->
|
|
14
|
-
|
|
15
|
-
<!-- code_chunk_output -->
|
|
16
|
-
|
|
17
|
-
- [Quickstart](#quickstart)
|
|
18
|
-
- [Introduction](#introduction)
|
|
19
|
-
- [The magic `serve` command](#the-magic-serve-command)
|
|
20
|
-
- [Configuration](#configuration)
|
|
21
|
-
- [Plugins Directory](#plugins-directory)
|
|
22
|
-
- [Writing Plugins](#writing-plugins)
|
|
23
|
-
- [Support](#support)
|
|
24
|
-
|
|
25
|
-
<!-- /code_chunk_output -->
|
|
26
|
-
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
## Quickstart
|
|
30
|
-
|
|
31
|
-
```
|
|
32
|
-
npx pockethost serve
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Introduction
|
|
36
|
-
|
|
37
|
-
PocketHost is a multitenant PocketBase hosting system. With it, you can run multiple instances of PocketBase on different subdomains, all on the same server.
|
|
38
|
-
|
|
39
|
-
Use PocketHost for development or production purposes.
|
|
40
|
-
|
|
41
|
-
PocketHost can be easily extended using its thoughtful plugin architecture. By choosing additional plugins, PocketHost's features can be extended according to your exact needs. You can even write your own plugins.
|
|
42
|
-
|
|
43
|
-
## The magic `serve` command
|
|
44
|
-
|
|
45
|
-
`pockethost serve` is a special command that can be decorated with plugins. Plugins can respond to the `serve` command by running their own services.
|
|
46
|
-
|
|
47
|
-
By convention, plugins that have some kind of `serve` functionality such as running a server, will make it available in two ways.
|
|
48
|
-
|
|
49
|
-
The first way runs ONLY the plugin's `serve` functionality:
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
pockethost <plugin-name> serve
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
The second way runs ALL `serve` functionality from ALL plugins:
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
pockethost serve
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
The exact plugins can also be narrowed:
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
pockethost serve --only=plugin1,plugin2,plugin3
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
See the plugin authoring guide for more information on how to make a plugin that responds to both methods.
|
|
68
|
-
|
|
69
|
-
## Configuration
|
|
70
|
-
|
|
71
|
-
PocketHost supports configuration by environment variable, `.env` file, and also built-in settings via `pockethost config`.
|
|
72
|
-
|
|
73
|
-
All PocketHost variables begin with `PH_`.
|
|
74
|
-
|
|
75
|
-
PocketHost will search the current directory for an `.env` when it loads. Anything in `.env` will be merged with and override any `<PH_HOME>/.env` that may exist.
|
|
76
|
-
|
|
77
|
-
Use `pockethost config` to list and set global defaults.
|
|
78
|
-
|
|
79
|
-
### Core Variables
|
|
80
|
-
|
|
81
|
-
See `pockethost config ls` for a full list of variables. Plugin variables will also be listed for loaded plugins.
|
|
82
|
-
|
|
83
|
-
| Name | Default | Discussion |
|
|
84
|
-
| -------------- | -------------------------- | ----------------------------------------------------------------------------- |
|
|
85
|
-
| PH_HOME | `~/.pockethost` | PocketHost's home directory where it holds all data. |
|
|
86
|
-
| PH_APEX_DOMAIN | `pockethost.lvh.me` | The apex domain used for routing and determining instance names. |
|
|
87
|
-
| PH_PORT | `3000` | The port PocketHost listens on |
|
|
88
|
-
| PH_DEBUG | `NODE_ENV==='development'` | Debug mode |
|
|
89
|
-
| PH_PLUGINS | (see below) | A comma-separated list of Plugins to load |
|
|
90
|
-
| PH_DATA_DIR | `~/.pockethost/data` | The root directory for storing PocketHost data, including instance databases. |
|
|
91
|
-
| PH_DEV | `NODE_ENV==='development'` | Whether PocketHost is running in development mode. |
|
|
92
|
-
|
|
93
|
-
### Default Plugins
|
|
94
|
-
|
|
95
|
-
- `@pockethost/plugin-console-logger`
|
|
96
|
-
- `@pockethost/plugin-launcher-spawn`
|
|
97
|
-
- `@pockethost/plugin-auto-admin`
|
|
98
|
-
|
|
99
|
-
## Plugins Directory
|
|
100
|
-
|
|
101
|
-
PocketHost uses an action/filter architecture to support a growing list plugins. Some plugins have a CLI component, whereas others add purely programmatic support to alter how PocketHost works.
|
|
102
|
-
|
|
103
|
-
### Core plugins
|
|
104
|
-
|
|
105
|
-
These plugins are maintained by the PocketHost project.
|
|
106
|
-
|
|
107
|
-
| Name | Description |
|
|
108
|
-
| ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
|
109
|
-
| `@pockethost/plugin-console-logger` | Routes log messages to the console |
|
|
110
|
-
| `@pockethost/plugin-auto-admin` | Auto-creates a default admin account on instance launch |
|
|
111
|
-
| `@pockethost/plugin-launcher-spawn` | Launches PocketBase instances via `spawn()` on the local machine. PocketHost uses this by default |
|
|
112
|
-
| `@pockethost/plugin-cloudflare-request-logger` | Log additional data when running behind Cloudflare |
|
|
113
|
-
| `@pockethost/plugin-ftp-server` | Used to provide secure FTPS access to PocketBase instance data. This FTP server can run along-side a PocketHost server. |
|
|
114
|
-
| `@pockethost/plugin-local-auth` | A light-weight username/password auth provider for associating instances with users. |
|
|
115
|
-
|
|
116
|
-
Coming soon:
|
|
117
|
-
| name | description |
|
|
118
|
-
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
|
119
|
-
| plugin-launcher-docker | Launches PocketBase instances via Docker. This is useful for running untrusted PocketBase code and instances. pockethost.io uses this. |
|
|
120
|
-
| plugin-waf | A Web Application Firewall |
|
|
121
|
-
| plugin-waf-enforce-ssl | Enforce SSL at the WAF
|
|
122
|
-
|
|
123
|
-
## Writing Plugins
|
|
124
|
-
|
|
125
|
-
See the [Plugin Authoring Guide](https://github.com/pockethost/pockethost/blob/master/packages/pockethost/plugin-guide.md) for details about how to write your own plugins.
|
|
126
|
-
|
|
127
|
-
## Support
|
|
128
|
-
|
|
129
|
-
PocketHost has a thriving [Discord community](https://discord.gg/nVTxCMEcGT).
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander'
|
|
2
|
-
import { listConfig, setConfig, unsetConfig } from '../../../core'
|
|
3
|
-
|
|
4
|
-
export const ConfigCommand = () => {
|
|
5
|
-
const cmd = new Command(`config`)
|
|
6
|
-
.description(`Set global config defaults`)
|
|
7
|
-
.addCommand(
|
|
8
|
-
new Command(`set`)
|
|
9
|
-
.argument(`<name>`, `Config name`)
|
|
10
|
-
.argument(`<value>`, `Config value`)
|
|
11
|
-
.description(`Set a config value`)
|
|
12
|
-
.action(setConfig),
|
|
13
|
-
)
|
|
14
|
-
|
|
15
|
-
.addCommand(
|
|
16
|
-
new Command(`unset`)
|
|
17
|
-
.argument(`<name>`, `Config name`)
|
|
18
|
-
.description(`Unset a config value`)
|
|
19
|
-
.action(unsetConfig),
|
|
20
|
-
)
|
|
21
|
-
.addCommand(
|
|
22
|
-
new Command(`list`)
|
|
23
|
-
.description(`List all config values`)
|
|
24
|
-
.alias(`ls`)
|
|
25
|
-
.action(listConfig),
|
|
26
|
-
)
|
|
27
|
-
return cmd
|
|
28
|
-
}
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander'
|
|
2
|
-
import { readFileSync } from 'fs'
|
|
3
|
-
import { dasherize, underscore } from 'inflection'
|
|
4
|
-
import nodePlop from 'node-plop'
|
|
5
|
-
import { dirname } from 'node:path'
|
|
6
|
-
import { fileURLToPath } from 'node:url'
|
|
7
|
-
import { join } from 'path'
|
|
8
|
-
import { cwd } from 'process'
|
|
9
|
-
import { error, info } from '../..'
|
|
10
|
-
import { version } from '../../../../package.json'
|
|
11
|
-
import { PH_PLUGINS, PH_PROJECT_DIR } from '../../../constants'
|
|
12
|
-
import { appendConfig, filterConfig } from '../../../core'
|
|
13
|
-
import { getCompatibleVersions, getPackageJson, removePackage } from './util'
|
|
14
|
-
|
|
15
|
-
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
16
|
-
|
|
17
|
-
export const PluginCommand = () => {
|
|
18
|
-
const cmd = new Command(`plugin`)
|
|
19
|
-
.description(`Manage PocketHost plugins`)
|
|
20
|
-
.addCommand(
|
|
21
|
-
new Command(`install`)
|
|
22
|
-
.alias(`i`)
|
|
23
|
-
.argument(`<name>`, `NPM registry plugin name`)
|
|
24
|
-
.description(`Install a plugin`)
|
|
25
|
-
.action(async (name: string) => {
|
|
26
|
-
try {
|
|
27
|
-
const pkg = JSON.parse(
|
|
28
|
-
readFileSync(PH_PROJECT_DIR(`package.json`), 'utf8').toString(),
|
|
29
|
-
)
|
|
30
|
-
const { version } = pkg
|
|
31
|
-
await getCompatibleVersions(`pockethost`, version, [name])
|
|
32
|
-
|
|
33
|
-
appendConfig(`PH_PLUGINS`, name)
|
|
34
|
-
} catch (e) {
|
|
35
|
-
error(`${e}`)
|
|
36
|
-
}
|
|
37
|
-
}),
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
.addCommand(
|
|
41
|
-
new Command(`list`)
|
|
42
|
-
.alias(`ls`)
|
|
43
|
-
.description(`List plugins`)
|
|
44
|
-
.action(async (name: string) => {
|
|
45
|
-
try {
|
|
46
|
-
for (const plugin of PH_PLUGINS()) {
|
|
47
|
-
const pkg = await getPackageJson(plugin)
|
|
48
|
-
info(`${plugin}@${pkg.version} - ${pkg?.description}`)
|
|
49
|
-
}
|
|
50
|
-
} catch (e) {
|
|
51
|
-
error(`${e}`)
|
|
52
|
-
}
|
|
53
|
-
}),
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
.addCommand(
|
|
57
|
-
new Command(`remove`)
|
|
58
|
-
.alias(`rm`)
|
|
59
|
-
.alias(`uninstall`)
|
|
60
|
-
.alias(`delete`)
|
|
61
|
-
.argument(`<name>`, `Plugin name`)
|
|
62
|
-
.description(`Remove a plugin`)
|
|
63
|
-
.action(async (name) => {
|
|
64
|
-
try {
|
|
65
|
-
await removePackage(name)
|
|
66
|
-
filterConfig(`PH_PLUGINS`, name)
|
|
67
|
-
} catch (e) {
|
|
68
|
-
error(`${e}`)
|
|
69
|
-
}
|
|
70
|
-
}),
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
.addCommand(
|
|
74
|
-
new Command(`update`)
|
|
75
|
-
.alias(`up`)
|
|
76
|
-
.description(`Update all plugins`)
|
|
77
|
-
.action(async () => {
|
|
78
|
-
try {
|
|
79
|
-
const pkg = JSON.parse(
|
|
80
|
-
readFileSync(PH_PROJECT_DIR(`package.json`), 'utf8').toString(),
|
|
81
|
-
)
|
|
82
|
-
const { version } = pkg
|
|
83
|
-
await getCompatibleVersions(`pockethost`, version, PH_PLUGINS())
|
|
84
|
-
} catch (e) {
|
|
85
|
-
error(`${e}`)
|
|
86
|
-
}
|
|
87
|
-
}),
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
.addCommand(
|
|
91
|
-
new Command(`create`)
|
|
92
|
-
.description(`Create a new plugin`)
|
|
93
|
-
.alias(`new`)
|
|
94
|
-
.alias(`n`)
|
|
95
|
-
.alias(`make`)
|
|
96
|
-
.alias(`generate`)
|
|
97
|
-
.argument(`<name>`, `Plugin name (dash case)`)
|
|
98
|
-
.action(async (name) => {
|
|
99
|
-
const dashCase = dasherize(underscore(name))
|
|
100
|
-
const plopfilePath = join(__dirname, 'plopfile.mjs')
|
|
101
|
-
const plopInstance = await nodePlop(plopfilePath, {
|
|
102
|
-
destBasePath: cwd(),
|
|
103
|
-
force: false,
|
|
104
|
-
})
|
|
105
|
-
const generator = plopInstance.getGenerator('plugin')
|
|
106
|
-
const results = await generator.runActions({
|
|
107
|
-
name: dashCase,
|
|
108
|
-
version,
|
|
109
|
-
})
|
|
110
|
-
}),
|
|
111
|
-
)
|
|
112
|
-
return cmd
|
|
113
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@pockethost/plugin-{{dashCase name}}",
|
|
3
|
-
"version": "0.0.1",
|
|
4
|
-
"repository": {
|
|
5
|
-
"type": "git",
|
|
6
|
-
"url": "http://github.com/pockethost/pockethost/packages/plugin-{{dashCase name}}"
|
|
7
|
-
},
|
|
8
|
-
"description": "A pockethost plugin.",
|
|
9
|
-
"main": "src/index.ts",
|
|
10
|
-
"module": "src/index.ts",
|
|
11
|
-
"types": "src/index.ts",
|
|
12
|
-
"type": "module",
|
|
13
|
-
"scripts": {
|
|
14
|
-
"check-types": "tsc --noEmit "
|
|
15
|
-
},
|
|
16
|
-
"keywords": [
|
|
17
|
-
"pockethost"
|
|
18
|
-
],
|
|
19
|
-
"author": {
|
|
20
|
-
"name": "Ben Allfree",
|
|
21
|
-
"url": "https://github.com/benallfree"
|
|
22
|
-
},
|
|
23
|
-
"license": "MIT",
|
|
24
|
-
"peerDependencies": {
|
|
25
|
-
"pockethost": "workspace:^1.6.0"
|
|
26
|
-
},
|
|
27
|
-
"devDependencies": {
|
|
28
|
-
"@types/node": "^20.8.10",
|
|
29
|
-
"typescript": "^5.4.5",
|
|
30
|
-
"@types/lowdb": "^1.0.15"
|
|
31
|
-
},
|
|
32
|
-
"dependencies": {
|
|
33
|
-
"commander": "^11.1.0",
|
|
34
|
-
"immer": "^10.1.1",
|
|
35
|
-
"inflection": "^3.0.0",
|
|
36
|
-
"lowdb": "^7.0.1"
|
|
37
|
-
}
|
|
38
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# plugin-{{dashCase name}}
|
|
2
|
-
|
|
3
|
-
A plugin for [pockethost](https://www.npmjs.com/package/pockethost).
|
|
4
|
-
|
|
5
|
-
## Quickstart
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npx pockethost plugin install @pockethost/plugin-{{dashCase name}}
|
|
9
|
-
|
|
10
|
-
npx pockethost {{dashCase name}} --help
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## Variables
|
|
14
|
-
|
|
15
|
-
The following variables will be used if they are found in the shell environment. PocketHost will also load them from an `.env` file if found at load time.
|
|
16
|
-
|
|
17
|
-
| Name | Default | Discussion |
|
|
18
|
-
| ------------------------------- | -------------------------------------- | ------------------------------------------------------------- |
|
|
19
|
-
| PH\_{{constantCase name}}\_HOME | `.pockethost/plugin-{{dashCase name}}` | The home directory for any data storage needs of this plugin. |
|
|
20
|
-
|
|
21
|
-
## Actions
|
|
22
|
-
|
|
23
|
-
## Filters
|
|
24
|
-
|
|
25
|
-
## Support
|
|
26
|
-
|
|
27
|
-
PocketHost has a thriving [Discord community](https://discord.gg/nVTxCMEcGT).
|
|
28
|
-
|
|
29
|
-
---
|
|
30
|
-
|
|
31
|
-
### Sponsored by https://pockethost.io. Instantly host your PocketBase projects.
|
|
32
|
-
|
|
33
|
-
---
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { underscore } from 'inflection'
|
|
2
|
-
import { dirname, join } from 'path'
|
|
3
|
-
import { PH_HOME, Settings, mkPath } from 'pockethost/core'
|
|
4
|
-
import { fileURLToPath } from 'url'
|
|
5
|
-
|
|
6
|
-
export const PLUGIN_NAME = `plugin-{{dashCase name}}`
|
|
7
|
-
|
|
8
|
-
export const HOME_DIR =
|
|
9
|
-
process.env.PH_{{constantCase name}}_HOME || join(PH_HOME(),PLUGIN_NAME)
|
|
10
|
-
|
|
11
|
-
export const PLUGIN_NAME_CONSTANT_CASE = underscore(PLUGIN_NAME, true)
|
|
12
|
-
|
|
13
|
-
export const PLUGIN_DATA = (...paths: string[]) => join(HOME_DIR, ...paths)
|
|
14
|
-
|
|
15
|
-
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
16
|
-
export const PROJECT_DIR = (...paths: string[]) =>
|
|
17
|
-
join(__dirname, '..', ...paths)
|
|
18
|
-
|
|
19
|
-
export const settings = Settings({
|
|
20
|
-
PH_{{constantCase name}}_HOME: mkPath(HOME_DIR, { create: true }),
|
|
21
|
-
})
|
|
22
|
-
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { JSONFileSyncPreset } from 'lowdb/node'
|
|
2
|
-
import { InstanceFields, InstanceId, mkSingleton } from 'pockethost'
|
|
3
|
-
import { PLUGIN_DATA } from './constants'
|
|
4
|
-
import { info } from './log'
|
|
5
|
-
|
|
6
|
-
export const DbService = mkSingleton(async () => {
|
|
7
|
-
const db = await JSONFileSyncPreset<{
|
|
8
|
-
instances: { [key: InstanceId]: InstanceFields }
|
|
9
|
-
}>(PLUGIN_DATA('db.json'), { instances: {} })
|
|
10
|
-
|
|
11
|
-
const deleteInstance = (id: InstanceId) => {
|
|
12
|
-
db.update((data) => {
|
|
13
|
-
delete data.instances[id]
|
|
14
|
-
})
|
|
15
|
-
info(`Deleted instance ${id}`)
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const addInstance = (instance: InstanceFields) => {
|
|
19
|
-
db.update((data) => (data.instances[instance.id] = instance))
|
|
20
|
-
info(`Added instance ${instance.id}`)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const getInstanceById = (id: InstanceId) => db.data.instances[id]
|
|
24
|
-
|
|
25
|
-
return {
|
|
26
|
-
addInstance,
|
|
27
|
-
deleteInstance,
|
|
28
|
-
getInstanceById,
|
|
29
|
-
}
|
|
30
|
-
})
|