This commit is contained in:
wayneshn
2025-07-27 18:34:28 +00:00
commit 30756ae5d1
55 changed files with 493 additions and 0 deletions

0
.nojekyll Normal file
View File

22
404.html Normal file
View File

@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en-US" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>404 | OpenArchiver Documentation</title>
<meta name="description" content="Not Found">
<meta name="generator" content="VitePress v1.6.3">
<link rel="preload stylesheet" href="/assets/style.L7-rAhYi.css" as="style">
<link rel="preload stylesheet" href="/vp-icons.css" as="style">
<script type="module" src="/assets/app.DguYn8Bw.js"></script>
<link rel="preload" href="/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
<script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
</head>
<body>
<div id="app"></div>
<script>window.__VP_HASH_MAP__=JSON.parse("{\"api_ingestion.md\":\"Cw9WcUAp\",\"api_readme.md\":\"_7P6rt6y\",\"readme.md\":\"CQnN0r3v\",\"services_readme.md\":\"DmYG8_uu\",\"services_storage-service.md\":\"xOqM9CWx\",\"summary.md\":\"DhPY8nsG\",\"user-guides_email-providers_google-workspace.md\":\"CWhO43nR\",\"user-guides_email-providers_imap.md\":\"BcXBEq43\",\"user-guides_email-providers_microsoft-365.md\":\"C4O8w9wT\",\"user-guides_email-providers_readme.md\":\"yQn5kDaG\",\"user-guides_installation.md\":\"Gno3X95r\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"OpenArchiver Documentation\",\"description\":\"Official documentation for the OpenArchiver project.\",\"base\":\"/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"nav\":[{\"text\":\"Home\",\"link\":\"/README\"},{\"text\":\"User Guides\",\"link\":\"/user-guides/email-providers/README\"}],\"sidebar\":[{\"text\":\"User Guides\",\"items\":[{\"text\":\"Get Started\",\"link\":\"/README\"},{\"text\":\"Installation\",\"link\":\"/user-guides/installation\"},{\"text\":\"Email Providers\",\"link\":\"/user-guides/email-providers/README\",\"collapsed\":true,\"items\":[{\"text\":\"Google Workspace\",\"link\":\"/user-guides/email-providers/google-workspace\"},{\"text\":\"Generic IMAP Server\",\"link\":\"/user-guides/email-providers/imap\"},{\"text\":\"Microsoft 365\",\"link\":\"/user-guides/email-providers/microsoft-365\"}]}]},{\"text\":\"API Reference\",\"items\":[{\"text\":\"Overview\",\"link\":\"/api/README\"},{\"text\":\"Ingestion API\",\"link\":\"/api/ingestion\"}]},{\"text\":\"Services\",\"items\":[{\"text\":\"Overview\",\"link\":\"/services/README\"},{\"text\":\"Storage Service\",\"link\":\"/services/storage-service\"}]}]},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":false}");</script>
</body>
</html>

25
README.html Normal file

File diff suppressed because one or more lines are too long

25
SUMMARY.html Normal file

File diff suppressed because one or more lines are too long

25
api/README.html Normal file

File diff suppressed because one or more lines are too long

56
api/ingestion.html Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
import{_ as o,c as t,o as a,ae as i}from"./chunks/framework.Cd-3tpCq.js";const h=JSON.parse('{"title":"Get Started","description":"","frontmatter":{},"headers":[],"relativePath":"README.md","filePath":"README.md"}'),r={name:"README.md"};function n(s,e,l,c,u,d){return a(),t("div",null,e[0]||(e[0]=[i('<h1 id="get-started" tabindex="-1">Get Started <a class="header-anchor" href="#get-started" aria-label="Permalink to &quot;Get Started&quot;"></a></h1><p>Welcome to Open Archiver! This guide will help you get started with setting up and using the platform.</p><h2 id="what-is-open-archiver" tabindex="-1">What is Open Archiver? <a class="header-anchor" href="#what-is-open-archiver" aria-label="Permalink to &quot;What is Open Archiver?&quot;"></a></h2><p><strong>A secure, sovereign, and affordable open-source platform for email archiving and eDiscovery.</strong></p><p>Open Archiver provides a robust, self-hosted solution for archiving, storing, indexing, and searching emails from major platforms, including Google Workspace (Gmail), Microsoft 365, as well as generic IMAP-enabled email inboxes. Use Open Archiver to keep a permanent, tamper-proof record of your communication history, free from vendor lock-in.</p><h2 id="key-features" tabindex="-1">Key Features <a class="header-anchor" href="#key-features" aria-label="Permalink to &quot;Key Features&quot;"></a></h2><ul><li><strong>Universal Ingestion</strong>: Connect to Google Workspace, Microsoft 365, and standard IMAP servers to perform initial bulk imports and maintain continuous, real-time synchronization.</li><li><strong>Secure &amp; Efficient Storage</strong>: Emails are stored in the standard <code>.eml</code> format. The system uses deduplication and compression to minimize storage costs. All data is encrypted at rest.</li><li><strong>Pluggable Storage Backends</strong>: Support both local filesystem storage and S3-compatible object storage (like AWS S3 or MinIO).</li><li><strong>Powerful Search &amp; eDiscovery</strong>: A high-performance search engine indexes the full text of emails and attachments (PDF, DOCX, etc.).</li><li><strong>Compliance &amp; Retention</strong>: Define granular retention policies to automatically manage the lifecycle of your data. Place legal holds on communications to prevent deletion during litigation (TBD).</li><li><strong>Comprehensive Auditing</strong>: An immutable audit trail logs all system activities, ensuring you have a clear record of who accessed what and when (TBD).</li></ul><h2 id="installation" tabindex="-1">Installation <a class="header-anchor" href="#installation" aria-label="Permalink to &quot;Installation&quot;"></a></h2><p>To get your own instance of Open Archiver running, follow our detailed installation guide:</p><ul><li><a href="./user-guides/installation.html">Installation Guide</a></li></ul><h2 id="data-source-configuration" tabindex="-1">Data Source Configuration <a class="header-anchor" href="#data-source-configuration" aria-label="Permalink to &quot;Data Source Configuration&quot;"></a></h2><p>After deploying the application, you will need to configure one or more ingestion sources to begin archiving emails. Follow our detailed guides to connect to your email provider:</p><ul><li><a href="./user-guides/email-providers/google-workspace.html">Connecting to Google Workspace</a></li><li><a href="./user-guides/email-providers/microsoft-365.html">Connecting to Microsoft 365</a></li><li><a href="./user-guides/email-providers/imap.html">Connecting to a Generic IMAP Server</a></li></ul><h2 id="contributing" tabindex="-1">Contributing <a class="header-anchor" href="#contributing" aria-label="Permalink to &quot;Contributing&quot;"></a></h2><p>We welcome contributions from the community!</p><ul><li><strong>Reporting Bugs</strong>: If you find a bug, please open an issue on our GitHub repository.</li><li><strong>Suggesting Enhancements</strong>: Have an idea for a new feature? We&#39;d love to hear it. Open an issue to start the discussion.</li><li><strong>Code Contributions</strong>: If you&#39;d like to contribute code, please fork the repository and submit a pull request.</li></ul><p>Please read our <code>CONTRIBUTING.md</code> file for more details on our code of conduct and the process for submitting pull requests.</p>',17)]))}const p=o(r,[["render",n]]);export{h as __pageData,p as default};

