mirror of
https://github.com/pockethost/pockethost.git
synced 2025-07-04 03:42:29 +00:00
chore: REST refactor
This commit is contained in:
parent
881c42ddcb
commit
e09e80fa4f
@ -100,13 +100,13 @@ export const createPocketbaseClient = (config: PocketbaseClientConfig) => {
|
|||||||
|
|
||||||
const createInstance = mkRest<CreateInstancePayload, CreateInstanceResult>(
|
const createInstance = mkRest<CreateInstancePayload, CreateInstanceResult>(
|
||||||
RestCommands.Instance,
|
RestCommands.Instance,
|
||||||
RestMethods.Create,
|
RestMethods.Post,
|
||||||
CreateInstancePayloadSchema,
|
CreateInstancePayloadSchema,
|
||||||
)
|
)
|
||||||
|
|
||||||
const updateInstance = mkRest<UpdateInstancePayload, UpdateInstanceResult>(
|
const updateInstance = mkRest<UpdateInstancePayload, UpdateInstanceResult>(
|
||||||
RestCommands.Instance,
|
RestCommands.Instance,
|
||||||
RestMethods.Update,
|
RestMethods.Put,
|
||||||
UpdateInstancePayloadSchema,
|
UpdateInstancePayloadSchema,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
const isChecked = target.checked
|
const isChecked = target.checked
|
||||||
|
|
||||||
// Update the database with the new value
|
// Update the database with the new value
|
||||||
updateInstance({ instanceId: id, fields: { maintenance: isChecked } }).then(
|
updateInstance({ id, fields: { maintenance: isChecked } }).then(
|
||||||
() => 'saved',
|
() => 'saved',
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
// If they select yes, then update the version in pocketbase
|
// If they select yes, then update the version in pocketbase
|
||||||
if (confirmVersionChange) {
|
if (confirmVersionChange) {
|
||||||
updateInstance({
|
updateInstance({
|
||||||
instanceId: id,
|
id,
|
||||||
fields: {
|
fields: {
|
||||||
subdomain: instanceNameValidation,
|
subdomain: instanceNameValidation,
|
||||||
},
|
},
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
errorMessage = ''
|
errorMessage = ''
|
||||||
client()
|
client()
|
||||||
.updateInstance({
|
.updateInstance({
|
||||||
instanceId: id,
|
id,
|
||||||
fields: { version: selectedVersion },
|
fields: { version: selectedVersion },
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
// Save to the database
|
// Save to the database
|
||||||
items.upsert({ name: secretKey, value: secretValue })
|
items.upsert({ name: secretKey, value: secretValue })
|
||||||
await client().updateInstance({
|
await client().updateInstance({
|
||||||
instanceId: $instance.id,
|
id: $instance.id,
|
||||||
fields: {
|
fields: {
|
||||||
secrets: reduce(
|
secrets: reduce(
|
||||||
$items,
|
$items,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
"instanceId": "kz4ngg77eaw1ho0",
|
"id": "kz4ngg77eaw1ho0",
|
||||||
"fields": {
|
"fields": {
|
||||||
"maintenance": true
|
"maintenance": true
|
||||||
"name": '',
|
"name": '',
|
||||||
@ -12,12 +12,11 @@
|
|||||||
*/
|
*/
|
||||||
routerAdd(
|
routerAdd(
|
||||||
'PUT',
|
'PUT',
|
||||||
'/api/instance',
|
'/api/instance/:id',
|
||||||
(c) => {
|
(c) => {
|
||||||
console.log(`***TOP OF PUt`)
|
console.log(`***TOP OF PUT`)
|
||||||
let data = new DynamicModel({
|
let data = new DynamicModel({
|
||||||
// describe the shape of the fields to read (used also as initial values)
|
id: '',
|
||||||
instanceId: '',
|
|
||||||
fields: {
|
fields: {
|
||||||
maintenance: null,
|
maintenance: null,
|
||||||
name: null,
|
name: null,
|
||||||
@ -27,21 +26,28 @@ routerAdd(
|
|||||||
})
|
})
|
||||||
|
|
||||||
c.bind(data)
|
c.bind(data)
|
||||||
|
console.log(`***After bind`)
|
||||||
|
|
||||||
// This is necessary for destructuring to work correctly
|
// This is necessary for destructuring to work correctly
|
||||||
data = JSON.parse(JSON.stringify(data))
|
data = JSON.parse(JSON.stringify(data))
|
||||||
|
|
||||||
|
const id = c.pathParam('id')
|
||||||
const {
|
const {
|
||||||
instanceId,
|
|
||||||
fields: { maintenance, name, version, secrets },
|
fields: { maintenance, name, version, secrets },
|
||||||
} = data
|
} = data
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
`***vars`,
|
`***vars`,
|
||||||
JSON.stringify({ instanceId, maintenance, name, version, secrets }),
|
JSON.stringify({
|
||||||
|
id,
|
||||||
|
maintenance,
|
||||||
|
name,
|
||||||
|
version,
|
||||||
|
secrets,
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
const record = $app.dao().findRecordById('instances', instanceId)
|
const record = $app.dao().findRecordById('instances', id)
|
||||||
const authRecord = c.get('authRecord') // empty if not authenticated as regular auth record
|
const authRecord = c.get('authRecord') // empty if not authenticated as regular auth record
|
||||||
console.log(`***authRecord`, JSON.stringify(authRecord))
|
console.log(`***authRecord`, JSON.stringify(authRecord))
|
||||||
|
|
||||||
@ -53,22 +59,23 @@ routerAdd(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function cleanObject(obj) {
|
function cleanObject(obj) {
|
||||||
return Object.entries(obj).reduce((acc, [key, value]) => {
|
console.log(`***original`, JSON.stringify(obj))
|
||||||
|
const sanitized = Object.entries(obj).reduce((acc, [key, value]) => {
|
||||||
if (value !== null && value !== undefined) {
|
if (value !== null && value !== undefined) {
|
||||||
acc[key] = value
|
acc[key] = value
|
||||||
}
|
}
|
||||||
return acc
|
return acc
|
||||||
}, {})
|
}, {})
|
||||||
|
console.log(`***sanitized`, JSON.stringify(sanitized))
|
||||||
|
return sanitized
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`***original`, JSON.stringify(data))
|
|
||||||
const sanitized = cleanObject({
|
const sanitized = cleanObject({
|
||||||
subdomain: name,
|
subdomain: name,
|
||||||
version,
|
version,
|
||||||
maintenance,
|
maintenance,
|
||||||
secrets,
|
secrets,
|
||||||
})
|
})
|
||||||
console.log(`***sanitized`, JSON.stringify(sanitized))
|
|
||||||
|
|
||||||
const form = new RecordUpsertForm($app, record)
|
const form = new RecordUpsertForm($app, record)
|
||||||
form.loadData(sanitized)
|
form.loadData(sanitized)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import Ajv, { JSONSchemaType } from 'ajv'
|
import Ajv, { JSONSchemaType } from 'ajv'
|
||||||
import type pocketbaseEs from 'pocketbase'
|
import type pocketbaseEs from 'pocketbase'
|
||||||
|
import { ClientResponseError } from 'pocketbase'
|
||||||
import type { JsonObject } from 'type-fest'
|
import type { JsonObject } from 'type-fest'
|
||||||
import { LoggerService } from '../Logger'
|
import { LoggerService } from '../Logger'
|
||||||
import { RestCommands, RestMethods } from '../schema'
|
import { RestCommands, RestMethods } from '../schema'
|
||||||
@ -28,13 +29,41 @@ export const createRestHelper = (config: RestHelperConfig) => {
|
|||||||
if (!validator(payload)) {
|
if (!validator(payload)) {
|
||||||
throw new Error(`Invalid REST payload: ${validator.errors}`)
|
throw new Error(`Invalid REST payload: ${validator.errors}`)
|
||||||
}
|
}
|
||||||
|
const _payload = { ...payload }
|
||||||
|
|
||||||
const res = await client.send(`/api/${cmd}`, {
|
const url = `/api/${cmd}${
|
||||||
method: method,
|
method === RestMethods.Post ? '' : '/:id'
|
||||||
body: payload,
|
}`.replace(/:([a-zA-Z]+)/g, (_, key) => {
|
||||||
|
if (!(key in _payload)) {
|
||||||
|
throw new Error(`Payload must include '${key}`)
|
||||||
|
}
|
||||||
|
const value = _payload[key]!
|
||||||
|
delete _payload[key]
|
||||||
|
return encodeURIComponent(value.toString())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const options: any = {
|
||||||
|
method: method,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method !== RestMethods.Get) {
|
||||||
|
options.body = _payload
|
||||||
|
}
|
||||||
|
|
||||||
|
dbg({ url, options })
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await client.send(url, options)
|
||||||
dbg(res)
|
dbg(res)
|
||||||
return res
|
return res
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof ClientResponseError) {
|
||||||
|
error(`REST error: ${e.originalError}`)
|
||||||
|
throw e.originalError
|
||||||
|
}
|
||||||
|
error(`REST error: ${e}`)
|
||||||
|
throw e
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
import { JSONSchemaType } from 'ajv'
|
import { JSONSchemaType } from 'ajv'
|
||||||
import { InstanceId, Semver } from '../types'
|
import { InstanceFields } from '../Instance'
|
||||||
|
import { InstanceId } from '../types'
|
||||||
|
|
||||||
export type UpdateInstancePayload = {
|
export type UpdateInstancePayload = {
|
||||||
instanceId: InstanceId
|
id: InstanceId
|
||||||
fields: {
|
fields: Partial<
|
||||||
subdomain?: string
|
Pick<
|
||||||
maintenance?: boolean
|
InstanceFields,
|
||||||
version?: Semver
|
'maintenance' | 'secrets' | 'subdomain' | 'syncAdmin' | 'version'
|
||||||
secrets?: {
|
>
|
||||||
[_: string]: string
|
>
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SECRET_KEY_REGEX = /^[A-Z][A-Z0-9_]*$/
|
export const SECRET_KEY_REGEX = /^[A-Z][A-Z0-9_]*$/
|
||||||
@ -24,10 +23,11 @@ export const UpdateInstancePayloadSchema: JSONSchemaType<UpdateInstancePayload>
|
|||||||
{
|
{
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
instanceId: { type: 'string' },
|
id: { type: 'string' },
|
||||||
fields: {
|
fields: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
|
syncAdmin: { type: 'boolean', nullable: true },
|
||||||
subdomain: { type: 'string', nullable: true },
|
subdomain: { type: 'string', nullable: true },
|
||||||
maintenance: { type: 'boolean', nullable: true },
|
maintenance: { type: 'boolean', nullable: true },
|
||||||
version: {
|
version: {
|
||||||
@ -47,6 +47,6 @@ export const UpdateInstancePayloadSchema: JSONSchemaType<UpdateInstancePayload>
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
required: ['instanceId', 'fields'],
|
required: ['id', 'fields'],
|
||||||
additionalProperties: false,
|
additionalProperties: false,
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,9 @@ import Ajv from 'ajv'
|
|||||||
import { JsonObject } from 'type-fest'
|
import { JsonObject } from 'type-fest'
|
||||||
|
|
||||||
export enum RestMethods {
|
export enum RestMethods {
|
||||||
Create = 'POST',
|
Get = 'GET',
|
||||||
Update = 'PUT',
|
Post = 'POST',
|
||||||
|
Put = 'PUT',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum RestCommands {
|
export enum RestCommands {
|
||||||
@ -16,4 +17,3 @@ export const ajv = new Ajv()
|
|||||||
|
|
||||||
export * from './CreateInstance'
|
export * from './CreateInstance'
|
||||||
export * from './UpdateInstance'
|
export * from './UpdateInstance'
|
||||||
// gen:export
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user