Initial commit

This commit is contained in:
root
2025-12-21 09:55:58 -05:00
committed by Sebastian Krupinski
commit 169b7b4c91
57 changed files with 10105 additions and 0 deletions
+209
View File
@@ -0,0 +1,209 @@
/**
* Services Store
*/
import { ref, computed, readonly } from 'vue'
import { defineStore } from 'pinia'
import { serviceService } from '../services'
import { ServiceObject } from '../models/service'
import type {
ServiceLocation,
SourceSelector,
ServiceIdentity,
} from '../types'
export const useServicesStore = defineStore('mailServicesStore', () => {
// State
const _services = ref<Record<string, ServiceObject>>({})
const transceiving = ref(false)
const lastTestResult = ref<any>(null)
// Getters
const count = computed(() => Object.keys(_services.value).length)
const has = computed(() => count.value > 0)
/**
* Get services as an array
* @returns Array of service objects
*/
const services = computed(() => Object.values(_services.value))
/**
* Get services grouped by provider
* @returns Services grouped by provider ID
*/
const servicesByProvider = computed(() => {
const groups: Record<string, ServiceObject[]> = {}
Object.values(_services.value).forEach((service) => {
if (!groups[service.provider]) {
groups[service.provider] = []
}
groups[service.provider].push(service)
})
return groups
})
// Actions
/**
* Retrieve for all or specific services
*/
async function list(sources?: SourceSelector): Promise<Record<string, ServiceObject>> {
transceiving.value = true
try {
const response = await serviceService.list({ sources })
// Flatten nested structure: provider-id: { service-id: object } -> "provider-id:service-id": object
const flattened: Record<string, ServiceObject> = {}
Object.entries(response).forEach(([_providerId, providerServices]) => {
Object.entries(providerServices).forEach(([_serviceId, serviceObj]) => {
const key = `${serviceObj.provider}:${serviceObj.identifier}`
flattened[key] = serviceObj
})
})
console.debug('[Mail Manager](Store) - Successfully retrieved', Object.keys(flattened).length, 'services')
_services.value = flattened
return flattened
} catch (error: any) {
console.error('[Mail Manager](Store) - Failed to retrieve services:', error)
throw error
} finally {
transceiving.value = false
}
}
/**
* Fetch a specific service
*/
async function fetch(provider: string, identifier: string | number): Promise<ServiceObject> {
transceiving.value = true
try {
return await serviceService.fetch({ provider, identifier })
} catch (error: any) {
console.error('[Mail Manager](Store) - Failed to fetch service:', error)
throw error
} finally {
transceiving.value = false
}
}
/**
* Discover service configuration
*
* @returns Array of discovered services sorted by provider
*/
async function discover(
identity: string,
secret: string | undefined,
location: string | undefined,
provider: string | undefined,
): Promise<ServiceObject[]> {
transceiving.value = true
try {
const services = await serviceService.discover({identity, secret, location, provider})
console.debug('[Mail Manager](Store) - Successfully discovered', services.length, 'services')
return services
} catch (error: any) {
console.error('[Mail Manager](Store) - Failed to discover service:', error)
throw error
} finally {
transceiving.value = false
}
}
async function test(
provider: string,
identifier?: string | number | null,
location?: ServiceLocation | null,
identity?: ServiceIdentity | null,
): Promise<any> {
transceiving.value = true
try {
const response = await serviceService.test({ provider, identifier, location, identity })
lastTestResult.value = response
return response
} catch (error: any) {
console.error('[Mail Manager](Store) - Failed to test service:', error)
throw error
} finally {
transceiving.value = false
}
}
async function create(provider: string, data: any) {
transceiving.value = true
try {
const serviceObj = await serviceService.create({ provider, data })
// Add to store with composite key
const key = `${serviceObj.provider}:${serviceObj.identifier}`
_services.value[key] = serviceObj
return serviceObj
} catch (error: any) {
console.error('[Mail Manager](Store) - Failed to create service:', error)
throw error
} finally {
transceiving.value = false
}
}
async function update(provider: string, identifier: string | number, data: any) {
transceiving.value = true
try {
const serviceObj = await serviceService.update({ provider, identifier, data })
// Update in store with composite key
const key = `${serviceObj.provider}:${serviceObj.identifier}`
_services.value[key] = serviceObj
return serviceObj
} catch (error: any) {
console.error('[Mail Manager](Store) - Failed to update service:', error)
throw error
} finally {
transceiving.value = false
}
}
async function remove(provider: string, identifier: string | number) {
transceiving.value = true
try {
await serviceService.delete({ provider, identifier })
// Remove from store using composite key
const key = `${provider}:${identifier}`
delete _services.value[key]
} catch (error: any) {
console.error('[Mail Manager](Store) - Failed to delete service:', error)
throw error
} finally {
transceiving.value = false
}
}
// Return public API
return {
// State (readonly)
transceiving: readonly(transceiving),
lastTestResult: readonly(lastTestResult),
// Getters
count,
has,
services,
servicesByProvider,
// Actions
list,
fetch,
discover,
test,
create,
update,
delete: remove,
}
})