View File

@@ -0,0 +1 @@
import{_ as o,c as t,o as a,ae as i}from"./chunks/framework.Cd-3tpCq.js";const h=JSON.parse('{"title":"Get Started","description":"","frontmatter":{},"headers":[],"relativePath":"README.md","filePath":"README.md"}'),r={name:"README.md"};function n(s,e,l,c,u,d){return a(),t("div",null,e[0]||(e[0]=[i("",17)]))}const p=o(r,[["render",n]]);export{h as __pageData,p as default};

View File

@@ -0,0 +1 @@
import{_ as a,c as i,o as t,ae as r}from"./chunks/framework.Cd-3tpCq.js";const m=JSON.parse('{"title":"Table of contents","description":"","frontmatter":{},"headers":[],"relativePath":"SUMMARY.md","filePath":"SUMMARY.md"}'),l={name:"SUMMARY.md"};function o(s,e,n,c,u,h){return t(),i("div",null,e[0]||(e[0]=[r('<h1 id="table-of-contents" tabindex="-1">Table of contents <a class="header-anchor" href="#table-of-contents" aria-label="Permalink to &quot;Table of contents&quot;"></a></h1><h2 id="user-guides" tabindex="-1">User guides <a class="header-anchor" href="#user-guides" aria-label="Permalink to &quot;User guides&quot;"></a></h2><ul><li><a href="./README.html">Get started</a></li><li><a href="./user-guides/installation.html">Installation</a></li><li><a href="./user-guides/email-providers/README.html">email-providers</a><ul><li><a href="./user-guides/email-providers/google-workspace.html">Connecting to Google Workspace</a></li><li><a href="./user-guides/email-providers/imap.html">Connecting to a Generic IMAP Server</a></li><li><a href="./user-guides/email-providers/microsoft-365.html">Connecting to Microsoft 365</a></li></ul></li></ul><hr><ul><li><a href="./api/README.html">api</a><ul><li><a href="./api/ingestion.html">Ingestion Sources API Documentation</a></li></ul></li><li><a href="./services/README.html">services</a><ul><li><a href="./services/storage-service.html">Pluggable Storage Service (StorageService)</a></li></ul></li></ul>',5)]))}const f=a(l,[["render",o]]);export{m as __pageData,f as default};

View File

@@ -0,0 +1 @@
import{_ as a,c as i,o as t,ae as r}from"./chunks/framework.Cd-3tpCq.js";const m=JSON.parse('{"title":"Table of contents","description":"","frontmatter":{},"headers":[],"relativePath":"SUMMARY.md","filePath":"SUMMARY.md"}'),l={name:"SUMMARY.md"};function o(s,e,n,c,u,h){return t(),i("div",null,e[0]||(e[0]=[r("",5)]))}const f=a(l,[["render",o]]);export{m as __pageData,f as default};

View File

@@ -0,0 +1 @@
import{_ as t,c as o,o as n,j as e,a as r}from"./chunks/framework.Cd-3tpCq.js";const f=JSON.parse('{"title":"API documentation","description":"","frontmatter":{},"headers":[],"relativePath":"api/README.md","filePath":"api/README.md"}'),i={name:"api/README.md"};function s(c,a,d,p,m,l){return n(),o("div",null,a[0]||(a[0]=[e("h1",{id:"api-documentation",tabindex:"-1"},[r("API documentation "),e("a",{class:"header-anchor",href:"#api-documentation","aria-label":'Permalink to "API documentation"'},"")],-1)]))}const E=t(i,[["render",s]]);export{f as __pageData,E as default};

