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.
Files changed (52) hide show
  1. package/CHANGELOG.md +119 -86
  2. package/README.md +96 -0
  3. package/dist/cli.js +21542 -0
  4. package/package.json +55 -55
  5. package/changesetx.ts +0 -110
  6. package/common.ts +0 -1
  7. package/core.ts +0 -1
  8. package/readme.md +0 -129
  9. package/src/cli/commands/ConfigCommand/index.ts +0 -28
  10. package/src/cli/commands/PluginCommand/index.ts +0 -113
  11. package/src/cli/commands/PluginCommand/plugin-template/package.json +0 -38
  12. package/src/cli/commands/PluginCommand/plugin-template/readme.md +0 -33
  13. package/src/cli/commands/PluginCommand/plugin-template/src/constants.ts +0 -22
  14. package/src/cli/commands/PluginCommand/plugin-template/src/db.ts +0 -30
  15. package/src/cli/commands/PluginCommand/plugin-template/src/index.ts +0 -3
  16. package/src/cli/commands/PluginCommand/plugin-template/src/log.ts +0 -5
  17. package/src/cli/commands/PluginCommand/plugin-template/src/plugin.ts +0 -58
  18. package/src/cli/commands/PluginCommand/util.ts +0 -140
  19. package/src/cli/commands/ServeCommand/index.ts +0 -36
  20. package/src/cli/index.ts +0 -70
  21. package/src/common/CleanupManager.ts +0 -65
  22. package/src/common/Logger.ts +0 -174
  23. package/src/common/ResourceAllocator.ts +0 -49
  24. package/src/common/TimerManager.ts +0 -64
  25. package/src/common/assert.ts +0 -26
  26. package/src/common/debug.ts +0 -8
  27. package/src/common/error.ts +0 -16
  28. package/src/common/events.ts +0 -53
  29. package/src/common/index.ts +0 -12
  30. package/src/common/mergeConfig.ts +0 -27
  31. package/src/common/mkSingleton.ts +0 -28
  32. package/src/common/plugin/action.ts +0 -164
  33. package/src/common/plugin/filter.ts +0 -197
  34. package/src/common/plugin/index.ts +0 -21
  35. package/src/common/promiseSerializer.ts +0 -22
  36. package/src/common/schema/BaseFields.ts +0 -10
  37. package/src/common/schema/Instance.ts +0 -46
  38. package/src/common/schema/InstanceLog.ts +0 -12
  39. package/src/common/schema/index.ts +0 -3
  40. package/src/common/schema/util.ts +0 -7
  41. package/src/constants.ts +0 -70
  42. package/src/core/Settings.ts +0 -119
  43. package/src/core/asyncExecutionGuard.ts +0 -49
  44. package/src/core/config.ts +0 -108
  45. package/src/core/exit.ts +0 -11
  46. package/src/core/index.ts +0 -8
  47. package/src/core/internal.ts +0 -3
  48. package/src/core/smartFetch.ts +0 -32
  49. package/src/core/tryFetch.ts +0 -69
  50. package/src/plugin.ts +0 -54
  51. package/src/server.ts +0 -129
  52. /package/{src/cli/commands/PluginCommand/plugin-template/LICENSE.md → LICENSE.md} +0 -0
