Files
sub-store/frontend/src/api/index.js
T
rogee 9ec8c956c1 feat: sing-box Clash template support + Docker CI + frontend scaffold
- Clash→sing-box template conversion engine (singbox_template.go)
- Auto-map 40+ Clash rule-providers to sing-box .srs binary rule-sets
- Fix sing-box 1.11+/1.12+ migrations (sniff/block/WireGuard/DNS/rule_set)
- Fix WireGuard URI '+' parsing bug (rawParamGet)
- Add REJECT block outbound for selector group references
- Skip rules referencing rule-sets with no sing-box equivalent
- Verified: sing-box run succeeds with ACL4SSR template (16 rule-sets loaded)
- Add Dockerfile (multi-stage Go build)
- Add GitHub Actions workflow (multi-arch: amd64+arm64, push to ghcr.io)
- Add frontend scaffold (Vue3 + Vite + Tailwind)
2026-07-27 21:56:19 +08:00

99 lines
3.7 KiB
JavaScript

import axios from 'axios'
import { getEffectiveToken, clearToken } from '@/utils/token'
// Read runtime config (injected by config.js, defaults to same-origin)
const apiBaseUrl = (window.SUB_STORE_CONFIG?.apiBaseUrl) || ''
const api = axios.create({
baseURL: apiBaseUrl + '/api',
timeout: 30000,
})
// Request interceptor — attach admin token
api.interceptors.request.use((config) => {
const token = getEffectiveToken()
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
})
// Response interceptor — unwrap data, handle errors
api.interceptors.response.use(
(response) => response.data,
(error) => {
if (error.response?.status === 401) {
// Token might be stale — clear it and let the router guard handle redirect
clearToken()
}
const msg = error.response?.data?.error?.message || error.message || 'Request failed'
return Promise.reject(new Error(msg))
}
)
// --- API methods ---
// Env
export const getEnv = () => api.get('/env')
export const getScripts = () => api.get('/scripts')
// Settings
export const getSettings = () => api.get('/settings')
export const updateSettings = (data) => api.patch('/settings', data)
// Storage
export const exportStorage = () => api.get('/storage')
export const importStorage = (data) => api.post('/storage', data)
// Sources
export const listSources = () => api.get('/sources')
export const createSource = (data) => api.post('/sources', data)
export const getSource = (name) => api.get(`/sources/${name}`)
export const updateSource = (name, data) => api.patch(`/sources/${name}`, data)
export const deleteSource = (name) => api.delete(`/sources/${name}`)
export const sortSources = (ids) => api.put('/sources', ids)
// Collections
export const listCollections = () => api.get('/collections')
export const createCollection = (data) => api.post('/collections', data)
export const getCollection = (name) => api.get(`/collections/${name}`)
export const updateCollection = (name, data) => api.patch(`/collections/${name}`, data)
export const deleteCollection = (name) => api.delete(`/collections/${name}`)
export const sortCollections = (ids) => api.put('/collections', ids)
// Templates
export const listTemplates = () => api.get('/templates')
export const createTemplate = (data) => api.post('/templates', data)
export const getTemplate = (name) => api.get(`/templates/${name}`)
export const updateTemplate = (name, data) => api.patch(`/templates/${name}`, data)
export const deleteTemplate = (name) => api.delete(`/templates/${name}`)
// Shares
export const listShares = () => api.get('/shares')
export const createShare = (data) => api.post('/shares', data)
export const updateShare = (id, data) => api.patch(`/shares/${id}`, data)
export const deleteShare = (id) => api.delete(`/shares/${id}`)
// Recycle bin
export const listRecycleBin = () => api.get('/recycle-bin')
export const deleteRecycleEntry = (id) => api.delete(`/recycle-bin/${id}`)
export const restoreRecycleEntry = (id) => api.post(`/recycle-bin/${id}/restore`)
// Preview
export const previewSource = (data) => api.post('/preview/source', data)
export const previewCollection = (data) => api.post('/preview/collection', data)
// Download links
export const getLinkSource = (name, target) => api.get(`/link/source/${name}`, { params: target ? { target } : {} })
export const getLinkCollection = (name, target) => api.get(`/link/collection/${name}`, { params: target ? { target } : {} })
// Flow info
export const getFlowInfo = (name) => api.get(`/source/flow/${name}`)
// Tools
export const parseProxy = (data) => api.post('/proxy/parse', data)
export const parseRule = (data) => api.post('/rule/parse', data)
export const getNodeInfo = (server) => api.post('/utils/node-info', { server })
export default api