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
+148
View File
@@ -0,0 +1,148 @@
/**
* Collection-related type definitions for Mail Manager
*/
import type { SourceSelector } from './common';
/**
* Collection interface (mailbox/folder)
*/
export interface CollectionInterface {
provider: string;
service: string | number;
collection: string | number | null;
identifier: string | number;
signature?: string | null;
created?: string | null;
modified?: string | null;
properties: CollectionPropertiesInterface;
}
export interface CollectionBaseProperties {
'@type': string;
version: number;
}
/**
* Immutable collection properties (computed by server)
*/
export interface CollectionImmutableProperties extends CollectionBaseProperties {
total?: number;
unread?: number;
role?: string | null;
}
/**
* Mutable collection properties (can be modified by user)
*/
export interface CollectionMutableProperties extends CollectionBaseProperties {
label: string;
rank?: number;
subscribed?: boolean;
}
/**
* Full collection properties (what server returns)
*/
export interface CollectionPropertiesInterface extends CollectionMutableProperties, CollectionImmutableProperties {}
/**
* Collection list request
*/
export interface CollectionListRequest {
sources?: SourceSelector;
filter?: any;
sort?: any;
}
/**
* Collection list response
*/
export interface CollectionListResponse {
[providerId: string]: {
[serviceId: string]: {
[collectionId: string]: CollectionInterface;
};
};
}
/**
* Collection extant request
*/
export interface CollectionExtantRequest {
sources: SourceSelector;
}
/**
* Collection extant response
*/
export interface CollectionExtantResponse {
[providerId: string]: {
[serviceId: string]: {
[collectionId: string]: boolean;
};
};
}
/**
* Collection fetch request
*/
export interface CollectionFetchRequest {
provider: string;
service: string | number;
collection: string | number;
}
/**
* Collection fetch response
*/
export interface CollectionFetchResponse extends CollectionInterface {}
/**
* Collection create request
*/
export interface CollectionCreateRequest {
provider: string;
service: string | number;
collection?: string | number | null; // Parent Collection Identifier
properties: CollectionMutableProperties;
}
/**
* Collection create response
*/
export interface CollectionCreateResponse extends CollectionInterface {}
/**
* Collection modify request
*/
export interface CollectionModifyRequest {
provider: string;
service: string | number;
identifier: string | number;
properties: CollectionMutableProperties;
}
/**
* Collection modify response
*/
export interface CollectionModifyResponse extends CollectionInterface {}
/**
* Collection destroy request
*/
export interface CollectionDestroyRequest {
provider: string;
service: string | number;
identifier: string | number;
options?: {
force?: boolean; // Whether to force destroy even if collection is not empty
recursive?: boolean; // Whether to destroy child collections/items as well
};
}
/**
* Collection destroy response
*/
export interface CollectionDestroyResponse {
success: boolean;
}
+93
View File
@@ -0,0 +1,93 @@
/**
* Common types shared across Mail Manager services
*/
/**
* Base API request envelope
*/
export interface ApiRequest<T = any> {
version: number;
transaction: string;
operation: string;
data: T;
user?: string;
}
/**
* Success response envelope
*/
export interface ApiSuccessResponse<T = any> {
version: number;
transaction: string;
operation: string;
status: 'success';
data: T;
}
/**
* Error response envelope
*/
export interface ApiErrorResponse {
version: number;
transaction: string;
operation: string;
status: 'error';
data: {
code: number;
message: string;
};
}
/**
* Combined response type
*/
export type ApiResponse<T = any> = ApiSuccessResponse<T> | ApiErrorResponse;
/**
* Source selector structure for hierarchical resource selection
* Structure: Provider -> Service -> Collection -> Message
*/
export type SourceSelector = {
[provider: string]: boolean | ServiceSelector;
};
export type ServiceSelector = {
[service: string]: boolean | CollectionSelector;
};
export type CollectionSelector = {
[collection: string | number]: boolean | MessageSelector;
};
export type MessageSelector = (string | number)[];
/**
* Filter condition for building complex queries
*/
export interface FilterCondition {
field: string;
operator: string;
value: any;
}
/**
* Filter criteria for list operations
*/
export interface ListFilter {
[key: string]: any;
}
/**
* Sort options for list operations
*/
export interface ListSort {
[key: string]: boolean;
}
/**
* Range specification for pagination/limiting results
*/
export interface ListRange {
start: number;
limit: number;
}
+190
View File
@@ -0,0 +1,190 @@
/**
* Entity type definitions for mail
*/
import type { SourceSelector } from './common';
import type { MessageInterface } from './message';
/**
* Entity wrapper with metadata
*/
export interface EntityInterface<T = MessageInterface> {
provider: string;
service: string;
collection: string | number;
identifier: string | number;
signature: string | null;
created: string | null;
modified: string | null;
properties: T;
}
/**
* Entity list request
*/
export interface EntityListRequest {
sources?: SourceSelector;
filter?: any;
sort?: any;
range?: { start: number; limit: number };
}
/**
* Entity list response
*/
export interface EntityListResponse {
[providerId: string]: {
[serviceId: string]: {
[collectionId: string]: {
[identifier: string]: EntityInterface<MessageInterface>;
};
};
};
}
/**
* Entity delta request
*/
export interface EntityDeltaRequest {
sources: SourceSelector;
}
/**
* Entity delta response
*/
export interface EntityDeltaResponse {
[providerId: string]: {
[serviceId: string]: {
[collectionId: string]: {
signature: string;
created?: EntityInterface<MessageInterface>[];
modified?: EntityInterface<MessageInterface>[];
deleted?: string[];
};
};
};
}
/**
* Entity extant request
*/
export interface EntityExtantRequest {
sources: SourceSelector;
}
/**
* Entity extant response
*/
export interface EntityExtantResponse {
[providerId: string]: {
[serviceId: string]: {
[collectionId: string]: {
[messageId: string]: boolean;
};
};
};
}
/**
* Entity fetch request
*/
export interface EntityFetchRequest {
provider: string;
service: string | number;
collection: string | number;
identifiers: (string | number)[];
properties?: string[];
}
/**
* Entity fetch response
*/
export interface EntityFetchResponse {
entities: EntityInterface<MessageInterface>[];
}
/**
* Entity create request
*/
export interface EntityCreateRequest<T = MessageInterface> {
provider: string;
service: string | number;
collection: string | number;
properties: T;
}
/**
* Entity create response
*/
export interface EntityCreateResponse<T = MessageInterface> {
entity: EntityInterface<T>;
}
/**
* Entity modify request
*/
export interface EntityModifyRequest<T = MessageInterface> {
provider: string;
service: string | number;
collection: string | number;
identifier: string | number;
properties: T;
}
/**
* Entity modify response
*/
export interface EntityModifyResponse<T = MessageInterface> {
success: boolean;
entity?: EntityInterface<T>;
}
/**
* Entity destroy request
*/
export interface EntityDestroyRequest {
provider: string;
service: string | number;
collection: string | number;
identifier: string | number;
}
/**
* Entity destroy response
*/
export interface EntityDestroyResponse {
success: boolean;
}
/**
* Entity send request
*/
export interface EntitySendRequest {
message: {
from?: string;
to: string[];
cc?: string[];
bcc?: string[];
subject?: string;
body?: {
text?: string;
html?: string;
};
attachments?: Array<{
filename: string;
contentType: string;
content: string; // base64 encoded
}>;
};
options?: {
queue?: boolean;
priority?: number;
};
}
/**
* Entity send response
*/
export interface EntitySendResponse {
id: string;
status: 'queued' | 'sent';
}
+10
View File
@@ -0,0 +1,10 @@
/**
* Central export point for all Mail Manager types
*/
export type * from './collection';
export type * from './common';
export type * from './entity';
export type * from './integration';
export type * from './provider';
export type * from './service';
+58
View File
@@ -0,0 +1,58 @@
/**
* Integration and panel contract type definitions
* Defines standardized interfaces for provider panels
*/
// ==================== Provider Panel Contracts ====================
/**
* Props all provider CONFIG panels receive
* Config panels handle protocol/location settings only
*/
export interface ProviderConfigPanelProps {
/** Pre-filled location from discovery (if available) */
discoveredLocation?: import('./service').ServiceLocation;
/** Current location value for v-model binding */
modelValue?: import('./service').ServiceLocation;
}
/**
* Events all provider CONFIG panels emit
* Config panels emit location configuration and validation state
*/
export interface ProviderConfigPanelEmits {
/** Emit updated location configuration */
'update:modelValue': [value: import('./service').ServiceLocation];
/** Emit validation state (true = valid, false = invalid) */
'valid': [value: boolean];
}
/**
* Props all provider AUTH panels receive
* Auth panels handle credentials/authentication only
*/
export interface ProviderAuthPanelProps {
/** Email address from discovery entry (for pre-filling username) */
emailAddress?: string;
/** Discovered or configured location (for context/auth decisions) */
discoveredLocation?: import('./service').ServiceLocation;
/** Pre-filled identity/username from discovery */
prefilledIdentity?: string;
/** Pre-filled secret/password if user entered during discovery */
prefilledSecret?: string;
/** Current identity value for v-model binding */
modelValue?: import('./service').ServiceIdentity;
}
/**
* Events all provider AUTH panels emit
* Auth panels emit identity configuration, validation state, and errors
*/
export interface ProviderAuthPanelEmits {
/** Emit updated identity configuration */
'update:modelValue': [value: import('./service').ServiceIdentity];
/** Emit validation state (true = valid, false = invalid) */
'valid': [value: boolean];
/** Emit authentication errors for user feedback */
'error': [error: string];
}
+68
View File
@@ -0,0 +1,68 @@
/**
* Message Part Interface
*/
export interface MessagePartInterface {
partId?: string | null;
blobId?: string | null;
size?: number | null;
name?: string | null;
type?: string;
charset?: string | null;
disposition?: string | null;
cid?: string | null;
language?: string | null;
location?: string | null;
content?: string;
subParts?: MessagePartInterface[];
}
/**
* Message object interface
*/
export interface MessageInterface {
urid?: string;
size?: number;
receivedDate?: string;
date?: string;
subject?: string;
snippet?: string;
from?: {
address: string;
label?: string;
};
to?: Array<{
address: string;
label?: string;
}>;
cc?: Array<{
address: string;
label?: string;
}>;
bcc?: Array<{
address: string;
label?: string;
}>;
replyTo?: Array<{
address: string;
label?: string;
}>;
flags?: {
read?: boolean;
flagged?: boolean;
answered?: boolean;
draft?: boolean;
};
body?: MessagePartInterface;
attachments?: Array<{
partId?: string;
blobId?: string;
size?: number;
name?: string;
type?: string;
charset?: string | null;
disposition?: string;
cid?: string | null;
language?: string | null;
location?: string | null;
}>;
}
+69
View File
@@ -0,0 +1,69 @@
/**
* Provider type definitions
*/
import type { SourceSelector } from "./common";
/**
* Provider capabilities
*/
export interface ProviderCapabilitiesInterface {
ServiceList?: boolean;
ServiceFetch?: boolean;
ServiceExtant?: boolean;
ServiceCreate?: boolean;
ServiceModify?: boolean;
ServiceDestroy?: boolean;
ServiceDiscover?: boolean;
ServiceTest?: boolean;
[key: string]: boolean | object | string[] | undefined;
}
/**
* Provider information
*/
export interface ProviderInterface {
'@type': string;
identifier: string;
label: string;
capabilities: ProviderCapabilitiesInterface;
}
/**
* Provider list request
*/
export interface ProviderListRequest {
sources?: SourceSelector;
}
/**
* Provider list response
*/
export interface ProviderListResponse {
[identifier: string]: ProviderInterface;
}
/**
* Provider fetch request
*/
export interface ProviderFetchRequest {
identifier: string;
}
/**
* Provider fetch response
*/
export interface ProviderFetchResponse extends ProviderInterface {}
/**
* Provider extant request
*/
export interface ProviderExtantRequest {
sources: SourceSelector;
}
/**
* Provider extant response
*/
export interface ProviderExtantResponse {
[identifier: string]: boolean;
}
+344
View File
@@ -0,0 +1,344 @@
/**
* Service-related type definitions
*/
import type { SourceSelector } from './common';
/**
* Service capabilities
*/
export interface ServiceCapabilitiesInterface {
// Collection capabilities
CollectionList?: boolean;
CollectionListFilter?: boolean | { [field: string]: string };
CollectionListSort?: boolean | string[];
CollectionExtant?: boolean;
CollectionFetch?: boolean;
CollectionCreate?: boolean;
CollectionModify?: boolean;
CollectionDelete?: boolean;
// Message capabilities
EntityList?: boolean;
EntityListFilter?: boolean | { [field: string]: string };
EntityListSort?: boolean | string[];
EntityListRange?: boolean | { tally?: string[] };
EntityDelta?: boolean;
EntityExtant?: boolean;
EntityFetch?: boolean;
EntityCreate?: boolean;
EntityModify?: boolean;
EntityDelete?: boolean;
EntityMove?: boolean;
EntityCopy?: boolean;
// Send capability
EntityTransmit?: boolean;
[key: string]: boolean | object | string[] | undefined;
}
/**
* Service information
*/
export interface ServiceInterface {
'@type': string;
provider: string;
identifier: string | number | null;
label: string | null;
enabled: boolean;
capabilities?: ServiceCapabilitiesInterface;
location?: ServiceLocation | null;
identity?: ServiceIdentity | null;
primaryAddress?: string | null;
secondaryAddresses?: string[] | null;
auxiliary?: Record<string, any>; // Provider-specific extension data
}
/**
* Service list request
*/
export interface ServiceListRequest {
sources?: SourceSelector;
}
/**
* Service list response
*/
export interface ServiceListResponse {
[provider: string]: {
[identifier: string]: ServiceInterface;
};
}
/**
* Service extant request
*/
export interface ServiceExtantRequest {
sources: SourceSelector;
}
/**
* Service extant response
*/
export interface ServiceExtantResponse {
[provider: string]: {
[identifier: string]: boolean;
};
}
/**
* Service fetch request
*/
export interface ServiceFetchRequest {
provider: string;
identifier: string | number;
}
/**
* Service fetch response
*/
export interface ServiceFetchResponse extends ServiceInterface {}
/**
* Service find by address request
*/
export interface ServiceFindByAddressRequest {
address: string;
}
/**
* Service find by address response
*/
export interface ServiceFindByAddressResponse extends ServiceInterface {}
/**
* Service create request
*/
export interface ServiceCreateRequest {
provider: string;
data: Partial<ServiceInterface>;
}
/**
* Service create response
*/
export interface ServiceCreateResponse extends ServiceInterface {}
/**
* Service update request
*/
export interface ServiceUpdateRequest {
provider: string;
identifier: string | number;
data: Partial<ServiceInterface>;
}
/**
* Service update response
*/
export interface ServiceUpdateResponse extends ServiceInterface {}
/**
* Service delete request
*/
export interface ServiceDeleteRequest {
provider: string;
identifier: string | number;
}
/**
* Service delete response
*/
export interface ServiceDeleteResponse {}
// ==================== Discovery Types ====================
/**
* Service discovery request - NEW VERSION
* Supports identity-based discovery with optional hints
*/
export interface ServiceDiscoverRequest {
identity: string; // Email address or domain
provider?: string; // Optional: specific provider ('jmap', 'smtp', etc.) or null for all
location?: string; // Optional: known hostname (bypasses DNS lookup)
secret?: string; // Optional: password/token for credential validation
}
/**
* Service discovery response - NEW VERSION
* Provider-keyed map of discovered service locations
*/
export interface ServiceDiscoverResponse {
[provider: string]: ServiceLocation; // Uses existing ServiceLocation discriminated union
}
/**
* Discovery status tracking for real-time UI updates
* Used by store to track per-provider discovery progress
*/
export interface ProviderDiscoveryStatus {
provider: string;
status: 'pending' | 'discovering' | 'success' | 'failed';
location?: ServiceLocation;
error?: string;
metadata?: {
host?: string;
port?: number;
protocol?: string;
};
}
// ==================== Service Testing Types ====================
/**
* Base service location interface
*/
export interface ServiceLocationBase {
type: 'URI' | 'SOCKET_SOLE' | 'SOCKET_SPLIT' | 'FILE';
}
/**
* URI-based service location for API and web services
* Used by: JMAP, Gmail API, etc.
*/
export interface ServiceLocationUri extends ServiceLocationBase {
type: 'URI';
scheme: string; // e.g., 'https', 'http'
host: string; // e.g., 'api.example.com'
port: number; // e.g., 443
path?: string; // e.g., '/v1/api'
verifyPeer?: boolean; // Verify SSL/TLS peer certificate
verifyHost?: boolean; // Verify SSL/TLS certificate host
}
/**
* Single socket-based service location
* Used by: services using a single host/port combination
*/
export interface ServiceLocationSocketSole extends ServiceLocationBase {
type: 'SOCKET_SOLE';
host: string; // e.g., 'mail.example.com'
port: number; // e.g., 993
encryption: 'none' | 'ssl' | 'tls' | 'starttls'; // Security mode
verifyPeer?: boolean; // Verify SSL/TLS peer certificate
verifyHost?: boolean; // Verify SSL/TLS certificate host
}
/**
* Split socket-based service location
* Used by: traditional IMAP/SMTP configurations
*/
export interface ServiceLocationSocketSplit extends ServiceLocationBase {
type: 'SOCKET_SPLIT';
inboundHost: string; // e.g., 'imap.example.com'
inboundPort: number; // e.g., 993
inboundEncryption: 'none' | 'ssl' | 'tls' | 'starttls'; // Inbound security mode
inboundVerifyPeer?: boolean; // Verify inbound SSL/TLS peer certificate
inboundVerifyHost?: boolean; // Verify inbound SSL/TLS certificate host
outboundHost: string; // e.g., 'smtp.example.com'
outboundPort: number; // e.g., 465
outboundEncryption: 'none' | 'ssl' | 'tls' | 'starttls'; // Outbound security mode
outboundVerifyPeer?: boolean; // Verify outbound SSL/TLS peer certificate
outboundVerifyHost?: boolean; // Verify outbound SSL/TLS certificate host
}
/**
* File-based service location
* Used by: local file system providers
*/
export interface ServiceLocationFile extends ServiceLocationBase {
type: 'FILE';
path: string; // File system path
}
/**
* Discriminated union of all service location types
*/
export type ServiceLocation =
| ServiceLocationUri
| ServiceLocationSocketSole
| ServiceLocationSocketSplit
| ServiceLocationFile;
// ==================== Service Identity Types ====================
/**
* Base service identity interface
*/
export interface ServiceIdentityBase {
type: 'NA' | 'BA' | 'TA' | 'OA' | 'CC';
}
/**
* No authentication
*/
export interface ServiceIdentityNone extends ServiceIdentityBase {
type: 'NA';
}
/**
* Basic authentication (username/password)
*/
export interface ServiceIdentityBasic extends ServiceIdentityBase {
type: 'BA';
identity: string; // Username/email
secret: string; // Password
}
/**
* Token authentication (API key, static token)
*/
export interface ServiceIdentityToken extends ServiceIdentityBase {
type: 'TA';
token: string; // Authentication token/API key
}
/**
* OAuth authentication
*/
export interface ServiceIdentityOAuth extends ServiceIdentityBase {
type: 'OA';
accessToken: string; // Current access token
accessScope?: string[]; // Token scopes
accessExpiry?: number; // Unix timestamp when token expires
refreshToken?: string; // Refresh token for getting new access tokens
refreshLocation?: string; // Token refresh endpoint URL
}
/**
* Client certificate authentication (mTLS)
*/
export interface ServiceIdentityCertificate extends ServiceIdentityBase {
type: 'CC';
certificate: string; // X.509 certificate (PEM format or file path)
privateKey: string; // Private key (PEM format or file path)
passphrase?: string; // Optional passphrase for encrypted private key
}
/**
* Service identity configuration
* Discriminated union of all identity types
*/
export type ServiceIdentity =
| ServiceIdentityNone
| ServiceIdentityBasic
| ServiceIdentityToken
| ServiceIdentityOAuth
| ServiceIdentityCertificate;
/**
* Service connection test request
*/
export interface ServiceTestRequest {
provider: string;
// For existing service
identifier?: string | number | null;
// For fresh configuration
location?: ServiceLocation | null;
identity?: ServiceIdentity | null;
}
/**
* Service connection test response
*/
export interface ServiceTestResponse {
success: boolean;
message: string;
}