View File

@@ -0,0 +1 @@
import{_ as t,c as o,o as n,j as e,a as r}from"./chunks/framework.Cd-3tpCq.js";const f=JSON.parse('{"title":"API documentation","description":"","frontmatter":{},"headers":[],"relativePath":"api/README.md","filePath":"api/README.md"}'),i={name:"api/README.md"};function s(c,a,d,p,m,l){return n(),o("div",null,a[0]||(a[0]=[e("h1",{id:"api-documentation",tabindex:"-1"},[r("API documentation "),e("a",{class:"header-anchor",href:"#api-documentation","aria-label":'Permalink to "API documentation"'},"")],-1)]))}const E=t(i,[["render",s]]);export{f as __pageData,E as default};

View File

@@ -0,0 +1,32 @@
import{_ as e,c as i,o as a,ae as t}from"./chunks/framework.Cd-3tpCq.js";const u=JSON.parse('{"title":"Ingestion Sources API Documentation","description":"","frontmatter":{},"headers":[],"relativePath":"api/ingestion.md","filePath":"api/ingestion.md"}'),n={name:"api/ingestion.md"};function o(r,s,l,h,d,p){return a(),i("div",null,s[0]||(s[0]=[t(`<h1 id="ingestion-sources-api-documentation" tabindex="-1">Ingestion Sources API Documentation <a class="header-anchor" href="#ingestion-sources-api-documentation" aria-label="Permalink to &quot;Ingestion Sources API Documentation&quot;"></a></h1><p>A guide to using the Ingestion Sources API.</p><p><strong>Base Path:</strong> <code>/v1/ingestion-sources</code></p><hr><h2 id="authentication" tabindex="-1">Authentication <a class="header-anchor" href="#authentication" aria-label="Permalink to &quot;Authentication&quot;"></a></h2><p>All endpoints in this API are protected and require authentication. Requests must include an <code>Authorization</code> header containing a valid Bearer token. This can be a JWT obtained from the login endpoint or a <code>SUPER_API_KEY</code> for administrative tasks.</p><p><strong>Header Example:</strong><code>Authorization: Bearer &lt;YOUR_JWT_OR_SUPER_API_KEY&gt;</code></p><hr><h2 id="core-concepts" tabindex="-1">Core Concepts <a class="header-anchor" href="#core-concepts" aria-label="Permalink to &quot;Core Concepts&quot;"></a></h2><h3 id="ingestion-providers" tabindex="-1">Ingestion Providers <a class="header-anchor" href="#ingestion-providers" aria-label="Permalink to &quot;Ingestion Providers&quot;"></a></h3><p>The <code>provider</code> field determines the type of email source. Each provider requires a different configuration object, for example:</p><ul><li><code>google_workspace</code>: For connecting to Google Workspace accounts via OAuth 2.0.</li><li><code>microsoft_365</code>: For connecting to Microsoft 365 accounts via OAuth 2.0.</li><li><code>generic_imap</code>: For connecting to any email server that supports IMAP.</li></ul><h3 id="ingestion-status" tabindex="-1">Ingestion Status <a class="header-anchor" href="#ingestion-status" aria-label="Permalink to &quot;Ingestion Status&quot;"></a></h3><p>The <code>status</code> field tracks the state of the ingestion source.</p><ul><li><code>pending_auth</code>: The source has been created but requires user authorization (OAuth flow).</li><li><code>active</code>: The source is authenticated and ready to sync.</li><li><code>syncing</code>: An import job is currently in progress.</li><li><code>importing</code>: initial syncing in progress</li><li><code>paused</code>: The source is temporarily disabled.</li><li><code>error</code>: An error occurred during the last sync.</li></ul><hr><h2 id="_1-create-ingestion-source" tabindex="-1">1. Create Ingestion Source <a class="header-anchor" href="#_1-create-ingestion-source" aria-label="Permalink to &quot;1. Create Ingestion Source&quot;"></a></h2><ul><li><strong>Method:</strong> <code>POST</code></li><li><strong>Path:</strong> <code>/</code></li><li><strong>Description:</strong> Registers a new source for email ingestion. The <code>providerConfig</code> will vary based on the selected <code>provider</code>.</li></ul><h4 id="request-body-createingestionsourcedto" tabindex="-1">Request Body (<code>CreateIngestionSourceDto</code>) <a class="header-anchor" href="#request-body-createingestionsourcedto" aria-label="Permalink to &quot;Request Body (\`CreateIngestionSourceDto\`)&quot;"></a></h4><ul><li><code>name</code> (string, required): A user-friendly name for the source (e.g., &quot;Marketing Department G-Suite&quot;).</li><li><code>provider</code> (string, required): One of <code>google_workspace</code>, <code>microsoft_365</code>, or <code>generic_imap</code>.</li><li><code>providerConfig</code> (object, required): Configuration specific to the provider.</li></ul><h5 id="providerconfig-for-google-workspace-microsoft-365" tabindex="-1"><code>providerConfig</code> for <code>google_workspace</code> / <code>microsoft_365</code> <a class="header-anchor" href="#providerconfig-for-google-workspace-microsoft-365" aria-label="Permalink to &quot;\`providerConfig\` for \`google_workspace\` / \`microsoft_365\`&quot;"></a></h5><div class="language-json vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;name&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;Corporate Google Workspace&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;provider&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;google_workspace&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;providerConfig&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: {</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;clientId&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;your-oauth-client-id.apps.googleusercontent.com&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;clientSecret&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;your-super-secret-client-secret&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;redirectUri&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;https://yourapp.com/oauth/google/callback&quot;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h5 id="providerconfig-for-generic-imap" tabindex="-1"><code>providerConfig</code> for <code>generic_imap</code> <a class="header-anchor" href="#providerconfig-for-generic-imap" aria-label="Permalink to &quot;\`providerConfig\` for \`generic_imap\`&quot;"></a></h5><div class="language-json vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;name&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;Legacy IMAP Server&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;provider&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;generic_imap&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;providerConfig&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: {</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;host&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;imap.example.com&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;port&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">993</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;secure&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;username&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;archive-user&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;password&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;imap-password&quot;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h4 id="responses" tabindex="-1">Responses <a class="header-anchor" href="#responses" aria-label="Permalink to &quot;Responses&quot;"></a></h4><ul><li><p><strong>Success (<code>201 Created</code>):</strong> Returns the full <code>IngestionSource</code> object, which now includes a system-generated <code>id</code> and default status.</p><div class="language-json vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;id&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;a1b2c3d4-e5f6-7890-1234-567890abcdef&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;name&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;Corporate Google Workspace&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;provider&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;google_workspace&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;status&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;pending_auth&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;createdAt&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;2025-07-11T12:00:00.000Z&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;updatedAt&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;2025-07-11T12:00:00.000Z&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;providerConfig&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: { </span><span style="--shiki-light:#B31D28;--shiki-light-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div></li><li><p><strong>Error (<code>500 Internal Server Error</code>):</strong> Indicates a server-side problem during creation.</p></li></ul><hr><h2 id="_2-get-all-ingestion-sources" tabindex="-1">2. Get All Ingestion Sources <a class="header-anchor" href="#_2-get-all-ingestion-sources" aria-label="Permalink to &quot;2. Get All Ingestion Sources&quot;"></a></h2><ul><li><strong>Method:</strong> <code>GET</code></li><li><strong>Path:</strong> <code>/</code></li><li><strong>Description:</strong> Retrieves a list of all configured ingestion sources for the organization.</li></ul><h4 id="responses-1" tabindex="-1">Responses <a class="header-anchor" href="#responses-1" aria-label="Permalink to &quot;Responses&quot;"></a></h4><ul><li><p><strong>Success (<code>200 OK</code>):</strong> Returns an array of <code>IngestionSource</code> objects.</p></li><li><p><strong>Error (<code>500 Internal Server Error</code>):</strong> Indicates a server-side problem.</p></li></ul><hr><h2 id="_3-get-ingestion-source-by-id" tabindex="-1">3. Get Ingestion Source by ID <a class="header-anchor" href="#_3-get-ingestion-source-by-id" aria-label="Permalink to &quot;3. Get Ingestion Source by ID&quot;"></a></h2><ul><li><strong>Method:</strong> <code>GET</code></li><li><strong>Path:</strong> <code>/:id</code></li><li><strong>Description:</strong> Fetches the details of a specific ingestion source.</li></ul><h4 id="url-parameters" tabindex="-1">URL Parameters <a class="header-anchor" href="#url-parameters" aria-label="Permalink to &quot;URL Parameters&quot;"></a></h4><ul><li><code>id</code> (string, required): The UUID of the ingestion source.</li></ul><h4 id="responses-2" tabindex="-1">Responses <a class="header-anchor" href="#responses-2" aria-label="Permalink to &quot;Responses&quot;"></a></h4><ul><li><p><strong>Success (<code>200 OK</code>):</strong> Returns the corresponding <code>IngestionSource</code> object.</p></li><li><p><strong>Error (<code>404 Not Found</code>):</strong> Returned if no source with the given ID exists.</p></li><li><p><strong>Error (<code>500 Internal Server Error</code>):</strong> Indicates a server-side problem.</p></li></ul><hr><h2 id="_4-update-ingestion-source" tabindex="-1">4. Update Ingestion Source <a class="header-anchor" href="#_4-update-ingestion-source" aria-label="Permalink to &quot;4. Update Ingestion Source&quot;"></a></h2><ul><li><strong>Method:</strong> <code>PUT</code></li><li><strong>Path:</strong> <code>/:id</code></li><li><strong>Description:</strong> Modifies an existing ingestion source. This is useful for changing the name, pausing a source, or updating its configuration.</li></ul><h4 id="url-parameters-1" tabindex="-1">URL Parameters <a class="header-anchor" href="#url-parameters-1" aria-label="Permalink to &quot;URL Parameters&quot;"></a></h4><ul><li><code>id</code> (string, required): The UUID of the ingestion source to update.</li></ul><h4 id="request-body-updateingestionsourcedto" tabindex="-1">Request Body (<code>UpdateIngestionSourceDto</code>) <a class="header-anchor" href="#request-body-updateingestionsourcedto" aria-label="Permalink to &quot;Request Body (\`UpdateIngestionSourceDto\`)&quot;"></a></h4><p>All fields are optional. Only include the fields you want to change.</p><div class="language-json vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;name&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;Marketing Dept G-Suite (Paused)&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;status&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;paused&quot;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h4 id="responses-3" tabindex="-1">Responses <a class="header-anchor" href="#responses-3" aria-label="Permalink to &quot;Responses&quot;"></a></h4><ul><li><p><strong>Success (<code>200 OK</code>):</strong> Returns the complete, updated <code>IngestionSource</code> object.</p></li><li><p><strong>Error (<code>404 Not Found</code>):</strong> Returned if no source with the given ID exists.</p></li><li><p><strong>Error (<code>500 Internal Server Error</code>):</strong> Indicates a server-side problem.</p></li></ul><hr><h2 id="_5-delete-ingestion-source" tabindex="-1">5. Delete Ingestion Source <a class="header-anchor" href="#_5-delete-ingestion-source" aria-label="Permalink to &quot;5. Delete Ingestion Source&quot;"></a></h2><ul><li><strong>Method:</strong> <code>DELETE</code></li><li><strong>Path:</strong> <code>/:id</code></li><li><strong>Description:</strong> Permanently removes an ingestion source. This action cannot be undone.</li></ul><h4 id="url-parameters-2" tabindex="-1">URL Parameters <a class="header-anchor" href="#url-parameters-2" aria-label="Permalink to &quot;URL Parameters&quot;"></a></h4><ul><li><code>id</code> (string, required): The UUID of the ingestion source to delete.</li></ul><h4 id="responses-4" tabindex="-1">Responses <a class="header-anchor" href="#responses-4" aria-label="Permalink to &quot;Responses&quot;"></a></h4><ul><li><p><strong>Success (<code>204 No Content</code>):</strong> Indicates successful deletion with no body content.</p></li><li><p><strong>Error (<code>404 Not Found</code>):</strong> Returned if no source with the given ID exists.</p></li><li><p><strong>Error (<code>500 Internal Server Error</code>):</strong> Indicates a server-side problem.</p></li></ul><hr><h2 id="_6-trigger-initial-import" tabindex="-1">6. Trigger Initial Import <a class="header-anchor" href="#_6-trigger-initial-import" aria-label="Permalink to &quot;6. Trigger Initial Import&quot;"></a></h2><ul><li><strong>Method:</strong> <code>POST</code></li><li><strong>Path:</strong> <code>/:id/sync</code></li><li><strong>Description:</strong> Initiates the email import process for a given source. This is an asynchronous operation that enqueues a background job and immediately returns a response. The status of the source will be updated to <code>importing</code>.</li></ul><h4 id="url-parameters-3" tabindex="-1">URL Parameters <a class="header-anchor" href="#url-parameters-3" aria-label="Permalink to &quot;URL Parameters&quot;"></a></h4><ul><li><code>id</code> (string, required): The UUID of the ingestion source to sync.</li></ul><h4 id="responses-5" tabindex="-1">Responses <a class="header-anchor" href="#responses-5" aria-label="Permalink to &quot;Responses&quot;"></a></h4><ul><li><p><strong>Success (<code>202 Accepted</code>):</strong> Confirms that the sync request has been accepted for processing.</p><div class="language-json vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;message&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;Initial import triggered successfully.&quot;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div></li><li><p><strong>Error (<code>404 Not Found</code>):</strong> Returned if no source with the given ID exists.</p></li><li><p><strong>Error (<code>500 Internal Server Error</code>):</strong> Indicates a server-side problem.</p></li></ul>`,62)]))}const g=e(n,[["render",o]]);export{u as __pageData,g as default};

