@morscherlab/mld-sdk 0.9.1 → 0.9.2
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.
|
@@ -17,6 +17,9 @@ function useApi(options = {}) {
|
|
|
17
17
|
const settingsStore = useSettingsStore();
|
|
18
18
|
const authStore = useAuthStore();
|
|
19
19
|
const apiClient = getApiClient();
|
|
20
|
+
if (!authStore.isInitialized) {
|
|
21
|
+
authStore.initialize();
|
|
22
|
+
}
|
|
20
23
|
if (!interceptorAttached) {
|
|
21
24
|
apiClient.interceptors.request.use((config) => {
|
|
22
25
|
config.baseURL = options.baseUrl ?? settingsStore.getApiBaseUrl();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useApi.js","sources":["../../src/composables/useApi.ts"],"sourcesContent":["import axios, { type AxiosInstance, type AxiosRequestConfig } from 'axios'\nimport { useSettingsStore } from '../stores/settings'\nimport { useAuthStore } from '../stores/auth'\n\nlet apiClientInstance: AxiosInstance | null = null\nlet interceptorAttached = false\n\nfunction getApiClient(): AxiosInstance {\n if (!apiClientInstance) {\n apiClientInstance = axios.create({\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n }\n return apiClientInstance\n}\n\nexport interface ApiClientOptions {\n baseUrl?: string\n timeout?: number\n withAuth?: boolean\n}\n\nexport interface UseApiReturn {\n client: AxiosInstance\n get: <T>(url: string, config?: AxiosRequestConfig) => Promise<T>\n post: <T>(url: string, data?: unknown, config?: AxiosRequestConfig) => Promise<T>\n put: <T>(url: string, data?: unknown, config?: AxiosRequestConfig) => Promise<T>\n patch: <T>(url: string, data?: unknown, config?: AxiosRequestConfig) => Promise<T>\n delete: <T>(url: string, config?: AxiosRequestConfig) => Promise<T>\n upload: <T>(url: string, file: File, fieldName?: string, additionalData?: Record<string, unknown>) => Promise<T>\n download: (url: string, filename?: string) => Promise<string>\n buildUrl: (path: string) => string\n buildWsUrl: (path: string) => string\n}\n\nexport function useApi(options: ApiClientOptions = {}): UseApiReturn {\n const settingsStore = useSettingsStore()\n const authStore = useAuthStore()\n const apiClient = getApiClient()\n\n // Attach interceptor only once\n if (!interceptorAttached) {\n apiClient.interceptors.request.use((config) => {\n // Set base URL from settings or options\n config.baseURL = options.baseUrl ?? settingsStore.getApiBaseUrl()\n config.timeout = options.timeout ?? settingsStore.requestTimeout\n\n // Add Authorization header if token exists and auth is not explicitly disabled\n if (options.withAuth !== false && authStore.token) {\n config.headers.Authorization = `Bearer ${authStore.token}`\n }\n\n return config\n })\n interceptorAttached = true\n }\n\n // Generic request methods\n async function get<T>(url: string, config?: AxiosRequestConfig): Promise<T> {\n const response = await apiClient.get<T>(url, config)\n return response.data\n }\n\n async function post<T>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T> {\n const response = await apiClient.post<T>(url, data, config)\n return response.data\n }\n\n async function put<T>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T> {\n const response = await apiClient.put<T>(url, data, config)\n return response.data\n }\n\n async function patch<T>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T> {\n const response = await apiClient.patch<T>(url, data, config)\n return response.data\n }\n\n async function del<T>(url: string, config?: AxiosRequestConfig): Promise<T> {\n const response = await apiClient.delete<T>(url, config)\n return response.data\n }\n\n // File upload helper\n async function upload<T>(url: string, file: File, fieldName = 'file', additionalData?: Record<string, unknown>): Promise<T> {\n const formData = new FormData()\n formData.append(fieldName, file)\n\n if (additionalData) {\n Object.entries(additionalData).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n formData.append(key, typeof value === 'object' ? JSON.stringify(value) : String(value))\n }\n })\n }\n\n const response = await apiClient.post<T>(url, formData, {\n headers: { 'Content-Type': 'multipart/form-data' },\n })\n return response.data\n }\n\n // Download helper - returns blob URL\n async function download(url: string, filename?: string): Promise<string> {\n const response = await apiClient.get(url, { responseType: 'blob' })\n const blob = new Blob([response.data])\n const blobUrl = URL.createObjectURL(blob)\n\n // Optionally trigger download\n if (filename) {\n const link = document.createElement('a')\n link.href = blobUrl\n link.download = filename\n link.click()\n }\n\n return blobUrl\n }\n\n // Build full URL for external use (e.g., <a href=\"...\">)\n function buildUrl(path: string): string {\n const baseUrl = options.baseUrl ?? settingsStore.getApiBaseUrl()\n return `${baseUrl}${path}`\n }\n\n // WebSocket URL builder\n function buildWsUrl(path: string): string {\n return `${settingsStore.getWsBaseUrl()}${path}`\n }\n\n return {\n client: apiClient,\n get,\n post,\n put,\n patch,\n delete: del,\n upload,\n download,\n buildUrl,\n buildWsUrl,\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useApi.js","sources":["../../src/composables/useApi.ts"],"sourcesContent":["import axios, { type AxiosInstance, type AxiosRequestConfig } from 'axios'\nimport { useSettingsStore } from '../stores/settings'\nimport { useAuthStore } from '../stores/auth'\n\nlet apiClientInstance: AxiosInstance | null = null\nlet interceptorAttached = false\n\nfunction getApiClient(): AxiosInstance {\n if (!apiClientInstance) {\n apiClientInstance = axios.create({\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n }\n return apiClientInstance\n}\n\nexport interface ApiClientOptions {\n baseUrl?: string\n timeout?: number\n withAuth?: boolean\n}\n\nexport interface UseApiReturn {\n client: AxiosInstance\n get: <T>(url: string, config?: AxiosRequestConfig) => Promise<T>\n post: <T>(url: string, data?: unknown, config?: AxiosRequestConfig) => Promise<T>\n put: <T>(url: string, data?: unknown, config?: AxiosRequestConfig) => Promise<T>\n patch: <T>(url: string, data?: unknown, config?: AxiosRequestConfig) => Promise<T>\n delete: <T>(url: string, config?: AxiosRequestConfig) => Promise<T>\n upload: <T>(url: string, file: File, fieldName?: string, additionalData?: Record<string, unknown>) => Promise<T>\n download: (url: string, filename?: string) => Promise<string>\n buildUrl: (path: string) => string\n buildWsUrl: (path: string) => string\n}\n\nexport function useApi(options: ApiClientOptions = {}): UseApiReturn {\n const settingsStore = useSettingsStore()\n const authStore = useAuthStore()\n const apiClient = getApiClient()\n\n // Ensure auth store is initialized (reads token from localStorage)\n if (!authStore.isInitialized) {\n authStore.initialize()\n }\n\n // Attach interceptor only once\n if (!interceptorAttached) {\n apiClient.interceptors.request.use((config) => {\n // Set base URL from settings or options\n config.baseURL = options.baseUrl ?? settingsStore.getApiBaseUrl()\n config.timeout = options.timeout ?? settingsStore.requestTimeout\n\n // Add Authorization header if token exists and auth is not explicitly disabled\n if (options.withAuth !== false && authStore.token) {\n config.headers.Authorization = `Bearer ${authStore.token}`\n }\n\n return config\n })\n interceptorAttached = true\n }\n\n // Generic request methods\n async function get<T>(url: string, config?: AxiosRequestConfig): Promise<T> {\n const response = await apiClient.get<T>(url, config)\n return response.data\n }\n\n async function post<T>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T> {\n const response = await apiClient.post<T>(url, data, config)\n return response.data\n }\n\n async function put<T>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T> {\n const response = await apiClient.put<T>(url, data, config)\n return response.data\n }\n\n async function patch<T>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T> {\n const response = await apiClient.patch<T>(url, data, config)\n return response.data\n }\n\n async function del<T>(url: string, config?: AxiosRequestConfig): Promise<T> {\n const response = await apiClient.delete<T>(url, config)\n return response.data\n }\n\n // File upload helper\n async function upload<T>(url: string, file: File, fieldName = 'file', additionalData?: Record<string, unknown>): Promise<T> {\n const formData = new FormData()\n formData.append(fieldName, file)\n\n if (additionalData) {\n Object.entries(additionalData).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n formData.append(key, typeof value === 'object' ? JSON.stringify(value) : String(value))\n }\n })\n }\n\n const response = await apiClient.post<T>(url, formData, {\n headers: { 'Content-Type': 'multipart/form-data' },\n })\n return response.data\n }\n\n // Download helper - returns blob URL\n async function download(url: string, filename?: string): Promise<string> {\n const response = await apiClient.get(url, { responseType: 'blob' })\n const blob = new Blob([response.data])\n const blobUrl = URL.createObjectURL(blob)\n\n // Optionally trigger download\n if (filename) {\n const link = document.createElement('a')\n link.href = blobUrl\n link.download = filename\n link.click()\n }\n\n return blobUrl\n }\n\n // Build full URL for external use (e.g., <a href=\"...\">)\n function buildUrl(path: string): string {\n const baseUrl = options.baseUrl ?? settingsStore.getApiBaseUrl()\n return `${baseUrl}${path}`\n }\n\n // WebSocket URL builder\n function buildWsUrl(path: string): string {\n return `${settingsStore.getWsBaseUrl()}${path}`\n }\n\n return {\n client: apiClient,\n get,\n post,\n put,\n patch,\n delete: del,\n upload,\n download,\n buildUrl,\n buildWsUrl,\n }\n}\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -40,6 +40,11 @@ export function useApi(options: ApiClientOptions = {}): UseApiReturn {
|
|
|
40
40
|
const authStore = useAuthStore()
|
|
41
41
|
const apiClient = getApiClient()
|
|
42
42
|
|
|
43
|
+
// Ensure auth store is initialized (reads token from localStorage)
|
|
44
|
+
if (!authStore.isInitialized) {
|
|
45
|
+
authStore.initialize()
|
|
46
|
+
}
|
|
47
|
+
|
|
43
48
|
// Attach interceptor only once
|
|
44
49
|
if (!interceptorAttached) {
|
|
45
50
|
apiClient.interceptors.request.use((config) => {
|