pockethost 1.6.1 → 1.7.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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # pockethost
2
2
 
3
+ ## 1.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 3c7e9bf: Added plugin template command and updated docs
8
+
3
9
  ## 1.6.1
4
10
 
5
11
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pockethost",
3
- "version": "1.6.1",
3
+ "version": "1.7.0",
4
4
  "author": {
5
5
  "name": "Ben Allfree",
6
6
  "url": "https://github.com/benallfree"
@@ -27,11 +27,13 @@
27
27
  "get-port": "^6.1.2",
28
28
  "http-proxy": "^1.18.1",
29
29
  "immer": "^10.1.1",
30
+ "inflection": "^3.0.0",
30
31
  "json-stringify-safe": "^5.0.1",
31
32
  "listr2": "^8.2.3",
32
33
  "minimist": "^1.2.8",
33
34
  "nanoid": "^5.0.2",
34
35
  "node-fetch": "^3.3.2",
36
+ "node-plop": "^0.32.0",
35
37
  "pocketbase": "^0.21.3",
36
38
  "rimraf": "^5.0.5",
37
39
  "semver": "^7.6.2",
@@ -1,10 +1,19 @@
1
1
  import { Command } from 'commander'
2
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'
3
9
  import { error, info } from '../..'
10
+ import { version } from '../../../../package.json'
4
11
  import { PH_PLUGINS, PH_PROJECT_DIR } from '../../../constants'
5
12
  import { appendConfig, filterConfig } from '../../../core'
6
13
  import { getCompatibleVersions, getPackageJson, removePackage } from './util'
7
14
 
15
+ const __dirname = dirname(fileURLToPath(import.meta.url))
16
+
8
17
  export const PluginCommand = () => {
9
18
  const cmd = new Command(`plugin`)
10
19
  .description(`Manage PocketHost plugins`)
@@ -77,5 +86,28 @@ export const PluginCommand = () => {
77
86
  }
78
87
  }),
79
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
+ )
80
112
  return cmd
81
113
  }
@@ -0,0 +1,38 @@
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
+ }
@@ -0,0 +1,33 @@
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
+ ---
@@ -0,0 +1,22 @@
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
+
@@ -0,0 +1,30 @@
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
+ })
@@ -0,0 +1,3 @@
1
+ import { plugin } from './plugin'
2
+
3
+ export default plugin
@@ -0,0 +1,5 @@
1
+ import { LoggerService } from 'pockethost'
2
+ import { PLUGIN_NAME } from './constants'
3
+
4
+ const logger = LoggerService().create(PLUGIN_NAME)
5
+ export const { dbg, info, error } = logger
@@ -0,0 +1,58 @@
1
+ import { Command } from 'commander'
2
+ import { produce } from 'immer'
3
+ import {
4
+ PocketHostPlugin,
5
+ onCliCommandsFilter,
6
+ onInstanceConfigFilter,
7
+ onServeAction,
8
+ onServeSlugsFilter,
9
+ onSettingsFilter,
10
+ } from 'pockethost'
11
+ import {
12
+ PLUGIN_NAME,
13
+ PLUGIN_NAME_CONSTANT_CASE,
14
+ PROJECT_DIR,
15
+ settings,
16
+ } from './constants'
17
+ import { DbService } from './db'
18
+ import { dbg } from './log'
19
+
20
+ export const plugin: PocketHostPlugin = async ({}) => {
21
+ dbg(`initializing ${PLUGIN_NAME}`)
22
+
23
+ await DbService({})
24
+
25
+ onInstanceConfigFilter(async (config) => {
26
+ return produce(config, (draft) => {
27
+ draft.env[`PH_${PLUGIN_NAME_CONSTANT_CASE}_ENABLED`] = true.toString()
28
+ draft.binds.hooks.push({
29
+ src: PROJECT_DIR(`src/instance-app/hooks/**/*`),
30
+ base: PROJECT_DIR(`src/instance-app/hooks`),
31
+ })
32
+ })
33
+ })
34
+
35
+ onCliCommandsFilter(async (commands) => {
36
+ return [
37
+ ...commands,
38
+ new Command(PLUGIN_NAME).description(`Command root`).addCommand(
39
+ new Command(`serve`)
40
+ .description(`Run a task`)
41
+ .action(async (options) => {
42
+ // do something
43
+ }),
44
+ ),
45
+ ]
46
+ })
47
+
48
+ onServeSlugsFilter(async (slugs) => {
49
+ return [...slugs, PLUGIN_NAME]
50
+ })
51
+
52
+ onServeAction(async ({ only }) => {
53
+ if (!only.includes(PLUGIN_NAME)) return
54
+ // Do something
55
+ })
56
+
57
+ onSettingsFilter(async (allSettings) => ({ ...allSettings, ...settings }))
58
+ }