mirror of
https://github.com/pockethost/pockethost.git
synced 2026-03-12 03:29:23 +00:00
123 lines
3.6 KiB
TypeScript
123 lines
3.6 KiB
TypeScript
import {
|
|
PocketHostPlugin,
|
|
mkInstance,
|
|
onAfterInstanceFoundAction,
|
|
onAfterInstanceStoppedAction,
|
|
onAfterServerStartAction,
|
|
onAppMountedAction,
|
|
onCliCommandsFilter,
|
|
onGetAllInstancesByExactCriteriaFilter,
|
|
onGetInstanceByRequestInfoFilter,
|
|
onGetOneInstanceByExactCriteriaFilter,
|
|
onGetOrProvisionInstanceUrlFilter,
|
|
onIsInstanceRunningFilter,
|
|
onNewInstanceRecordFilter,
|
|
onSettingsFilter,
|
|
} from 'pockethost'
|
|
import {
|
|
APEX_DOMAIN,
|
|
HTTP_PROTOCOL,
|
|
PORT,
|
|
PUBLIC_INSTANCE_URL,
|
|
} from 'pockethost/core'
|
|
import { InternalApp } from './InternalApp'
|
|
import { LauncherCommand } from './LauncherCommand'
|
|
import { PLUGIN_NAME, settings } from './constants'
|
|
import { DbService } from './db'
|
|
import { mkLauncher } from './launcher'
|
|
import { dbg, info } from './log'
|
|
|
|
export const plugin: PocketHostPlugin = async ({}) => {
|
|
dbg(`initializing ${PLUGIN_NAME}`)
|
|
|
|
const {
|
|
getInstanceBySubdomain,
|
|
createOrUpdateInstance,
|
|
getInstancesByExactCriteria,
|
|
} = await DbService({})
|
|
|
|
onCliCommandsFilter(async (commands) => {
|
|
return [...commands, LauncherCommand()]
|
|
})
|
|
|
|
onAppMountedAction(async ({ internalApp }) => {
|
|
dbg(`Mounting internal app`)
|
|
internalApp.use(InternalApp())
|
|
})
|
|
|
|
/** Display some informational alerts to help the user get started. */
|
|
onAfterServerStartAction(async () => {
|
|
const protocol = HTTP_PROTOCOL()
|
|
{
|
|
const url = new URL(`${protocol}//*.${APEX_DOMAIN()}`)
|
|
url.port = `${PORT() === 80 || PORT() == 443 ? '' : PORT()}`
|
|
info(`Listening for requests on ${url}`)
|
|
}
|
|
{
|
|
const url = PUBLIC_INSTANCE_URL({ subdomain: 'hello' })
|
|
info(`Try visiting ${url}`)
|
|
}
|
|
})
|
|
|
|
/** When a request comes in, return an instance based on subdomain */
|
|
onGetInstanceByRequestInfoFilter(async (instance, context) => {
|
|
const { subdomain } = context
|
|
return {
|
|
...(instance || (await mkInstance(subdomain))),
|
|
...getInstanceBySubdomain(subdomain),
|
|
}
|
|
})
|
|
|
|
/**
|
|
* When a new instance model is instantiated, this filter gives listeners a
|
|
* chance to augment or update the instance data.
|
|
*
|
|
* In this case, the instance data is restored from a local db.
|
|
*/
|
|
onNewInstanceRecordFilter(async (instance) => {
|
|
const { subdomain } = instance
|
|
return { ...instance, ...getInstanceBySubdomain(subdomain), id: subdomain }
|
|
})
|
|
|
|
/** After an instance has been found, store it to the db */
|
|
onAfterInstanceFoundAction(async (context) => {
|
|
const { instance } = context
|
|
dbg({ instance })
|
|
createOrUpdateInstance(instance)
|
|
})
|
|
|
|
const instances: { [_: string]: Promise<string> } = {}
|
|
|
|
/**
|
|
* The workhorse. This filter is responsible for launching PocketBase and
|
|
* returning an endpoint URL.
|
|
*/
|
|
onGetOrProvisionInstanceUrlFilter(async (url, { instance }) => {
|
|
const { dev, subdomain, version, secrets } = instance
|
|
|
|
if (subdomain in instances) return instances[subdomain]!
|
|
|
|
dbg({ instance })
|
|
return (instances[subdomain] = mkLauncher(instance))
|
|
})
|
|
|
|
onAfterInstanceStoppedAction(async ({ instance }) => {
|
|
const { subdomain } = instance
|
|
delete instances[subdomain]
|
|
})
|
|
|
|
onSettingsFilter(async (allSettings) => ({ ...allSettings, ...settings }))
|
|
|
|
onIsInstanceRunningFilter(async (isRunning, { instance }) => {
|
|
return isRunning || !!instances[instance.subdomain]
|
|
})
|
|
|
|
onGetOneInstanceByExactCriteriaFilter(async (instance, criteria) => {
|
|
return instance || getInstancesByExactCriteria(criteria)[0]
|
|
})
|
|
|
|
onGetAllInstancesByExactCriteriaFilter(async (instances, criteria) => {
|
|
return [...instances, ...getInstancesByExactCriteria(criteria)]
|
|
})
|
|
}
|