mirror of
https://github.com/supabase/supabase.git
synced 2026-07-05 03:24:19 +08:00
200 lines
4.8 KiB
TypeScript
200 lines
4.8 KiB
TypeScript
import { makeObservable, action, observable, computed, toJS, makeAutoObservable } from 'mobx'
|
|
import { get, patch, post, delete_ } from 'lib/common/fetch'
|
|
import { keyBy, isEmpty } from 'lodash'
|
|
import { UserContent } from 'types'
|
|
import { API_URL } from 'lib/constants'
|
|
|
|
/**
|
|
* Singleton
|
|
* Usage:
|
|
* import { useProjectContentStore } from 'stores/userContent/projectContentStore'
|
|
* const contentStore = useProjectContentStore(projectRef)
|
|
* contentStore.load() // inside usEffect()
|
|
* @deprecated use content store on RootStore instead.
|
|
*/
|
|
let store: any = null
|
|
let projectRef: any = null
|
|
export function useProjectContentStore(ref: any) {
|
|
if (store === null || ref !== projectRef) {
|
|
// set the current ref
|
|
projectRef = ref
|
|
const baseUrl = `${API_URL}/projects/${ref}/content`
|
|
store = new ProjectContent(baseUrl)
|
|
}
|
|
return store
|
|
}
|
|
|
|
/**
|
|
* Local type declarations
|
|
*/
|
|
interface UserContentMap {
|
|
[key: string]: UserContent
|
|
}
|
|
|
|
/**
|
|
* MobX Store
|
|
* @deprecated
|
|
*/
|
|
export default class ProjectContent {
|
|
STATES = {
|
|
INITIAL: 'initial',
|
|
LOADING: 'loading',
|
|
ERROR: 'error',
|
|
LOADED: 'loaded',
|
|
}
|
|
rootStore = null
|
|
url = ''
|
|
state = this.STATES.INITIAL
|
|
data: UserContentMap = {}
|
|
error = null
|
|
|
|
/**
|
|
* @param connectionString And encrypted database connection string to pass to the API
|
|
*/
|
|
constructor(dataUrl: any) {
|
|
this.url = dataUrl
|
|
makeObservable(this, {
|
|
state: observable,
|
|
data: observable,
|
|
list: observable,
|
|
hasError: computed,
|
|
isLoading: computed,
|
|
})
|
|
}
|
|
|
|
async fetchData() {
|
|
const headers = {
|
|
'Content-Type': 'application/json',
|
|
}
|
|
const res = await get(this.url, { headers })
|
|
if (res.error) {
|
|
throw res.error
|
|
}
|
|
this.data = res.data.length > 0 ? keyBy(res.data, 'id') : res.data
|
|
return res
|
|
}
|
|
|
|
async load() {
|
|
let { LOADING, ERROR, LOADED } = this.STATES
|
|
try {
|
|
this.error = null
|
|
this.state = LOADING
|
|
await this.fetchData()
|
|
this.state = LOADED
|
|
return this.data
|
|
} catch (e: any) {
|
|
console.error('e.message', e.message)
|
|
this.error = e
|
|
this.state = ERROR
|
|
}
|
|
}
|
|
|
|
get hasError() {
|
|
return this.state === this.STATES.ERROR
|
|
}
|
|
|
|
get isLoading() {
|
|
return this.state === this.STATES.INITIAL || this.state === this.STATES.LOADING
|
|
}
|
|
|
|
list(filter: any) {
|
|
let arr = Object.values(this.data)
|
|
if (!!filter) {
|
|
return arr.filter(filter).sort((a, b) => a.name.localeCompare(b.name))
|
|
} else {
|
|
return arr.sort((a, b) => a.name.localeCompare(b.name))
|
|
}
|
|
}
|
|
|
|
reports(filter: any) {
|
|
let arr = Object.values(this.data)
|
|
if (!!filter) {
|
|
return arr
|
|
.filter((x) => x.type == 'report')
|
|
.filter(filter)
|
|
.sort((a, b) => a.name.localeCompare(b.name))
|
|
} else {
|
|
return arr.filter((x) => x.type == 'report').sort((a, b) => a.name.localeCompare(b.name))
|
|
}
|
|
}
|
|
|
|
sqlSnippets(filter: any) {
|
|
let arr = Object.values(this.data)
|
|
if (!!filter) {
|
|
const arr_filtered = arr
|
|
.filter((x) => x.type == 'sql')
|
|
.filter(filter)
|
|
.sort((a, b) => a.name.localeCompare(b.name))
|
|
|
|
return arr_filtered
|
|
} else {
|
|
const arr_filtered = arr
|
|
.filter((x) => x.type == 'sql')
|
|
.sort((a, b) => a.name.localeCompare(b.name))
|
|
|
|
return arr_filtered
|
|
}
|
|
}
|
|
|
|
byId(id: any) {
|
|
return this.data[id]
|
|
}
|
|
|
|
async create(payload: any) {
|
|
try {
|
|
const headers = {
|
|
'Content-Type': 'application/json',
|
|
}
|
|
const created = await post(this.url, payload, { headers })
|
|
if (created.error) throw created.error
|
|
this.data[created['id']] = created
|
|
return { data: created, error: null }
|
|
} catch (error) {
|
|
return { data: null, error }
|
|
}
|
|
}
|
|
|
|
async update(id: any, updates: any, type: any) {
|
|
try {
|
|
const headers = {
|
|
'Content-Type': 'application/json',
|
|
}
|
|
let payload = {
|
|
...updates,
|
|
type,
|
|
id,
|
|
}
|
|
const url = `${this.url}?id=${id}`
|
|
const updated = await patch(url, payload, { headers })
|
|
if (updated.error) throw updated.error
|
|
this.data[id] = updated
|
|
return { data: updated, error: null }
|
|
} catch (error) {
|
|
return { data: null, error }
|
|
}
|
|
}
|
|
|
|
async updateSql(id: any, updates: any) {
|
|
return this.update(id, updates, 'sql')
|
|
}
|
|
|
|
async updateReport(id: any, updates: any) {
|
|
return this.update(id, updates, 'report')
|
|
}
|
|
|
|
async del(id: any) {
|
|
try {
|
|
const headers = {
|
|
'Content-Type': 'application/json',
|
|
}
|
|
const url = `${this.url}?id=${id}`
|
|
const deleted = await delete_(url, {}, { headers })
|
|
if (deleted.error) throw deleted.error
|
|
delete this.data[id]
|
|
return { data: true, error: null }
|
|
} catch (error) {
|
|
return { data: false, error }
|
|
}
|
|
}
|
|
}
|