diff --git a/gitbook/releases/0.9.0.md b/gitbook/releases/0.9.0.md index 1af944c0..674038fa 100644 --- a/gitbook/releases/0.9.0.md +++ b/gitbook/releases/0.9.0.md @@ -14,9 +14,22 @@ Highlights in this release: - Improved secrets - secrets are now passed to `pocketbase` executable and are available in JS hooks - Security - All `pocketbase` instances now run in Docker sandboxes in isolated environments. Reduces security risks and bad neighbor effects. - Started using `pb_hooks` internally to replace some complex listener logic +- SSG frontend for better SEO and load times ## Change log +- chore: remove old cli package +- enh: update sftp link +- chore: add permalink to live publishing step +- enh: Cloudflare Pages SSG publishing +- enh: SSG +- fix: sveltekit environment variables +- enh: invocation indexes +- chore: comment template environment variables +- enh: run PocketBase in debugging mode when DEBUG=true +- enh: gitignore update +- fix: db migrations +- fix: secondsThisMonth in users table - enh: usage tracking to JS hooks - enh: add docker-compose sample for better dx - enh: mothership backup script diff --git a/packages/cli/.gitignore b/packages/cli/.gitignore deleted file mode 100644 index 53c37a16..00000000 --- a/packages/cli/.gitignore +++ /dev/null @@ -1 +0,0 @@ -dist \ No newline at end of file diff --git a/packages/cli/.npmignore b/packages/cli/.npmignore deleted file mode 100644 index 38d55370..00000000 --- a/packages/cli/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -src -tsconfig.json -dist/index.* \ No newline at end of file diff --git a/packages/cli/package.json b/packages/cli/package.json deleted file mode 100644 index affe4965..00000000 --- a/packages/cli/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "pockethost", - "version": "0.0.5", - "main": "./dist/index.js", - "bin": { - "pbscript": "./dist/pbscript" - }, - "author": { - "name": "Ben Allfree", - "url": "https://github.com/benallfree" - }, - "repository": { - "url": "https://github.com/benallfree/pockethost" - }, - "scripts": { - "dev": "chokidar package.json 'src/**' './node_modules/**' -c 'yarn build' --initial", - "build": "parcel build --no-cache && yarn build:shebang && npm i -g --force .", - "build:shebang": "echo \"#!/usr/bin/env node\"|cat - ./dist/index.js > ./dist/pbscript", - "publish": "npm publish --access public" - }, - "license": "MIT", - "devDependencies": { - "parcel": "^2.7.0" - }, - "dependencies": { - "@types/eventsource": "^1.1.9", - "@types/node": "^18.8.2", - "@types/prompts": "^2.4.1", - "@types/tmp": "^0.2.3", - "commander": "^9.4.0", - "cross-fetch": "^3.1.5", - "eventsource": "^2.0.2", - "find-up": "^6.3.0", - "pocketbase": "^0.8.0", - "prompts": "^2.4.2", - "tmp": "^0.2.1" - }, - "targets": { - "node": { - "engines": { - "node": ">= 12" - }, - "source": "./src/index.ts", - "context": "node", - "outputFormat": "commonjs", - "includeNodeModules": [ - "@s-libs/micro-dash", - "find-up", - "locate-path", - "path-exists", - "p-locate", - "p-limit", - "yocto-queue", - "pocketbase" - ] - } - } -} \ No newline at end of file diff --git a/packages/cli/readme.md b/packages/cli/readme.md deleted file mode 100644 index 3db23030..00000000 --- a/packages/cli/readme.md +++ /dev/null @@ -1,25 +0,0 @@ -# TS/JS Cloud Functions for PocketBase - -[PBScript](https://github.com/benallfree/pbscript) allows you to write [PocketBase](https://pocketbase.io) server-side functions in Typescript or Javascript without recompiling. - -This package is the CLI tool. - -```bash -npm i -g pbscript -``` - -or - -```bash -npx pbscript --help -``` - -or - -```bash -npm i -D pbscript -``` - -And then reference from `package.json`. - -See official docs at the [PBScript repo](https://github.com/benallfree/pbscript). diff --git a/packages/cli/src/commands/build.ts b/packages/cli/src/commands/build.ts deleted file mode 100644 index ab7fd5cf..00000000 --- a/packages/cli/src/commands/build.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { Parcel } from '@parcel/core' -import { debounce } from '@s-libs/micro-dash' -import chokidar from 'chokidar' -import { Command } from 'commander' -import { mkdirSync } from 'fs' -import { join } from 'path' -import { cwd } from 'process' -import { getProjectRoot, readSettings } from '../util/project' - -export type BuildConfig = { - dist: string - src: string -} - -export const addDevCommand = (program: Command) => { - program - .command('build') - .description('Build the JS bundle') - .option( - '--src ', - `Path to source (default: /src/index.{ts|js})`, - ) - .option('--dist ', `Path to dist (default: /dist/index.js)`) - .action(async (options) => { - const defaultSrc = options.src - const defaultDist = options.dist - - const config: BuildConfig = { - src: join(getProjectRoot(), './src/index.ts'), - dist: join(getProjectRoot(), './dist/index.js'), - ...readSettings('build'), - } - if (defaultDist) config.dist = defaultDist - if (defaultSrc) config.src = defaultSrc - - const { src, dist } = config - mkdirSync(dist, { recursive: true }) - console.log(cwd()) - - const bundler = new Parcel({ - entries: './src/index.ts', - defaultConfig: '@parcel/config-default', - mode: 'production', - defaultTargetOptions: { - distDir: join(cwd(), 'dist'), - outputFormat: 'global', - sourceMaps: false, - }, - shouldDisableCache: true, - // targets: { - // iife: { - // distDir: './dist', - // source: './src/index.ts', - // context: 'browser', - // outputFormat: 'global', - // sourceMap: { - // inline: true, - // }, - // }, - // }, - }) - - const build = debounce(() => { - console.log(`Building...`) - bundler - .run() - .then((e) => { - console.log(`Build succeeded`, e) - console.log(e.bundleGraph.getBundles({ includeInline: true })) - let { bundleGraph } = e - }) - .catch((e) => { - console.error(`Build failed with ${e}`) - }) - }, 100) - - build() - console.log(join(getProjectRoot(), 'src/**')) - chokidar - .watch([ - join(getProjectRoot(), 'src/**'), - join(getProjectRoot(), 'node_modules/**'), - ]) - .on('all', (event, path) => { - build() - }) - - console.log('here') - }) -} diff --git a/packages/cli/src/commands/dev.ts b/packages/cli/src/commands/dev.ts deleted file mode 100644 index 387e7c6c..00000000 --- a/packages/cli/src/commands/dev.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { DEFAULT_PB_DEV_URL } from '$constants' -import { Parcel } from '@parcel/core' -import { debounce } from '@s-libs/micro-dash' -import chokidar from 'chokidar' -import { Command } from 'commander' -import { join } from 'path' -import { cwd } from 'process' -import tmp from 'tmp' -import { SessionState } from '../providers/CustomAuthStore' -import { ensureAdminClient } from '../util/ensureAdminClient' -import { getProjectRoot, readSettings } from '../util/project' - -export type DevConfig = { - session: SessionState - host: string - src: string - dist: string -} -export const addDevCommand = (program: Command) => { - program - .command('dev') - .description('Watch for source code changes in development mode') - .option( - '--src ', - `Path to source (default: /src/index.{ts|js})`, - ) - .option('--dist ', `Path to dist (default: /dist/index.js)`) - .option('--host', 'PocketBase host', DEFAULT_PB_DEV_URL) - .action(async (options) => { - const defaultSrc = options.src - const defaultDist = options.dist - const defaultHost = options.host - - const config: DevConfig = { - session: { token: '', model: null }, - host: DEFAULT_PB_DEV_URL, - src: join(getProjectRoot(), './src/index.ts'), - dist: join(getProjectRoot(), './dist/index.js'), - ...readSettings('dev'), - } - if (defaultDist) config.dist = defaultDist - if (defaultSrc) config.src = defaultSrc - - const client = await ensureAdminClient('dev', config) - - const distDir = tmp.dirSync().name - console.log(cwd()) - - const bundler = new Parcel({ - entries: './src/index.ts', - defaultConfig: '@parcel/config-default', - mode: 'production', - defaultTargetOptions: { - distDir: join(cwd(), 'dist'), - outputFormat: 'global', - sourceMaps: false, - }, - shouldDisableCache: true, - // targets: { - // iife: { - // distDir: './dist', - // source: './src/index.ts', - // context: 'browser', - // outputFormat: 'global', - // sourceMap: { - // inline: true, - // }, - // }, - // }, - }) - - const build = debounce(() => { - console.log(`Building...`) - bundler - .run() - .then((e) => { - console.log(`Build succeeded`, e) - console.log(e.bundleGraph.getBundles({ includeInline: true })) - let { bundleGraph } = e - }) - .catch((e) => { - console.error(`Build failed with ${e}`) - }) - }, 100) - - build() - console.log(join(getProjectRoot(), 'src/**')) - chokidar - .watch([ - join(getProjectRoot(), 'src/**'), - join(getProjectRoot(), 'node_modules/**'), - ]) - .on('all', (event, path) => { - build() - }) - - console.log('here') - }) -} diff --git a/packages/cli/src/commands/publish.ts b/packages/cli/src/commands/publish.ts deleted file mode 100644 index 5a3a29ee..00000000 --- a/packages/cli/src/commands/publish.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { DEFAULT_PB_DEV_URL } from '$constants' -import { Command } from 'commander' -import { existsSync, readFileSync } from 'fs' -import { join } from 'path' -import pocketbaseEs from 'pocketbase' -import { SessionState } from '../providers/CustomAuthStore' -import { die } from '../util/die' -import { ensureAdminClient } from '../util/ensureAdminClient' -import { getProjectRoot, readSettings } from '../util/project' - -export type PublishConfig = { - session: SessionState - host: string - dist: string -} - -const migrate = async (client: pocketbaseEs) => { - { - // VERSION 1 - const res = await client.collections.getList(1, 1, { - filter: `name='pbscript'`, - }) - const [item] = res.items - if (!item) { - await client.collections.create({ - name: 'pbscript', - schema: [ - { - name: 'type', - type: 'text', - required: true, - }, - { - name: 'isActive', - type: 'bool', - }, - { - name: 'data', - type: 'json', - required: true, - }, - ], - }) - } - } -} - -const publish = async (client: pocketbaseEs, fname: string) => { - const js = readFileSync(fname).toString() - const url = `${client.baseUrl}/api/pbscript/deploy` - const res = await client - .send(`api/pbscript/deploy`, { - method: 'post', - body: JSON.stringify({ - source: js, - }), - headers: { 'Content-Type': 'application/json' }, - }) - .catch((e) => { - console.error(e) - throw e - }) -} - -export const addPublishCommand = (program: Command) => { - const _srcDefault = join(getProjectRoot(), './dist/index.js') - const _hostDefault = DEFAULT_PB_DEV_URL - program - .command('publish') - .description('Publish JS bundle to PBScript-enabled PocketBase instance') - .option( - '--dist ', - `Path to dist bundle (default: /dist/index.js)`, - ) - .option('--host ', `PocketBase host (default: ${DEFAULT_PB_DEV_URL})`) - .action(async (options) => { - const defaultHost = options.host - const defaultDist = options.dist - - const config: PublishConfig = { - session: { token: '', model: null }, - host: DEFAULT_PB_DEV_URL, - dist: join(getProjectRoot(), './dist/index.js'), - ...readSettings('publish'), - } - if (defaultHost) config.host = defaultHost - if (defaultDist) config.dist = defaultDist - - const { host, dist } = config - - if (!existsSync(dist)) { - die(`${dist} does not exist. Nothing to publish.`) - } - - const client = await ensureAdminClient('publish', config) - console.log(`Deploying from ${dist} to ${host}`) - await migrate(client) - await publish(client, dist) - }) -} diff --git a/packages/cli/src/constants.ts b/packages/cli/src/constants.ts deleted file mode 100644 index 29fb6ee7..00000000 --- a/packages/cli/src/constants.ts +++ /dev/null @@ -1 +0,0 @@ -export const DEFAULT_PB_DEV_URL = `http://127.0.0.1:8090` diff --git a/packages/cli/src/helpers/buildQueryFilter.ts b/packages/cli/src/helpers/buildQueryFilter.ts deleted file mode 100644 index 7cf4ad72..00000000 --- a/packages/cli/src/helpers/buildQueryFilter.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { map } from '@s-libs/micro-dash' -import { Pb_Any_Record_Db, Pb_QueryParams } from '../schema/base' - -export type FieldStruct = Partial<{ - [_ in keyof TRec]: TRec[_] -}> - -export const buildQueryFilter = ( - fields: FieldStruct, -): Pb_QueryParams => { - const filter = map(fields, (v, k) => `${k.toString()} = "${v}"`).join(' and ') - return { filter } -} diff --git a/packages/cli/src/helpers/getOne.ts b/packages/cli/src/helpers/getOne.ts deleted file mode 100644 index ddafe39c..00000000 --- a/packages/cli/src/helpers/getOne.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { assertTruthy } from 'util/assert' -import { client } from '../client' -import { - Pb_Any_Collection_Name, - Pb_Any_Record_Db, - Pb_Untrusted_Db, -} from '../schema/base' -import { FieldStruct, buildQueryFilter } from './buildQueryFilter' - -export const getOne = async < - TRec extends Pb_Any_Record_Db, - TFields extends FieldStruct = FieldStruct, ->( - collectionName: Pb_Any_Collection_Name, - fields: TFields, -) => { - const queryParams = buildQueryFilter(fields) - const recs = await client.records.getList(collectionName, 1, 2, queryParams) - assertTruthy(recs.totalItems < 2, `Expected exactly 0 or 1 items here`) - const [item] = recs.items - return item ? (recs.items[0] as unknown as Pb_Untrusted_Db) : null -} diff --git a/packages/cli/src/helpers/index.ts b/packages/cli/src/helpers/index.ts deleted file mode 100644 index 16e2a2ec..00000000 --- a/packages/cli/src/helpers/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './getOne' -export * from './onAuthStateChanged' -export * from './pbUid' -export * from './signInAnonymously' -export * from './upsert' diff --git a/packages/cli/src/helpers/mergeDeep.ts b/packages/cli/src/helpers/mergeDeep.ts deleted file mode 100644 index 8ea281b9..00000000 --- a/packages/cli/src/helpers/mergeDeep.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { forEach, isObject } from '@s-libs/micro-dash' - -export const mergeDeep = (dst: any, src: TObject) => { - forEach(src, (v, k) => { - if (isObject(v)) { - if (dst[k] === undefined) dst[k] = {} - if (!isObject(dst[k])) { - throw new Error( - `${k.toString()} is an object in default, but not in target`, - ) - } - dst[k] = mergeDeep(dst[k], v) - } else { - if (isObject(dst[k])) { - throw new Error( - `${k.toString()} is an object in target, but not in default`, - ) - } - // The magic: if the target has no value for this field, use the - // default value - if (dst[k] === undefined) { - dst[k] = v - } - } - }) - return dst as TObject -} diff --git a/packages/cli/src/helpers/onAuthStateChanged.ts b/packages/cli/src/helpers/onAuthStateChanged.ts deleted file mode 100644 index 540426e6..00000000 --- a/packages/cli/src/helpers/onAuthStateChanged.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { UnsubFunc } from 'store/backend/types' -import { client } from '../client' - -export const onAuthStateChanged = ( - cb: (user: typeof client.authStore.model) => void, -): UnsubFunc => { - setTimeout(() => cb(client.authStore.model), 0) - return client.authStore.onChange(() => { - cb(client.authStore.model) - }) -} diff --git a/packages/cli/src/helpers/pbUid.ts b/packages/cli/src/helpers/pbUid.ts deleted file mode 100644 index e0131cda..00000000 --- a/packages/cli/src/helpers/pbUid.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { identity } from 'ts-brand' -import { client } from '../client' -import { Pb_UserId } from '../schema/base' - -export const pbUid = () => { - const { id } = client.authStore.model || {} - if (!id) return - return identity(id) -} diff --git a/packages/cli/src/helpers/signInAnonymously.ts b/packages/cli/src/helpers/signInAnonymously.ts deleted file mode 100644 index 0e46f8df..00000000 --- a/packages/cli/src/helpers/signInAnonymously.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { customAlphabet } from 'nanoid' -import { identity } from 'ts-brand' -import { client } from '../client' -import { Email, Password, PbCreds } from '../schema/base' - -export const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz') - -export const signInAnonymously = () => { - const { email, password } = (() => { - const credsJson = localStorage.getItem('__pb_creds') - if (credsJson) { - return JSON.parse(credsJson) as PbCreds - } - const email = identity(`${nanoid()}@harvest.io`) - const password = identity(nanoid()) - return { email, password } - })() - - return client.users.authViaEmail(email, password).catch((e) => { - console.error(`Couldn't long in anonymously: ${e}`) - }) -} diff --git a/packages/cli/src/helpers/upsert.ts b/packages/cli/src/helpers/upsert.ts deleted file mode 100644 index 7c04f8f4..00000000 --- a/packages/cli/src/helpers/upsert.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { reduce } from '@s-libs/micro-dash' -import produce, { Draft, produceWithPatches } from 'immer' -import { assertExists, assertTruthy } from 'util/assert' -import { client } from '../client' -import { - Pb_Any_Collection_Name, - Pb_Any_Record_Db, - Pb_Untrusted_Db, - Pb_UserFields, -} from '../schema/base' -import { FieldStruct, buildQueryFilter } from './buildQueryFilter' -import { mergeDeep } from './mergeDeep' - -export const upsert = async ( - collectionName: Pb_Any_Collection_Name, - filterFields: FieldStruct, - mutate: (draft: Draft>) => void, - defaultRec: Pb_UserFields, -) => { - const queryParams = buildQueryFilter(filterFields) - const recs = await client.records.getList(collectionName, 1, 2, queryParams) - assertTruthy(recs.totalItems < 2, `Expected exactly 0 or 1 item to upsert`) - if (recs.totalItems === 0) { - // Insert - client.records.create(collectionName, produce(defaultRec, mutate)) - } else { - // Update - const [item] = recs.items as unknown as Pb_Untrusted_Db[] - assertExists(item, `Expected item here`) - const { id } = item - const safeItem = mergeDeep(item, defaultRec) - const [rec, patches] = produceWithPatches(safeItem, mutate) - console.log({ patches }) - const final = reduce( - patches, - (carry, patch) => { - if (patch.op === 'add' || patch.op === 'replace') { - const [key] = patch.path - assertExists(key, `Expected key here`) - const _key = `${key}` as keyof Pb_UserFields - carry[_key] = rec[_key] - } - return carry - }, - {} as Partial>, - ) - client.records.update(collectionName, id, final) - } -} diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts deleted file mode 100644 index 05199875..00000000 --- a/packages/cli/src/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { program } from 'commander' - -declare global { - let __go_app: any -} - -import 'cross-fetch/polyfill' -import 'eventsource' -import packagex from '../package.json' -import { addPublishCommand } from './commands/publish' -console.log(`PBScript ${packagex.version}`) - -program - .name('pbscript') - .description('CLI for JavaScript extensions for PocketBase ') - .version('0.0.1') -addPublishCommand(program) -// addDevCommand(program) - -program.parse() diff --git a/packages/cli/src/providers/CustomAuthStore.ts b/packages/cli/src/providers/CustomAuthStore.ts deleted file mode 100644 index 825a1606..00000000 --- a/packages/cli/src/providers/CustomAuthStore.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Admin, BaseAuthStore, User } from 'pocketbase' - -export interface SerializeOptions { - encode?: (val: string | number | boolean) => string - maxAge?: number - domain?: string - path?: string - expires?: Date - httpOnly?: boolean - secure?: boolean - priority?: string - sameSite?: boolean | string -} - -export type SessionState = { token: string; model: User | Admin | null } -export type SessionStateSaver = (state: SessionState) => void - -export class CustomAuthStore extends BaseAuthStore { - _save: SessionStateSaver - - constructor(state: SessionState, _save: SessionStateSaver) { - super() - const { token, model } = state - this.baseToken = token - this.baseModel = model - this._save = _save - } - get get() { - // console.log(`Get token`) - return this.baseToken - } - get model(): User | Admin | null { - // console.log(`get model`) - return this.baseModel - } - get isValid(): boolean { - // console.log(`isValid`) - return !!this.baseToken - } - save(token: string, model: User | Admin | null) { - this._save({ token, model }) - this.baseModel = model - this.baseToken = token - } - clear(): void { - throw new Error(`Unsupported clear()`) - } - loadFromCookie(cookie: string, key?: string | undefined): void { - throw new Error(`Unsupported loadFromCookie()`) - } - exportToCookie( - options?: SerializeOptions | undefined, - key?: string | undefined, - ): string { - throw new Error(`Unsupported exportToCookie()`) - } -} diff --git a/packages/cli/src/util/assert.ts b/packages/cli/src/util/assert.ts deleted file mode 100644 index c3eb4bcf..00000000 --- a/packages/cli/src/util/assert.ts +++ /dev/null @@ -1,8 +0,0 @@ -export function assertExists( - v: TType, - message = `Value does not exist`, -): asserts v is NonNullable { - if (typeof v === 'undefined') { - throw new Error(message) - } -} diff --git a/packages/cli/src/util/die.ts b/packages/cli/src/util/die.ts deleted file mode 100644 index b2752533..00000000 --- a/packages/cli/src/util/die.ts +++ /dev/null @@ -1,4 +0,0 @@ -export function die(msg: string): never { - console.error(msg) - process.exit(1) -} diff --git a/packages/cli/src/util/ensureAdminClient.ts b/packages/cli/src/util/ensureAdminClient.ts deleted file mode 100644 index 48156d56..00000000 --- a/packages/cli/src/util/ensureAdminClient.ts +++ /dev/null @@ -1,71 +0,0 @@ -import prompts from 'prompts' -import { SessionState } from '../providers/CustomAuthStore' -import { die } from './die' -import { isAdmin, pbClient } from './pbClient' -import { mkProjectSaver } from './project' - -function isEmail(email: string) { - var emailFormat = /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/ - if (email !== '' && email.match(emailFormat)) { - return true - } - - return false -} - -export type ConnectionConfig = { - session: SessionState - host: string -} - -export const ensureAdminClient = async ( - slug: string, - config: ConnectionConfig, -) => { - const saver = mkProjectSaver(slug) - const client = pbClient(config, (session) => - saver((config) => ({ ...config, session })), - ) - const _isAdmin = await isAdmin(client) - if (_isAdmin) { - return client - } - - const { host } = config - - console.log( - `You must be logged in to ${host}/_ as a PocketBase admin to continue.`, - ) - - while (true) { - const response = await prompts( - [ - { - type: 'text', - name: 'username', - message: 'Username (email):', - validate: (value: string) => - isEmail(value) ? true : `Enter an email address`, - }, - { - type: 'password', - name: 'password', - message: 'Password:', - validate: (value: string) => - value.length > 0 ? true : `Enter a password`, - }, - ], - { onCancel: () => die(`Exited.`) }, - ) - const { username, password } = response - try { - await client.admins.authViaEmail(username, password) - saver((config) => ({ ...config, host })) - console.log(`Successfully logged in as ${username} for project `) - break - } catch (e) { - console.error(`Login failed for ${username}. Try again.`) - } - } - return client -} diff --git a/packages/cli/src/util/pbClient.ts b/packages/cli/src/util/pbClient.ts deleted file mode 100644 index 12ef46b1..00000000 --- a/packages/cli/src/util/pbClient.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { default as PocketBase, default as pocketbaseEs } from 'pocketbase' -import { - CustomAuthStore, - SessionStateSaver, -} from '../providers/CustomAuthStore' -import { assertExists } from './assert' -import { die } from './die' -import { ConnectionConfig } from './ensureAdminClient' - -export const pbClient = ( - config: ConnectionConfig, - saver: SessionStateSaver, -) => { - const { host, session } = config - const client = new PocketBase( - host, - 'en-US', - new CustomAuthStore(session, saver), - ) - return client -} - -export const isAdmin = async (client: pocketbaseEs) => { - if (!client.authStore.isValid) return false - const { model } = client.authStore - if (!model) return false - const res = await client.admins.getOne(model.id) - if (!res) return false - return true -} - -export const adminPbClient = async ( - config: ConnectionConfig, - saver: SessionStateSaver, -) => { - const client = pbClient(config, saver) - if (!client.authStore.isValid) { - die(`Must be logged in to PocketBase as an admin.`) - } - const { model } = client.authStore - assertExists(model, `Expected a valid model here`) - const res = await client.admins.getOne(model.id) - if (!res) { - die(`User must be an admin user.`) - } - return client -} diff --git a/packages/cli/src/util/project.ts b/packages/cli/src/util/project.ts deleted file mode 100644 index e4fd4ef1..00000000 --- a/packages/cli/src/util/project.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { findUpSync } from 'find-up' -import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs' -import { dirname, join } from 'path' -import { cwd } from 'process' -import { SessionState } from '../providers/CustomAuthStore' - -export type TConfigProjectConfig = { - dev: { - session: SessionState - host: string - } - publish: { - session: SessionState - host: string - } - src: string - dist: string -} - -export const CACHE_FNAME = '.pbcache' - -export const mkProjectSaver = (slug: string) => { - type ConfigMutator = (config: Partial) => Partial - return (m: ConfigMutator) => { - const root = getProjectRoot() - const cachePath = join(root, CACHE_FNAME) - if (!existsSync(cachePath)) { - mkdirSync(cachePath, { recursive: true }) - } - const currentConfig = readSettings(slug) - const nextConfig = m(currentConfig) - const fname = join(cachePath, slug) - const json = JSON.stringify(nextConfig, null, 2) - console.log(`Saving to ${fname}`, json) - writeFileSync(`${fname}.json`, json) - } -} - -export const getProjectRoot = () => { - const root = findUpSync(`package.json`) - if (!root) return cwd() - return dirname(root) -} - -export const readSettings = (name: string): Partial => { - const root = getProjectRoot() - const fname = join(root, CACHE_FNAME, `${name}.json`) - if (!existsSync(fname)) return {} - const json = readFileSync(fname).toString() - const settings = JSON.parse(json) - return settings as Partial -} diff --git a/packages/cli/tsconfig.json b/packages/cli/tsconfig.json deleted file mode 100644 index 860d586d..00000000 --- a/packages/cli/tsconfig.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "compilerOptions": { - "allowJs": true, - "checkJs": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true, - "skipLibCheck": true, - "strict": true, - "module": "ESNext", - "target": "ESNext", - "moduleResolution": "node", - "noUncheckedIndexedAccess": true, - "strictNullChecks": true - }, - "include": ["./src"] -}