@@ -1,58 +0,0 @@
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
- }
@@ -1,140 +0,0 @@
1
- import { exec } from 'child_process'
2
- import fs from 'fs/promises'
3
- import { Listr, ListrTask } from 'listr2'
4
- import { createRequire } from 'module'
5
- import fetch from 'node-fetch'
6
- import semver from 'semver'
7
- import util from 'util'
8
-
9
- const execPromise = util.promisify(exec)
10
- const require = createRequire(import.meta.url)
11
-
12
- export async function getPackageJson(packageName: string): Promise<any | null> {
13
- try {
14
- const packageJsonPath = require.resolve(`${packageName}/package.json`)
15
- const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'))
16
- return packageJson
17
- } catch (error) {
18
- return null
19
- }
20
- }
21
-
22
- export async function fetchPackageData(
23
- packageName: string,
24
- ): Promise<any | null> {
25
- const npmRegistryUrl = `https://registry.npmjs.org/${packageName}`
26
- try {
27
- const response = await fetch(npmRegistryUrl)
28
- return await response.json()
29
- } catch (error) {
30
- return null
31
- }
32
- }
33
-
34
- async function installPackage(
35
- packageName: string,
36
- version: string,
37
- ): Promise<void> {
38
- try {
39
- await execPromise(`npm install -g ${packageName}@${version}`)
40
- } catch (e) {
41
- throw new Error(`Error installing ${packageName}@${version}: ${e}`)
42
- }
43
- }
44
-
45
- export async function removePackage(packageName: string): Promise<void> {
46
- try {
47
- await execPromise(`npm remove -g ${packageName}`)
48
- } catch (e) {
49
- throw new Error(`Error removing ${packageName}: ${e}`)
50
- }
51
- }
52
-
53
- async function checkPackageCompatibility(
54
- packageA: string,
55
- versionA: string,
56
- packageB: string,
57
- ): Promise<string> {
58
- const localPackageJson = await getPackageJson(packageB)
59
-
60
- if (localPackageJson) {
61
- const { version: localPackageBVersion, dependencies } = localPackageJson
62
-
63
- if (dependencies && semver.satisfies(versionA, dependencies[packageA])) {
64
- return `Local ${packageB}@${localPackageBVersion} is already compatible with ${packageA}@${versionA}`
65
- }
66
- }
67
-
68
- const packageBData = await fetchPackageData(packageB)
69
- if (!packageBData) {
70
- throw new Error(`Error fetching data for ${packageB}`)
71
- }
72
-
73
- const versions = packageBData.versions
74
- let latestCompatibleVersion: string | null = null
75
-
76
- for (const version in versions) {
77
- const dependencies = versions[version].dependencies
78
- if (
79
- dependencies &&
80
- packageA in dependencies &&
81
- semver.satisfies(versionA, dependencies[packageA])
82
- ) {
83
- if (
84
- !latestCompatibleVersion ||
85
- semver.gt(version, latestCompatibleVersion)
86
- ) {
87
- latestCompatibleVersion = version
88
- }
89
- }
90
- }
91
-
92
- if (latestCompatibleVersion) {
93
- await installPackage(packageB, latestCompatibleVersion)
94
- return `${packageB}@${latestCompatibleVersion} installed successfully`
95
- } else {
96
- throw new Error(
97
- `No compatible version of ${packageB} found for ${packageA}@${versionA}`,
98
- )
99
- }
100
- }
101
-
102
- export async function getCompatibleVersions(
103
- packageA: string,
104
- versionA: string,
105
- packagesB: string[],
106
- ): Promise<void> {
107
- const tasks = packagesB.map(
108
- (packageB) =>
109
- ({
110
- title: `Checking ${packageB}...`,
111
- task: async (_, task) => {
112
- try {
113
- const result = await checkPackageCompatibility(
114
- packageA,
115
- versionA,
116
- packageB,
117
- )
118
- task.output = result
119
- } catch (error) {
120
- task.output = `${error}`
121
- throw error
122
- }
123
- },
124
- }) as ListrTask,
125
- )
126
-
127
- const listr = new Listr(tasks, {
128
- concurrent: true,
129
- rendererOptions: { collapseSubtasks: false },
130
- })
131
-
132
- await listr.run()
133
- }
134
-
135
- // Example usage
136
- // const packageA = 'express'
137
- // const versionA = '4.17.1'
138
- // const packagesB = ['some-package', 'another-package', 'yet-another-package']
139
-
140
- // getCompatibleVersions(packageA, versionA, packagesB)
@@ -1,36 +0,0 @@
1
- import { Command } from 'commander'
2
- import {
3
- LoggerService,
4
- doServeAction,
5
- doServeSlugsFilter,
6
- } from '../../../common'
7
-
8
- type Options = {
9
- only: string[]
10
- }
11
-
12
- export const ServeCommand = async () => {
13
- const serveSlugs = await doServeSlugsFilter([])
14
-
15
- const cmd = new Command(`serve`)
16
- .description(`Run PocketHost`)
17
- .option(
18
- `-o, --only <only>`,
19
- `Only run the specified services`,
20
- (s) =>
21
- s
22
- .split(/,/)
23
- .map((s) => s.trim())
24
- .filter((s) => serveSlugs.includes(s)),
25
- serveSlugs,
26
- )
27
- .action(async (options: Options, cmd: Command) => {
28
- const logger = LoggerService().create(`ServeCommand`)
29
- const { dbg, error, info, warn } = logger
30
- info(`Starting`)
31
-
32
- const { only } = options
33
- await doServeAction({ only })
34
- })
35
- return cmd
36
- }
package/src/cli/index.ts DELETED
@@ -1,70 +0,0 @@
1
- #!/usr/bin/env tsx
2
-
3
- import { uniq } from '@s-libs/micro-dash'
4
- import { program } from 'commander'
5
- import { readFileSync } from 'fs'
6
- import minimist from 'minimist'
7
- import updateNotifier from 'update-notifier'
8
- import { PH_PLUGINS, PH_PROJECT_DIR } from '../../core'
9
- import {
10
- DEBUG,
11
- LogLevelName,
12
- LoggerService,
13
- doAfterPluginsLoadedAction,
14
- doCliCommandsFilter,
15
- loadPlugins,
16
- } from '../common'
17
- import { pockethost } from '../plugin'
18
- import { ConfigCommand } from './commands/ConfigCommand'
19
- import { PluginCommand } from './commands/PluginCommand'
20
- import { ServeCommand } from './commands/ServeCommand'
21
-
22
- export const { dbg, info, error } = LoggerService({
23
- level: DEBUG() ? LogLevelName.Debug : LogLevelName.Info,
24
- })
25
-
26
- export type GlobalOptions = {
27
- extraPlugins: string[]
28
- }
29
-
30
- export const main = async () => {
31
- const pkg = await JSON.parse(
32
- readFileSync(PH_PROJECT_DIR(`package.json`), 'utf8').toString(),
33
- )
34
- updateNotifier({ pkg }).notify()
35
-
36
- const { version } = pkg
37
-
38
- const argv = minimist<{ e: string }>(process.argv.slice(2), {
39
- alias: { e: 'extra-plugins' },
40
- default: { e: '' },
41
- })
42
- const extraPlugins = argv.e
43
- .split(/,/)
44
- .map((s) => s.trim())
45
- .filter((v) => !!v)
46
-
47
- await loadPlugins([pockethost, ...uniq(PH_PLUGINS()), ...extraPlugins])
48
-
49
- await doAfterPluginsLoadedAction()
50
-
51
- program
52
- .name('pockethost')
53
- .description('Multitenant PocketBase hosting')
54
- .version(version)
55
- .option(`-e, --extra-plugins <plugins...>`, `Extra plugins to load`, [])
56
-
57
- const commands = await doCliCommandsFilter([
58
- await ServeCommand(),
59
- ConfigCommand(),
60
- PluginCommand(),
61
- ])
62
-
63
- for (const command of commands) {
64
- program.addCommand(command)
65
- }
66
-
67
- await program.parseAsync()
68
- }
69
-
70
- main()
@@ -1,65 +0,0 @@
1
- import { reduce, uniqueId, values } from '@s-libs/micro-dash'
2
- import { LoggerService } from '.'
3
-
4
- export type CleanupFunc = () => Promise<void> | void
5
-
6
- type CleanupRec = {
7
- cleanup: CleanupFunc
8
- priority: number
9
- }
10
-
11
- export const CLEANUP_DEFAULT_PRIORITY = 10
12
- export const CLEANUP_PRIORITY_HIGH = 1
13
- export const CLEANUP_PRIORITY_LOW = 20
14
- export const CLEANUP_PRIORITY_LAST = 1000
15
-
16
- export type CleanupManagerApi = ReturnType<typeof createCleanupManager>
17
-
18
- export const createCleanupManager = (slug?: string) => {
19
- const _slug = slug || uniqueId()
20
-
21
- const { error, warn, dbg } = LoggerService().create(`cleanupManager:${_slug}`)
22
-
23
- let i = 0
24
-
25
- const cleanups: { [_: number]: CleanupRec } = {}
26
-
27
- const add = (cb: CleanupFunc, priority = CLEANUP_DEFAULT_PRIORITY) => {
28
- const idx = i++
29
-
30
- const cleanup = async () => {
31
- await cb()
32
- delete cleanups[idx]
33
- }
34
-
35
- cleanups[idx] = { cleanup, priority }
36
-
37
- return cleanup
38
- }
39
-
40
- let _shutdownP: Promise<void> | undefined = undefined
41
-
42
- const shutdown: () => Promise<void> = () => {
43
- if (_shutdownP) return _shutdownP
44
-
45
- const _cleanupFuncs = values(cleanups)
46
- .sort((a, b) => a.priority - b.priority)
47
- .map((v) => v.cleanup)
48
- _shutdownP = reduce(
49
- _cleanupFuncs,
50
- (c, v) => {
51
- return c.then(() => v())
52
- },
53
- Promise.resolve(),
54
- ).catch((e) => {
55
- error(
56
- `Cleanup functions are failing. This should never happen, check all cleanup functions to make sure they are trapping their exceptions.`,
57
- )
58
- throw e
59
- })
60
-
61
- return _shutdownP
62
- }
63
-
64
- return { add, shutdown }
65
- }
@@ -1,174 +0,0 @@
1
- /// <require "node">
2
-
3
- import chalk from 'chalk'
4
- import stringify from 'json-stringify-safe'
5
- import { doLogAction, mergeConfig, mkSingleton } from '.'
6
-
7
- export type LoggerConfig = {
8
- level: LogLevelName
9
- pfx: string[]
10
- }
11
-
12
- export type Logger = ReturnType<typeof createLogger>
13
-
14
- export const isLevelLte = (a: LogLevelName, b: LogLevelName) => {
15
- return LogLevels[a] <= LogLevels[b]
16
- }
17
-
18
- export const isLevelGt = (a: LogLevelName, b: LogLevelName) => {
19
- return LogLevels[a] > LogLevels[b]
20
- }
21
-
22
- export const isLevelGte = (a: LogLevelName, b: LogLevelName) => {
23
- return LogLevels[a] >= LogLevels[b]
24
- }
25
-
26
- export enum LogLevelName {
27
- Trace = 'trace',
28
- Raw = 'raw',
29
- Debug = 'debug',
30
- Info = 'info',
31
- Warn = 'warn',
32
- Error = 'error',
33
- Abort = 'abort',
34
- }
35
-
36
- export const LEVEL_NAMES = [
37
- LogLevelName.Trace,
38
- LogLevelName.Raw,
39
- LogLevelName.Debug,
40
- LogLevelName.Info,
41
- LogLevelName.Warn,
42
- LogLevelName.Error,
43
- LogLevelName.Abort,
44
- ]
45
-
46
- export const LogLevels = {
47
- [LogLevelName.Trace]: 0,
48
- [LogLevelName.Raw]: 1,
49
- [LogLevelName.Debug]: 2,
50
- [LogLevelName.Info]: 3,
51
- [LogLevelName.Warn]: 4,
52
- [LogLevelName.Error]: 5,
53
- [LogLevelName.Abort]: 6,
54
- } as const
55
-
56
- export const namespace = (...names: string[]) =>
57
- names
58
- .filter((v) => !!v)
59
- .map((p) => `[${p}]`)
60
- .join(' ')
61
-
62
- export const createLogger = (config: Partial<LoggerConfig>) => {
63
- const _config = mergeConfig<LoggerConfig>(
64
- {
65
- level: LogLevelName.Debug,
66
- pfx: [''],
67
- },
68
- config,
69
- )
70
- const { pfx } = _config
71
-
72
- const setLevel = (level: LogLevelName) => {
73
- _config.level = level
74
- }
75
-
76
- const _pfx = (s: string) => namespace(s, ...pfx)
77
-
78
- const _log = (levelIn: LogLevelName, ...args: any[]) => {
79
- doLogAction({
80
- currentLevel: _config.level,
81
- levelIn,
82
- args,
83
- })
84
- }
85
-
86
- const raw = (...args: any[]) => {
87
- _log(LogLevelName.Raw, _pfx('RAW'), ...args)
88
- }
89
-
90
- const trace = (...args: any[]) => {
91
- _log(LogLevelName.Trace, _pfx(`TRACE`), ...args)
92
- }
93
-
94
- const dbg = (...args: any[]) => {
95
- _log(LogLevelName.Debug, _pfx(chalk.blueBright('DBG')), ...args)
96
- }
97
-
98
- const info = (...args: any[]) => {
99
- const _args = (() => {
100
- if (isLevelGt(LogLevelName.Info, _config.level)) {
101
- return [_pfx(chalk.gray(`INFO`)), ...args]
102
- }
103
- return [...args]
104
- })()
105
- _log(
106
- LogLevelName.Info,
107
-
108
- ..._args,
109
- )
110
- }
111
-
112
- const warn = (...args: any[]) => {
113
- _log(
114
- LogLevelName.Warn,
115
- _pfx(chalk.yellow(chalk.cyanBright('WARN'))),
116
- ...args,
117
- )
118
- }
119
-
120
- const error = (...args: any[]) => {
121
- _log(LogLevelName.Error, ...[_pfx(chalk.bgRed(`ERROR`)), ...args])
122
- }
123
-
124
- const criticalError = (...args: any[]) => {
125
- _log(LogLevelName.Error, ...[_pfx(chalk.bgRed(`ERROR`)), ...args])
126
- new Error().stack?.split(/\n/).forEach((line) => {
127
- _log(LogLevelName.Debug, _pfx(chalk.bgRed(`ERROR`)), line)
128
- })
129
- }
130
-
131
- const abort = (...args: any[]): never => {
132
- _log(LogLevelName.Abort, true, ...[_pfx(chalk.bgRed(`ABORT`)), ...args])
133
- throw new Error(`Fatal error: ${stringify(args)}`)
134
- }
135
-
136
- const create = (s: string, configOverride?: Partial<LoggerConfig>) =>
137
- createLogger({
138
- ..._config,
139
- ...configOverride,
140
- pfx: [..._config.pfx, s],
141
- })
142
-
143
- const breadcrumb = (s: string) => {
144
- pfx.push(s)
145
- return api
146
- }
147
-
148
- // Compatibility func
149
- const child = (extra: any) => create(stringify(extra))
150
-
151
- const api = {
152
- raw,
153
- dbg,
154
- warn,
155
- info,
156
- error,
157
- criticalError,
158
- create,
159
- child,
160
- trace,
161
- debug: dbg,
162
- breadcrumb,
163
- abort,
164
- shutdown() {
165
- dbg(`Logger shutting down`)
166
- },
167
- setLevel,
168
- }
169
- return api
170
- }
171
-
172
- export const LoggerService = mkSingleton((config: Partial<LoggerConfig> = {}) =>
173
- createLogger(config),
174
- )
@@ -1,49 +0,0 @@
1
- export type Deallocator = () => void
2
-
3
- export type Allocator<T> = {
4
- free: (item: T) => void
5
- alloc: () => [T, Deallocator]
6
- }
7
-
8
- export function ResourceAllocator<T>(
9
- initialPoolSize: number,
10
- initializer: () => T,
11
- ): Allocator<T> {
12
- // Available queue to hold resolved items of type T
13
- const available: T[] = []
14
-
15
- // Function to add an item back to the available queue
16
- const free = (item: T) => {
17
- available.push(item)
18
- }
19
-
20
- // Pre-populate the available queue with initial items
21
- for (let i = 0; i < initialPoolSize; i++) {
22
- available.push(initializer())
23
- }
24
-
25
- return {
26
- alloc() {
27
- if (available.length === 0) {
28
- available.push(initializer())
29
- }
30
- const newItem = initializer()
31
- return [newItem, () => free(newItem)]
32
- },
33
- free,
34
- }
35
- }
36
-
37
- /*
38
- // Example Usage
39
- const allocator = PromiseAllocator(2, async () => {
40
- return new Promise<number>((resolve) => {
41
- setTimeout(() => resolve(Math.random()), 1000);
42
- });
43
- });
44
-
45
- allocator.alloc().then(([num, freeFunc]) => {
46
- console.log(num); // e.g. 0.123456789
47
- freeFunc(); // Adds the number back to the available queue
48
- });
49
- */
@@ -1,64 +0,0 @@
1
- import { forEach, values } from '@s-libs/micro-dash'
2
- import { LoggerService } from '.'
3
-
4
- export type UnixTimestampMs = number
5
- export type TimerCanceler = () => void
6
-
7
- export type RepeatableTimerCallback = () => boolean | Promise<boolean>
8
- export type TimerCallback = () => void | Promise<void>
9
- export type TimeManagerConfig = {}
10
-
11
- export type TimeManager = ReturnType<typeof createTimerManager>
12
-
13
- export const createTimerManager = (config?: Partial<TimeManagerConfig>) => {
14
- const { dbg, error } = LoggerService().create(`timerManager`)
15
- let i = 0
16
- const cleanups: any = {}
17
- let isShutDown = false
18
-
19
- const add = (cb: TimerCallback, ms: UnixTimestampMs) => {
20
- if (isShutDown) throw new Error(`Already shut down`)
21
- const idx = i++
22
- const tid = setTimeout(async () => {
23
- cancel()
24
- try {
25
- await cb()
26
- } catch (e) {
27
- error(e)
28
- }
29
- }, ms)
30
- const cancel = () => {
31
- clearTimeout(tid)
32
- delete cleanups[idx]
33
- }
34
- cleanups[idx] = cancel
35
- return cancel
36
- }
37
-
38
- const shutdown = () => {
39
- isShutDown = true
40
-
41
- dbg(`Canceling ${values(cleanups.length).length} timers`)
42
- forEach(cleanups, (c) => c())
43
- dbg(`done`, cleanups)
44
- }
45
-
46
- const repeat = (
47
- cb: RepeatableTimerCallback,
48
- ms: UnixTimestampMs,
49
- initial = true,
50
- ) => {
51
- let _unsub: TimerCanceler | undefined = undefined
52
- const _again = async () => {
53
- const shouldRepeat = await cb()
54
- if (shouldRepeat && !isShutDown) _unsub = add(_again, ms)
55
- }
56
- add(_again, initial ? 0 : ms)
57
- return () => {
58
- _unsub?.()
59
- _unsub = undefined
60
- }
61
- }
62
-
63
- return { add, shutdown, repeat }
64
- }
@@ -1,26 +0,0 @@
1
- export function assertExists<TType>(
2
- v: TType,
3
- message = `Value does not exist`,
4
- ): asserts v is NonNullable<TType> {
5
- if (typeof v === 'undefined') {
6
- throw new Error(message)
7
- }
8
- }
9
-
10
- export function assertTruthy<TType>(
11
- v: unknown,
12
- message = `Value should be truthy`,
13
- ): asserts v is NonNullable<TType> {
14
- if (!v) {
15
- throw new Error(message)
16
- }
17
- }
18
-
19
- export function assert<T>(
20
- v: T | undefined | void | null,
21
- msg?: string,
22
- ): asserts v is T {
23
- if (!v) {
24
- throw new Error(msg || `Assertion failure`)
25
- }
26
- }
@@ -1,8 +0,0 @@
1
- import { boolean } from 'boolean'
2
-
3
- export const IS_DEV = () =>
4
- `PH_DEV` in process.env
5
- ? boolean(process.env.PH_DEV)
6
- : process.env.NODE_ENV === 'development'
7
- export const DEBUG = () =>
8
- `PH_DEBUG` in process.env ? boolean(process.env.PH_DEBUG) : IS_DEV()
@@ -1,16 +0,0 @@
1
- import { keys, map } from '@s-libs/micro-dash'
2
- import { ClientResponseError } from 'pocketbase'
3
-
4
- export const parseError = (e: any): string[] => {
5
- if (e instanceof ClientResponseError) {
6
- if (e.data.message && keys(e.data.data).length === 0)
7
- return [e.data.message]
8
- return map(e.data.data, (v, k) => (v ? v.message : undefined)).filter(
9
- (v) => !!v,
10
- )
11
- }
12
- if (e instanceof Error) {
13
- return [e.message]
14
- }
15
- return [e.toString()]
16
- }