View File

@@ -0,0 +1 @@
import{_ as e,c as i,o as a,ae as t}from"./chunks/framework.Cd-3tpCq.js";const u=JSON.parse('{"title":"Ingestion Sources API Documentation","description":"","frontmatter":{},"headers":[],"relativePath":"api/ingestion.md","filePath":"api/ingestion.md"}'),n={name:"api/ingestion.md"};function o(r,s,l,h,d,p){return a(),i("div",null,s[0]||(s[0]=[t("",62)]))}const g=e(n,[["render",o]]);export{u as __pageData,g as default};

1
assets/app.DguYn8Bw.js Normal file
View File

@@ -0,0 +1 @@
import{t as p}from"./chunks/theme.D5-fWCd8.js";import{R as s,a0 as i,a1 as u,a2 as c,a3 as l,a4 as f,a5 as d,a6 as m,a7 as h,a8 as g,a9 as A,d as v,u as y,v as C,s as P,aa as b,ab as w,ac as R,ad as E}from"./chunks/framework.Cd-3tpCq.js";function r(e){if(e.extends){const a=r(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const n=r(p),S=v({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=y();return C(()=>{P(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&b(),w(),R(),n.setup&&n.setup(),()=>E(n.Layout)}});async function T(){globalThis.__VITEPRESS__=!0;const e=_(),a=D();a.provide(u,e);const t=c(e.route);return a.provide(l,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),n.enhanceApp&&await n.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function D(){return A(S)}function _(){let e=s;return h(a=>{let t=g(a),o=null;return t&&(e&&(t=t.replace(/\.js$/,".lean.js")),o=import(t)),s&&(e=!1),o},n.NotFound)}s&&T().then(({app:e,router:a,data:t})=>{a.go().then(()=>{i(a.route,t.site),e.mount("#app")})});export{T as createApp};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
import{_ as a,c as r,o as t,j as s,a as c}from"./chunks/framework.Cd-3tpCq.js";const f=JSON.parse('{"title":"services","description":"","frontmatter":{},"headers":[],"relativePath":"services/README.md","filePath":"services/README.md"}'),i={name:"services/README.md"};function o(n,e,d,l,p,m){return t(),r("div",null,e[0]||(e[0]=[s("h1",{id:"services",tabindex:"-1"},[c("services "),s("a",{class:"header-anchor",href:"#services","aria-label":'Permalink to "services"'},"")],-1)]))}const E=a(i,[["render",o]]);export{f as __pageData,E as default};

View File

@@ -0,0 +1 @@
import{_ as a,c as r,o as t,j as s,a as c}from"./chunks/framework.Cd-3tpCq.js";const f=JSON.parse('{"title":"services","description":"","frontmatter":{},"headers":[],"relativePath":"services/README.md","filePath":"services/README.md"}'),i={name:"services/README.md"};function o(n,e,d,l,p,m){return t(),r("div",null,e[0]||(e[0]=[s("h1",{id:"services",tabindex:"-1"},[c("services "),s("a",{class:"header-anchor",href:"#services","aria-label":'Permalink to "services"'},"")],-1)]))}const E=a(i,[["render",o]]);export{f as __pageData,E as default};

View File

@@ -0,0 +1,38 @@
import{_ as s,c as i,o as a,ae as t}from"./chunks/framework.Cd-3tpCq.js";const k=JSON.parse('{"title":"Pluggable Storage Service (StorageService)","description":"","frontmatter":{},"headers":[],"relativePath":"services/storage-service.md","filePath":"services/storage-service.md"}'),n={name:"services/storage-service.md"};function l(r,e,o,h,p,c){return a(),i("div",null,e[0]||(e[0]=[t(`<h1 id="pluggable-storage-service-storageservice" tabindex="-1">Pluggable Storage Service (<code>StorageService</code>) <a class="header-anchor" href="#pluggable-storage-service-storageservice" aria-label="Permalink to &quot;Pluggable Storage Service (\`StorageService\`)&quot;"></a></h1><h2 id="overview" tabindex="-1">Overview <a class="header-anchor" href="#overview" aria-label="Permalink to &quot;Overview&quot;"></a></h2><p>The <code>StorageService</code> provides a unified, abstract interface for handling file storage across different backends. Its primary purpose is to decouple the application&#39;s core logic from the underlying storage technology. This design allows administrators to switch between storage providers (e.g., from the local filesystem to an S3-compatible object store) with only a configuration change, requiring no modifications to the application code.</p><p>The service is built around a standardized <code>IStorageProvider</code> interface, which guarantees that all storage providers have a consistent API for common operations like storing, retrieving, and deleting files.</p><h2 id="configuration" tabindex="-1">Configuration <a class="header-anchor" href="#configuration" aria-label="Permalink to &quot;Configuration&quot;"></a></h2><p>The <code>StorageService</code> is configured via environment variables in the <code>.env</code> file. You must specify the storage backend you wish to use and provide the necessary credentials and settings for it.</p><h3 id="_1-choosing-the-backend" tabindex="-1">1. Choosing the Backend <a class="header-anchor" href="#_1-choosing-the-backend" aria-label="Permalink to &quot;1. Choosing the Backend&quot;"></a></h3><p>The <code>STORAGE_TYPE</code> variable determines which provider the service will use.</p><ul><li><code>STORAGE_TYPE=local</code>: Uses the local server&#39;s filesystem.</li><li><code>STORAGE_TYPE=s3</code>: Uses an S3-compatible object storage service (e.g., AWS S3, MinIO, Google Cloud Storage).</li></ul><h3 id="_2-local-filesystem-configuration" tabindex="-1">2. Local Filesystem Configuration <a class="header-anchor" href="#_2-local-filesystem-configuration" aria-label="Permalink to &quot;2. Local Filesystem Configuration&quot;"></a></h3><p>When <code>STORAGE_TYPE</code> is set to <code>local</code>, you must also provide the root path where files will be stored.</p><div class="language-env vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">env</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span># .env</span></span>
<span class="line"><span>STORAGE_TYPE=local</span></span>
<span class="line"><span>STORAGE_LOCAL_ROOT_PATH=/var/data/open-archiver</span></span></code></pre></div><ul><li><code>STORAGE_LOCAL_ROOT_PATH</code>: The absolute path on the server where the archive will be created. The service will create subdirectories within this path as needed.</li></ul><h3 id="_3-s3-compatible-storage-configuration" tabindex="-1">3. S3-Compatible Storage Configuration <a class="header-anchor" href="#_3-s3-compatible-storage-configuration" aria-label="Permalink to &quot;3. S3-Compatible Storage Configuration&quot;"></a></h3><p>When <code>STORAGE_TYPE</code> is set to <code>s3</code>, you must provide the credentials and endpoint for your object storage provider.</p><div class="language-env vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">env</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span># .env</span></span>
<span class="line"><span>STORAGE_TYPE=s3</span></span>
<span class="line"><span>STORAGE_S3_ENDPOINT=http://127.0.0.1:9000</span></span>
<span class="line"><span>STORAGE_S3_BUCKET=email-archive</span></span>
<span class="line"><span>STORAGE_S3_ACCESS_KEY_ID=minioadmin</span></span>
<span class="line"><span>STORAGE_S3_SECRET_ACCESS_KEY=minioadmin</span></span>
<span class="line"><span>STORAGE_S3_REGION=us-east-1</span></span>
<span class="line"><span>STORAGE_S3_FORCE_PATH_STYLE=true</span></span></code></pre></div><ul><li><code>STORAGE_S3_ENDPOINT</code>: The full URL of the S3 API endpoint.</li><li><code>STORAGE_S3_BUCKET</code>: The name of the bucket to use for storage.</li><li><code>STORAGE_S3_ACCESS_KEY_ID</code>: The access key for your S3 user.</li><li><code>STORAGE_S3_SECRET_ACCESS_KEY</code>: The secret key for your S3 user.</li><li><code>STORAGE_S3_REGION</code> (Optional): The AWS region of your bucket. Recommended for AWS S3.</li><li><code>STORAGE_S3_FORCE_PATH_STYLE</code> (Optional): Set to <code>true</code> when using non-AWS S3 services like MinIO.</li></ul><h2 id="how-to-use-the-service" tabindex="-1">How to Use the Service <a class="header-anchor" href="#how-to-use-the-service" aria-label="Permalink to &quot;How to Use the Service&quot;"></a></h2><p>The <code>StorageService</code> is designed to be used via dependency injection in other services. You should never instantiate the providers (<code>LocalFileSystemProvider</code> or <code>S3StorageProvider</code>) directly. Instead, create an instance of <code>StorageService</code> and the factory will provide the correct provider based on your <code>.env</code> configuration.</p><h3 id="example-usage-in-ingestionservice" tabindex="-1">Example: Usage in <code>IngestionService</code> <a class="header-anchor" href="#example-usage-in-ingestionservice" aria-label="Permalink to &quot;Example: Usage in \`IngestionService\`&quot;"></a></h3><div class="language-typescript vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">typescript</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { StorageService } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;./StorageService&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">class</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> IngestionService</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> private</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> storageService</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> StorageService</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> constructor</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // The StorageService is instantiated without any arguments.</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // It automatically reads the configuration from the environment.</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> this</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.storageService </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> StorageService</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> public</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> async</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> archiveEmail</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span></span>
<span class="line"><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> rawEmail</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Buffer</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> userId</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> messageId</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> string</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> )</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Promise</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">void</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt; {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Define a structured, unique path for the email.</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> archivePath</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> \`\${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">userId</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">}/messages/\${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">messageId</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">}.eml\`</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> try</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Use the service. It doesn&#39;t know or care if this is writing</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // to a local disk or an S3 bucket.</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> this</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.storageService.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">put</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(archivePath, rawEmail);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">\`Successfully archived email to \${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">archivePath</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">}\`</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">catch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (error) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">error</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">\`Failed to archive email \${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">messageId</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">}\`</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, error);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h2 id="api-reference" tabindex="-1">API Reference <a class="header-anchor" href="#api-reference" aria-label="Permalink to &quot;API Reference&quot;"></a></h2><p>The <code>StorageService</code> implements the <code>IStorageProvider</code> interface. All methods are asynchronous and return a <code>Promise</code>.</p><hr><h3 id="put-path-content" tabindex="-1"><code>put(path, content)</code> <a class="header-anchor" href="#put-path-content" aria-label="Permalink to &quot;\`put(path, content)\`&quot;"></a></h3><p>Stores a file at the specified path. If a file already exists at that path, it will be overwritten.</p><ul><li><strong><code>path: string</code></strong>: A unique identifier for the file, including its directory structure (e.g., <code>&quot;user-123/emails/message-abc.eml&quot;</code>).</li><li><strong><code>content: Buffer | NodeJS.ReadableStream</code></strong>: The content of the file. It can be a <code>Buffer</code> for small files or a <code>ReadableStream</code> for large files to ensure memory efficiency.</li><li><strong>Returns</strong>: <code>Promise&lt;void&gt;</code> - A promise that resolves when the file has been successfully stored.</li></ul><hr><h3 id="get-path" tabindex="-1"><code>get(path)</code> <a class="header-anchor" href="#get-path" aria-label="Permalink to &quot;\`get(path)\`&quot;"></a></h3><p>Retrieves a file from the specified path as a readable stream.</p><ul><li><strong><code>path: string</code></strong>: The unique identifier of the file to retrieve.</li><li><strong>Returns</strong>: <code>Promise&lt;NodeJS.ReadableStream&gt;</code> - A promise that resolves with a readable stream of the file&#39;s content.</li><li><strong>Throws</strong>: An <code>Error</code> if the file is not found at the specified path.</li></ul><hr><h3 id="delete-path" tabindex="-1"><code>delete(path)</code> <a class="header-anchor" href="#delete-path" aria-label="Permalink to &quot;\`delete(path)\`&quot;"></a></h3><p>Deletes a file from the storage backend.</p><ul><li><strong><code>path: string</code></strong>: The unique identifier of the file to delete.</li><li><strong>Returns</strong>: <code>Promise&lt;void&gt;</code> - A promise that resolves when the file is deleted. If the file does not exist, the promise will still resolve successfully without throwing an error.</li></ul><hr><h3 id="exists-path" tabindex="-1"><code>exists(path)</code> <a class="header-anchor" href="#exists-path" aria-label="Permalink to &quot;\`exists(path)\`&quot;"></a></h3><p>Checks for the existence of a file.</p><ul><li><strong><code>path: string</code></strong>: The unique identifier of the file to check.</li><li><strong>Returns</strong>: <code>Promise&lt;boolean&gt;</code> - A promise that resolves with <code>true</code> if the file exists, and <code>false</code> otherwise.</li></ul>`,39)]))}const g=s(n,[["render",l]]);export{k as __pageData,g as default};

View File

@@ -0,0 +1 @@
import{_ as s,c as i,o as a,ae as t}from"./chunks/framework.Cd-3tpCq.js";const k=JSON.parse('{"title":"Pluggable Storage Service (StorageService)","description":"","frontmatter":{},"headers":[],"relativePath":"services/storage-service.md","filePath":"services/storage-service.md"}'),n={name:"services/storage-service.md"};function l(r,e,o,h,p,c){return a(),i("div",null,e[0]||(e[0]=[t("",39)]))}const g=s(n,[["render",l]]);export{k as __pageData,g as default};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
import{_ as a,c as s,o as i,j as r,a as t}from"./chunks/framework.Cd-3tpCq.js";const v=JSON.parse('{"title":"email-providers","description":"","frontmatter":{},"headers":[],"relativePath":"user-guides/email-providers/README.md","filePath":"user-guides/email-providers/README.md"}'),o={name:"user-guides/email-providers/README.md"};function d(l,e,n,p,m,c){return i(),s("div",null,e[0]||(e[0]=[r("h1",{id:"email-providers",tabindex:"-1"},[t("email-providers "),r("a",{class:"header-anchor",href:"#email-providers","aria-label":'Permalink to "email-providers"'},"")],-1)]))}const f=a(o,[["render",d]]);export{v as __pageData,f as default};

View File

@@ -0,0 +1 @@
import{_ as a,c as s,o as i,j as r,a as t}from"./chunks/framework.Cd-3tpCq.js";const v=JSON.parse('{"title":"email-providers","description":"","frontmatter":{},"headers":[],"relativePath":"user-guides/email-providers/README.md","filePath":"user-guides/email-providers/README.md"}'),o={name:"user-guides/email-providers/README.md"};function d(l,e,n,p,m,c){return i(),s("div",null,e[0]||(e[0]=[r("h1",{id:"email-providers",tabindex:"-1"},[t("email-providers "),r("a",{class:"header-anchor",href:"#email-providers","aria-label":'Permalink to "email-providers"'},"")],-1)]))}const f=a(o,[["render",d]]);export{v as __pageData,f as default};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
import{_ as o,c as t,o as i,ae as r}from"./chunks/framework.Cd-3tpCq.js";const d=JSON.parse('{"title":"Connecting to Google Workspace","description":"","frontmatter":{},"headers":[],"relativePath":"user-guides/email-providers/google-workspace.md","filePath":"user-guides/email-providers/google-workspace.md"}'),n={name:"user-guides/email-providers/google-workspace.md"};function a(s,e,l,c,u,g){return i(),t("div",null,e[0]||(e[0]=[r("",29)]))}const p=o(n,[["render",a]]);export{d as __pageData,p as default};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
import{_ as e,c as t,o as r,ae as a}from"./chunks/framework.Cd-3tpCq.js";const g=JSON.parse('{"title":"Connecting to a Generic IMAP Server","description":"","frontmatter":{},"headers":[],"relativePath":"user-guides/email-providers/imap.md","filePath":"user-guides/email-providers/imap.md"}'),s={name:"user-guides/email-providers/imap.md"};function i(n,o,l,c,p,u){return r(),t("div",null,o[0]||(o[0]=[a("",16)]))}const h=e(s,[["render",i]]);export{g as __pageData,h as default};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
import{_ as e,c as i,o,ae as r}from"./chunks/framework.Cd-3tpCq.js";const u=JSON.parse('{"title":"Connecting to Microsoft 365","description":"","frontmatter":{},"headers":[],"relativePath":"user-guides/email-providers/microsoft-365.md","filePath":"user-guides/email-providers/microsoft-365.md"}'),n={name:"user-guides/email-providers/microsoft-365.md"};function s(a,t,l,c,h,p){return o(),i("div",null,t[0]||(t[0]=[r("",27)]))}const d=e(n,[["render",s]]);export{u as __pageData,d as default};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
import{_ as i,c as a,o as s,ae as t}from"./chunks/framework.Cd-3tpCq.js";const u=JSON.parse('{"title":"Installation Guide","description":"","frontmatter":{},"headers":[],"relativePath":"user-guides/installation.md","filePath":"user-guides/installation.md"}'),n={name:"user-guides/installation.md"};function o(l,e,r,h,p,c){return s(),a("div",null,e[0]||(e[0]=[t("",34)]))}const g=i(n,[["render",o]]);export{u as __pageData,g as default};

1
hashmap.json Normal file
View File

@@ -0,0 +1 @@
{"api_ingestion.md":"Cw9WcUAp","api_readme.md":"_7P6rt6y","readme.md":"CQnN0r3v","services_readme.md":"DmYG8_uu","services_storage-service.md":"xOqM9CWx","summary.md":"DhPY8nsG","user-guides_email-providers_google-workspace.md":"CWhO43nR","user-guides_email-providers_imap.md":"BcXBEq43","user-guides_email-providers_microsoft-365.md":"C4O8w9wT","user-guides_email-providers_readme.md":"yQn5kDaG","user-guides_installation.md":"Gno3X95r"}

25
services/README.html Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

0
vp-icons.css Normal file
View File