diff --git a/.env.example b/.env.example index e611f01..13e8f67 100644 --- a/.env.example +++ b/.env.example @@ -4,9 +4,6 @@ PORT_BACKEND=4000 PORT_FRONTEND=3000 # PostgreSQL -POSTGRES_DB=open_archive -POSTGRES_USER=admin -POSTGRES_PASSWORD=password DATABASE_URL="postgresql://admin:password@postgres:5432/open_archive?schema=public" # Redis @@ -25,4 +22,5 @@ JWT_EXPIRES_IN="7d" # Admin users ADMIN_EMAIL=admin@local.com -ADMIN_PASSWORD=a_strong_pass \ No newline at end of file +ADMIN_PASSWORD=a_strong_pass +SUPER_API_KEY= \ No newline at end of file diff --git a/.gitignore b/.gitignore index fda06f7..49cdfca 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,5 @@ pnpm-debug.log .DS_Store # Dev -.dev \ No newline at end of file +.dev +.clinerules \ No newline at end of file diff --git a/docs/api/ingestion.md b/docs/api/ingestion.md new file mode 100644 index 0000000..3236d45 --- /dev/null +++ b/docs/api/ingestion.md @@ -0,0 +1,205 @@ +# Ingestion Sources API Documentation + +A comprehensive guide to using the Ingestion Sources API. + +**Base Path:** `/v1/ingestion-sources` + +--- + +## Authentication + +All endpoints in this API are protected and require authentication. Requests must include an `Authorization` header containing a valid Bearer token. This can be a JWT obtained from the login endpoint or a `SUPER_API_KEY` for administrative tasks. + +**Header Example:** +`Authorization: Bearer ` + +--- + +## Core Concepts + +### Ingestion Providers + +The `provider` field determines the type of email source. Each provider requires a different configuration object, for example: + +- `google_workspace`: For connecting to Google Workspace accounts via OAuth 2.0. +- `microsoft_365`: For connecting to Microsoft 365 accounts via OAuth 2.0. +- `generic_imap`: For connecting to any email server that supports IMAP. + +### Ingestion Status + +The `status` field tracks the state of the ingestion source. + +- `pending_auth`: The source has been created but requires user authorization (OAuth flow). +- `active`: The source is authenticated and ready to sync. +- `syncing`: An import job is currently in progress. +- `paused`: The source is temporarily disabled. +- `error`: An error occurred during the last sync. + +--- + +## 1. Create Ingestion Source + +- **Method:** `POST` +- **Path:** `/` +- **Description:** Registers a new source for email ingestion. The `providerConfig` will vary based on the selected `provider`. + +#### Request Body (`CreateIngestionSourceDto`) + +- `name` (string, required): A user-friendly name for the source (e.g., "Marketing Department G-Suite"). +- `provider` (string, required): One of `google_workspace`, `microsoft_365`, or `generic_imap`. +- `providerConfig` (object, required): Configuration specific to the provider. + +##### `providerConfig` for `google_workspace` / `microsoft_365` + +```json +{ + "name": "Corporate Google Workspace", + "provider": "google_workspace", + "providerConfig": { + "clientId": "your-oauth-client-id.apps.googleusercontent.com", + "clientSecret": "your-super-secret-client-secret", + "redirectUri": "https://yourapp.com/oauth/google/callback" + } +} +``` + +##### `providerConfig` for `generic_imap` + +```json +{ + "name": "Legacy IMAP Server", + "provider": "generic_imap", + "providerConfig": { + "host": "imap.example.com", + "port": 993, + "secure": true, + "username": "archive-user", + "password": "imap-password" + } +} +``` + +#### Responses + +- **Success (`201 Created`):** Returns the full `IngestionSource` object, which now includes a system-generated `id` and default status. + + ```json + { + "id": "a1b2c3d4-e5f6-7890-1234-567890abcdef", + "name": "Corporate Google Workspace", + "provider": "google_workspace", + "status": "pending_auth", + "createdAt": "2025-07-11T12:00:00.000Z", + "updatedAt": "2025-07-11T12:00:00.000Z", + "providerConfig": { ... } + } + ``` + +- **Error (`500 Internal Server Error`):** Indicates a server-side problem during creation. + +--- + +## 2. Get All Ingestion Sources + +- **Method:** `GET` +- **Path:** `/` +- **Description:** Retrieves a list of all configured ingestion sources for the organization. + +#### Responses + +- **Success (`200 OK`):** Returns an array of `IngestionSource` objects. + +- **Error (`500 Internal Server Error`):** Indicates a server-side problem. + +--- + +## 3. Get Ingestion Source by ID + +- **Method:** `GET` +- **Path:** `/:id` +- **Description:** Fetches the details of a specific ingestion source. + +#### URL Parameters + +- `id` (string, required): The UUID of the ingestion source. + +#### Responses + +- **Success (`200 OK`):** Returns the corresponding `IngestionSource` object. + +- **Error (`404 Not Found`):** Returned if no source with the given ID exists. +- **Error (`500 Internal Server Error`):** Indicates a server-side problem. + +--- + +## 4. Update Ingestion Source + +- **Method:** `PUT` +- **Path:** `/:id` +- **Description:** Modifies an existing ingestion source. This is useful for changing the name, pausing a source, or updating its configuration. + +#### URL Parameters + +- `id` (string, required): The UUID of the ingestion source to update. + +#### Request Body (`UpdateIngestionSourceDto`) + +All fields are optional. Only include the fields you want to change. + +```json +{ + "name": "Marketing Dept G-Suite (Paused)", + "status": "paused" +} +``` + +#### Responses + +- **Success (`200 OK`):** Returns the complete, updated `IngestionSource` object. + +- **Error (`404 Not Found`):** Returned if no source with the given ID exists. +- **Error (`500 Internal Server Error`):** Indicates a server-side problem. + +--- + +## 5. Delete Ingestion Source + +- **Method:** `DELETE` +- **Path:** `/:id` +- **Description:** Permanently removes an ingestion source. This action cannot be undone. + +#### URL Parameters + +- `id` (string, required): The UUID of the ingestion source to delete. + +#### Responses + +- **Success (`204 No Content`):** Indicates successful deletion with no body content. + +- **Error (`404 Not Found`):** Returned if no source with the given ID exists. +- **Error (`500 Internal Server Error`):** Indicates a server-side problem. + +--- + +## 6. Trigger Initial Import + +- **Method:** `POST` +- **Path:** `/:id/sync` +- **Description:** 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 `syncing`. + +#### URL Parameters + +- `id` (string, required): The UUID of the ingestion source to sync. + +#### Responses + +- **Success (`202 Accepted`):** Confirms that the sync request has been accepted for processing. + + ```json + { + "message": "Initial import triggered successfully." + } + ``` + +- **Error (`404 Not Found`):** Returned if no source with the given ID exists. +- **Error (`500 Internal Server Error`):** Indicates a server-side problem. diff --git a/packages/backend/drizzle.config.ts b/packages/backend/drizzle.config.ts new file mode 100644 index 0000000..aefafb6 --- /dev/null +++ b/packages/backend/drizzle.config.ts @@ -0,0 +1,19 @@ +import { defineConfig } from 'drizzle-kit'; +import { config } from 'dotenv'; + +config({ path: '../../.env' }); + +if (!process.env.DATABASE_URL) { + throw new Error('DATABASE_URL is not set in the .env file'); +} + +export default defineConfig({ + schema: './src/database/schema.ts', + out: './src/database/migrations', + dialect: 'postgresql', + dbCredentials: { + url: process.env.DATABASE_URL, + }, + verbose: true, + strict: true, +}); diff --git a/packages/backend/package.json b/packages/backend/package.json index 4bda81e..8ee653b 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -7,16 +7,22 @@ "dev": "ts-node-dev --respawn --transpile-only src/index.ts ", "build": "tsc", "start": "node dist/index.js", - "start:worker": "ts-node-dev --respawn --transpile-only src/workers/ingestion.worker.ts" + "start:worker": "ts-node-dev --respawn --transpile-only src/workers/ingestion.worker.ts", + "db:generate": "drizzle-kit generate --config=drizzle.config.ts", + "db:push": "drizzle-kit push --config=drizzle.config.ts", + "db:migrate": "ts-node-dev src/database/migrate.ts" }, "dependencies": { "@open-archive/types": "workspace:*", "bcryptjs": "^3.0.2", "bullmq": "^5.56.3", "dotenv": "^17.2.0", + "drizzle-orm": "^0.44.2", "express": "^5.1.0", + "express-validator": "^7.2.1", "jose": "^6.0.11", "pg": "^8.16.3", + "postgres": "^3.4.7", "reflect-metadata": "^0.2.2", "sqlite3": "^5.1.7", "tsconfig-paths": "^4.2.0" @@ -24,6 +30,7 @@ "devDependencies": { "@types/express": "^5.0.3", "@types/node": "^24.0.12", + "drizzle-kit": "^0.31.4", "ts-node-dev": "^2.0.0", "typescript": "^5.8.3" } diff --git a/packages/backend/src/api/controllers/ingestion.controller.ts b/packages/backend/src/api/controllers/ingestion.controller.ts new file mode 100644 index 0000000..76ab792 --- /dev/null +++ b/packages/backend/src/api/controllers/ingestion.controller.ts @@ -0,0 +1,83 @@ +import { Request, Response } from 'express'; +import { IngestionService } from '../../services/IngestionService'; +import { CreateIngestionSourceDto, UpdateIngestionSourceDto } from '@open-archive/types'; + +export class IngestionController { + public create = async (req: Request, res: Response): Promise => { + try { + const dto: CreateIngestionSourceDto = req.body; + const newSource = await IngestionService.create(dto); + return res.status(201).json(newSource); + } catch (error) { + console.error('Create ingestion source error:', error); + return res.status(500).json({ message: 'An internal server error occurred' }); + } + }; + + public findAll = async (req: Request, res: Response): Promise => { + try { + const sources = await IngestionService.findAll(); + return res.status(200).json(sources); + } catch (error) { + console.error('Find all ingestion sources error:', error); + return res.status(500).json({ message: 'An internal server error occurred' }); + } + }; + + public findById = async (req: Request, res: Response): Promise => { + try { + const { id } = req.params; + const source = await IngestionService.findById(id); + return res.status(200).json(source); + } catch (error) { + console.error(`Find ingestion source by id ${req.params.id} error:`, error); + if (error instanceof Error && error.message === 'Ingestion source not found') { + return res.status(404).json({ message: error.message }); + } + return res.status(500).json({ message: 'An internal server error occurred' }); + } + }; + + public update = async (req: Request, res: Response): Promise => { + try { + const { id } = req.params; + const dto: UpdateIngestionSourceDto = req.body; + const updatedSource = await IngestionService.update(id, dto); + return res.status(200).json(updatedSource); + } catch (error) { + console.error(`Update ingestion source ${req.params.id} error:`, error); + if (error instanceof Error && error.message === 'Ingestion source not found') { + return res.status(404).json({ message: error.message }); + } + return res.status(500).json({ message: 'An internal server error occurred' }); + } + }; + + public delete = async (req: Request, res: Response): Promise => { + try { + const { id } = req.params; + await IngestionService.delete(id); + return res.status(204).send(); + } catch (error) { + console.error(`Delete ingestion source ${req.params.id} error:`, error); + if (error instanceof Error && error.message === 'Ingestion source not found') { + return res.status(404).json({ message: error.message }); + } + return res.status(500).json({ message: 'An internal server error occurred' }); + } + }; + + public triggerInitialImport = async (req: Request, res: Response): Promise => { + try { + const { id } = req.params; + await IngestionService.triggerInitialImport(id); + return res.status(202).json({ message: 'Initial import triggered successfully.' }); + } catch (error) { + console.error(`Trigger initial import for ${req.params.id} error:`, error); + if (error instanceof Error && error.message === 'Ingestion source not found') { + return res.status(404).json({ message: error.message }); + } + return res.status(500).json({ message: 'An internal server error occurred' }); + } + }; +} diff --git a/packages/backend/src/api/middleware/requireAuth.ts b/packages/backend/src/api/middleware/requireAuth.ts index dfed3f5..bad2de4 100644 --- a/packages/backend/src/api/middleware/requireAuth.ts +++ b/packages/backend/src/api/middleware/requireAuth.ts @@ -1,7 +1,7 @@ import type { Request, Response, NextFunction } from 'express'; import type { IAuthService } from '../../services/AuthService'; import type { AuthTokenPayload } from '@open-archive/types'; - +import 'dotenv/config'; // By using module augmentation, we can add our custom 'user' property // to the Express Request interface in a type-safe way. declare global { @@ -15,20 +15,20 @@ declare global { export const requireAuth = (authService: IAuthService) => { return async (req: Request, res: Response, next: NextFunction) => { const authHeader = req.headers.authorization; - if (!authHeader || !authHeader.startsWith('Bearer ')) { return res.status(401).json({ message: 'Unauthorized: No token provided' }); } - const token = authHeader.split(' ')[1]; - try { + // use a SUPER_API_KEY for all authentications. + if (token === process.env.SUPER_API_KEY) { + next(); + return; + } const payload = await authService.verifyToken(token); - if (!payload) { return res.status(401).json({ message: 'Unauthorized: Invalid token' }); } - req.user = payload; next(); } catch (error) { diff --git a/packages/backend/src/api/routes/ingestion.routes.ts b/packages/backend/src/api/routes/ingestion.routes.ts new file mode 100644 index 0000000..00be3be --- /dev/null +++ b/packages/backend/src/api/routes/ingestion.routes.ts @@ -0,0 +1,28 @@ +import { Router } from 'express'; +import { IngestionController } from '../controllers/ingestion.controller'; +import { requireAuth } from '../middleware/requireAuth'; +import { IAuthService } from '../../services/AuthService'; + +export const createIngestionRouter = ( + ingestionController: IngestionController, + authService: IAuthService +): Router => { + const router = Router(); + + // Secure all routes in this module + router.use(requireAuth(authService)); + + router.post('/', ingestionController.create); + + router.get('/', ingestionController.findAll); + + router.get('/:id', ingestionController.findById); + + router.put('/:id', ingestionController.update); + + router.delete('/:id', ingestionController.delete); + + router.post('/:id/sync', ingestionController.triggerInitialImport); + + return router; +}; diff --git a/packages/backend/src/database/index.ts b/packages/backend/src/database/index.ts new file mode 100644 index 0000000..aaa0b50 --- /dev/null +++ b/packages/backend/src/database/index.ts @@ -0,0 +1,12 @@ +import { drizzle } from 'drizzle-orm/postgres-js'; +import postgres from 'postgres'; +import 'dotenv/config'; + +import * as schema from './schema'; + +if (!process.env.DATABASE_URL) { + throw new Error('DATABASE_URL is not set in the .env file'); +} + +const client = postgres(process.env.DATABASE_URL); +export const db = drizzle(client, { schema }); diff --git a/packages/backend/src/database/migrate.ts b/packages/backend/src/database/migrate.ts new file mode 100644 index 0000000..a3a9ae2 --- /dev/null +++ b/packages/backend/src/database/migrate.ts @@ -0,0 +1,27 @@ +import { migrate } from 'drizzle-orm/postgres-js/migrator'; +import { drizzle } from 'drizzle-orm/postgres-js'; +import postgres from 'postgres'; +import { config } from 'dotenv'; + +config({ path: '../../.env' }); + +const runMigrate = async () => { + if (!process.env.DATABASE_URL) { + throw new Error('DATABASE_URL is not set in the .env file'); + } + + const connection = postgres(process.env.DATABASE_URL, { max: 1 }); + const db = drizzle(connection); + + console.log('Running migrations...'); + + await migrate(db, { migrationsFolder: 'src/database/migrations' }); + + console.log('Migrations completed!'); + process.exit(0); +}; + +runMigrate().catch((err) => { + console.error('Migration failed!', err); + process.exit(1); +}); diff --git a/packages/backend/src/database/migrations/0000_amusing_namora.sql b/packages/backend/src/database/migrations/0000_amusing_namora.sql new file mode 100644 index 0000000..f24fede --- /dev/null +++ b/packages/backend/src/database/migrations/0000_amusing_namora.sql @@ -0,0 +1,125 @@ +CREATE TYPE "public"."retention_action" AS ENUM('delete_permanently', 'notify_admin');--> statement-breakpoint +CREATE TYPE "public"."ingestion_provider" AS ENUM('google_workspace', 'microsoft_365', 'generic_imap');--> statement-breakpoint +CREATE TYPE "public"."ingestion_status" AS ENUM('active', 'paused', 'error', 'pending_auth', 'syncing');--> statement-breakpoint +CREATE TABLE "archived_emails" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "custodian_id" uuid NOT NULL, + "message_id_header" text NOT NULL, + "sent_at" timestamp with time zone NOT NULL, + "subject" text, + "sender_name" text, + "sender_email" text NOT NULL, + "recipients" jsonb, + "storage_path" text NOT NULL, + "storage_hash_sha256" text NOT NULL, + "size_bytes" bigint NOT NULL, + "is_indexed" boolean DEFAULT false NOT NULL, + "has_attachments" boolean DEFAULT false NOT NULL, + "is_on_legal_hold" boolean DEFAULT false NOT NULL, + "archived_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "attachments" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "filename" text NOT NULL, + "mime_type" text, + "size_bytes" bigint NOT NULL, + "content_hash_sha256" text NOT NULL, + "storage_path" text NOT NULL, + CONSTRAINT "attachments_content_hash_sha256_unique" UNIQUE("content_hash_sha256") +); +--> statement-breakpoint +CREATE TABLE "email_attachments" ( + "email_id" uuid NOT NULL, + "attachment_id" uuid NOT NULL, + CONSTRAINT "email_attachments_email_id_attachment_id_pk" PRIMARY KEY("email_id","attachment_id") +); +--> statement-breakpoint +CREATE TABLE "audit_logs" ( + "id" bigserial PRIMARY KEY NOT NULL, + "timestamp" timestamp with time zone DEFAULT now() NOT NULL, + "actor_identifier" text NOT NULL, + "action" text NOT NULL, + "target_type" text, + "target_id" text, + "details" jsonb, + "is_tamper_evident" boolean DEFAULT false +); +--> statement-breakpoint +CREATE TABLE "ediscovery_cases" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "name" text NOT NULL, + "description" text, + "status" text DEFAULT 'open' NOT NULL, + "created_by_identifier" text NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT "ediscovery_cases_name_unique" UNIQUE("name") +); +--> statement-breakpoint +CREATE TABLE "export_jobs" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "case_id" uuid, + "format" text NOT NULL, + "status" text DEFAULT 'pending' NOT NULL, + "query" jsonb NOT NULL, + "file_path" text, + "created_by_identifier" text NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "completed_at" timestamp with time zone +); +--> statement-breakpoint +CREATE TABLE "legal_holds" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "case_id" uuid NOT NULL, + "custodian_id" uuid, + "hold_criteria" jsonb, + "reason" text, + "applied_by_identifier" text NOT NULL, + "applied_at" timestamp with time zone DEFAULT now() NOT NULL, + "removed_at" timestamp with time zone +); +--> statement-breakpoint +CREATE TABLE "retention_policies" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "name" text NOT NULL, + "description" text, + "priority" integer NOT NULL, + "retention_period_days" integer NOT NULL, + "action_on_expiry" "retention_action" NOT NULL, + "is_enabled" boolean DEFAULT true NOT NULL, + "conditions" jsonb, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT "retention_policies_name_unique" UNIQUE("name") +); +--> statement-breakpoint +CREATE TABLE "custodians" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "email" text NOT NULL, + "display_name" text, + "source_type" "ingestion_provider" NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT "custodians_email_unique" UNIQUE("email") +); +--> statement-breakpoint +CREATE TABLE "ingestion_sources" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "name" text NOT NULL, + "provider" "ingestion_provider" NOT NULL, + "credentials" jsonb, + "status" "ingestion_status" DEFAULT 'pending_auth' NOT NULL, + "last_sync_started_at" timestamp with time zone, + "last_sync_finished_at" timestamp with time zone, + "last_sync_status_message" text, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +ALTER TABLE "archived_emails" ADD CONSTRAINT "archived_emails_custodian_id_custodians_id_fk" FOREIGN KEY ("custodian_id") REFERENCES "public"."custodians"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "email_attachments" ADD CONSTRAINT "email_attachments_email_id_archived_emails_id_fk" FOREIGN KEY ("email_id") REFERENCES "public"."archived_emails"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "email_attachments" ADD CONSTRAINT "email_attachments_attachment_id_attachments_id_fk" FOREIGN KEY ("attachment_id") REFERENCES "public"."attachments"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "export_jobs" ADD CONSTRAINT "export_jobs_case_id_ediscovery_cases_id_fk" FOREIGN KEY ("case_id") REFERENCES "public"."ediscovery_cases"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "legal_holds" ADD CONSTRAINT "legal_holds_case_id_ediscovery_cases_id_fk" FOREIGN KEY ("case_id") REFERENCES "public"."ediscovery_cases"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "legal_holds" ADD CONSTRAINT "legal_holds_custodian_id_custodians_id_fk" FOREIGN KEY ("custodian_id") REFERENCES "public"."custodians"("id") ON DELETE cascade ON UPDATE no action; \ No newline at end of file diff --git a/packages/backend/src/database/migrations/meta/0000_snapshot.json b/packages/backend/src/database/migrations/meta/0000_snapshot.json new file mode 100644 index 0000000..596765e --- /dev/null +++ b/packages/backend/src/database/migrations/meta/0000_snapshot.json @@ -0,0 +1,818 @@ +{ + "id": "3fe238cc-60db-4ddb-8945-11db89bdee2b", + "prevId": "00000000-0000-0000-0000-000000000000", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.archived_emails": { + "name": "archived_emails", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "custodian_id": { + "name": "custodian_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "message_id_header": { + "name": "message_id_header", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "subject": { + "name": "subject", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sender_name": { + "name": "sender_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sender_email": { + "name": "sender_email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "recipients": { + "name": "recipients", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "storage_path": { + "name": "storage_path", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "storage_hash_sha256": { + "name": "storage_hash_sha256", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "size_bytes": { + "name": "size_bytes", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "is_indexed": { + "name": "is_indexed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "has_attachments": { + "name": "has_attachments", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_on_legal_hold": { + "name": "is_on_legal_hold", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "archived_at": { + "name": "archived_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "archived_emails_custodian_id_custodians_id_fk": { + "name": "archived_emails_custodian_id_custodians_id_fk", + "tableFrom": "archived_emails", + "tableTo": "custodians", + "columnsFrom": [ + "custodian_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.attachments": { + "name": "attachments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "filename": { + "name": "filename", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "mime_type": { + "name": "mime_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "size_bytes": { + "name": "size_bytes", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "content_hash_sha256": { + "name": "content_hash_sha256", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "storage_path": { + "name": "storage_path", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "attachments_content_hash_sha256_unique": { + "name": "attachments_content_hash_sha256_unique", + "nullsNotDistinct": false, + "columns": [ + "content_hash_sha256" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_attachments": { + "name": "email_attachments", + "schema": "", + "columns": { + "email_id": { + "name": "email_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "attachment_id": { + "name": "attachment_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "email_attachments_email_id_archived_emails_id_fk": { + "name": "email_attachments_email_id_archived_emails_id_fk", + "tableFrom": "email_attachments", + "tableTo": "archived_emails", + "columnsFrom": [ + "email_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "email_attachments_attachment_id_attachments_id_fk": { + "name": "email_attachments_attachment_id_attachments_id_fk", + "tableFrom": "email_attachments", + "tableTo": "attachments", + "columnsFrom": [ + "attachment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "email_attachments_email_id_attachment_id_pk": { + "name": "email_attachments_email_id_attachment_id_pk", + "columns": [ + "email_id", + "attachment_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audit_logs": { + "name": "audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "actor_identifier": { + "name": "actor_identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "target_id": { + "name": "target_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "details": { + "name": "details", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "is_tamper_evident": { + "name": "is_tamper_evident", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ediscovery_cases": { + "name": "ediscovery_cases", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'open'" + }, + "created_by_identifier": { + "name": "created_by_identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "ediscovery_cases_name_unique": { + "name": "ediscovery_cases_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.export_jobs": { + "name": "export_jobs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "case_id": { + "name": "case_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "format": { + "name": "format", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "query": { + "name": "query", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "file_path": { + "name": "file_path", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by_identifier": { + "name": "created_by_identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "export_jobs_case_id_ediscovery_cases_id_fk": { + "name": "export_jobs_case_id_ediscovery_cases_id_fk", + "tableFrom": "export_jobs", + "tableTo": "ediscovery_cases", + "columnsFrom": [ + "case_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.legal_holds": { + "name": "legal_holds", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "case_id": { + "name": "case_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "custodian_id": { + "name": "custodian_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "hold_criteria": { + "name": "hold_criteria", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "applied_by_identifier": { + "name": "applied_by_identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "applied_at": { + "name": "applied_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "removed_at": { + "name": "removed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "legal_holds_case_id_ediscovery_cases_id_fk": { + "name": "legal_holds_case_id_ediscovery_cases_id_fk", + "tableFrom": "legal_holds", + "tableTo": "ediscovery_cases", + "columnsFrom": [ + "case_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "legal_holds_custodian_id_custodians_id_fk": { + "name": "legal_holds_custodian_id_custodians_id_fk", + "tableFrom": "legal_holds", + "tableTo": "custodians", + "columnsFrom": [ + "custodian_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.retention_policies": { + "name": "retention_policies", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "priority": { + "name": "priority", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "retention_period_days": { + "name": "retention_period_days", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "action_on_expiry": { + "name": "action_on_expiry", + "type": "retention_action", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "is_enabled": { + "name": "is_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "conditions": { + "name": "conditions", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "retention_policies_name_unique": { + "name": "retention_policies_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.custodians": { + "name": "custodians", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source_type": { + "name": "source_type", + "type": "ingestion_provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "custodians_email_unique": { + "name": "custodians_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ingestion_sources": { + "name": "ingestion_sources", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "ingestion_provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "credentials": { + "name": "credentials", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "ingestion_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending_auth'" + }, + "last_sync_started_at": { + "name": "last_sync_started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_sync_finished_at": { + "name": "last_sync_finished_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_sync_status_message": { + "name": "last_sync_status_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.retention_action": { + "name": "retention_action", + "schema": "public", + "values": [ + "delete_permanently", + "notify_admin" + ] + }, + "public.ingestion_provider": { + "name": "ingestion_provider", + "schema": "public", + "values": [ + "google_workspace", + "microsoft_365", + "generic_imap" + ] + }, + "public.ingestion_status": { + "name": "ingestion_status", + "schema": "public", + "values": [ + "active", + "paused", + "error", + "pending_auth", + "syncing" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/packages/backend/src/database/migrations/meta/_journal.json b/packages/backend/src/database/migrations/meta/_journal.json new file mode 100644 index 0000000..5e317c9 --- /dev/null +++ b/packages/backend/src/database/migrations/meta/_journal.json @@ -0,0 +1,13 @@ +{ + "version": "7", + "dialect": "postgresql", + "entries": [ + { + "idx": 0, + "version": "7", + "when": 1752225352591, + "tag": "0000_amusing_namora", + "breakpoints": true + } + ] +} \ No newline at end of file diff --git a/packages/backend/src/database/schema.ts b/packages/backend/src/database/schema.ts new file mode 100644 index 0000000..571a02b --- /dev/null +++ b/packages/backend/src/database/schema.ts @@ -0,0 +1,6 @@ +export * from './schema/archived-emails'; +export * from './schema/attachments'; +export * from './schema/audit-logs'; +export * from './schema/compliance'; +export * from './schema/custodians'; +export * from './schema/ingestion-sources'; diff --git a/packages/backend/src/database/schema/archived-emails.ts b/packages/backend/src/database/schema/archived-emails.ts new file mode 100644 index 0000000..410bca8 --- /dev/null +++ b/packages/backend/src/database/schema/archived-emails.ts @@ -0,0 +1,28 @@ +import { relations } from 'drizzle-orm'; +import { boolean, jsonb, pgTable, text, timestamp, uuid, bigint } from 'drizzle-orm/pg-core'; +import { custodians } from './custodians'; + +export const archivedEmails = pgTable('archived_emails', { + id: uuid('id').primaryKey().defaultRandom(), + custodianId: uuid('custodian_id').notNull().references(() => custodians.id, { onDelete: 'cascade' }), + messageIdHeader: text('message_id_header').notNull(), + sentAt: timestamp('sent_at', { withTimezone: true }).notNull(), + subject: text('subject'), + senderName: text('sender_name'), + senderEmail: text('sender_email').notNull(), + recipients: jsonb('recipients'), + storagePath: text('storage_path').notNull(), + storageHashSha256: text('storage_hash_sha256').notNull(), + sizeBytes: bigint('size_bytes', { mode: 'number' }).notNull(), + isIndexed: boolean('is_indexed').notNull().default(false), + hasAttachments: boolean('has_attachments').notNull().default(false), + isOnLegalHold: boolean('is_on_legal_hold').notNull().default(false), + archivedAt: timestamp('archived_at', { withTimezone: true }).notNull().defaultNow(), +}); + +export const archivedEmailsRelations = relations(archivedEmails, ({ one }) => ({ + custodian: one(custodians, { + fields: [archivedEmails.custodianId], + references: [custodians.id], + }), +})); diff --git a/packages/backend/src/database/schema/attachments.ts b/packages/backend/src/database/schema/attachments.ts new file mode 100644 index 0000000..35e4bea --- /dev/null +++ b/packages/backend/src/database/schema/attachments.ts @@ -0,0 +1,34 @@ +import { relations } from 'drizzle-orm'; +import { pgTable, text, uuid, bigint, primaryKey } from 'drizzle-orm/pg-core'; +import { archivedEmails } from './archived-emails'; + +export const attachments = pgTable('attachments', { + id: uuid('id').primaryKey().defaultRandom(), + filename: text('filename').notNull(), + mimeType: text('mime_type'), + sizeBytes: bigint('size_bytes', { mode: 'number' }).notNull(), + contentHashSha256: text('content_hash_sha256').notNull().unique(), + storagePath: text('storage_path').notNull(), +}); + +export const emailAttachments = pgTable('email_attachments', { + emailId: uuid('email_id').notNull().references(() => archivedEmails.id, { onDelete: 'cascade' }), + attachmentId: uuid('attachment_id').notNull().references(() => attachments.id, { onDelete: 'restrict' }), +}, (t) => ({ + pk: primaryKey({ columns: [t.emailId, t.attachmentId] }), +})); + +export const attachmentsRelations = relations(attachments, ({ many }) => ({ + emailAttachments: many(emailAttachments), +})); + +export const emailAttachmentsRelations = relations(emailAttachments, ({ one }) => ({ + archivedEmail: one(archivedEmails, { + fields: [emailAttachments.emailId], + references: [archivedEmails.id], + }), + attachment: one(attachments, { + fields: [emailAttachments.attachmentId], + references: [attachments.id], + }), +})); diff --git a/packages/backend/src/database/schema/audit-logs.ts b/packages/backend/src/database/schema/audit-logs.ts new file mode 100644 index 0000000..8edba8a --- /dev/null +++ b/packages/backend/src/database/schema/audit-logs.ts @@ -0,0 +1,12 @@ +import { bigserial, boolean, jsonb, pgTable, text, timestamp } from 'drizzle-orm/pg-core'; + +export const auditLogs = pgTable('audit_logs', { + id: bigserial('id', { mode: 'number' }).primaryKey(), + timestamp: timestamp('timestamp', { withTimezone: true }).notNull().defaultNow(), + actorIdentifier: text('actor_identifier').notNull(), + action: text('action').notNull(), + targetType: text('target_type'), + targetId: text('target_id'), + details: jsonb('details'), + isTamperEvident: boolean('is_tamper_evident').default(false), +}); diff --git a/packages/backend/src/database/schema/compliance.ts b/packages/backend/src/database/schema/compliance.ts new file mode 100644 index 0000000..38369fa --- /dev/null +++ b/packages/backend/src/database/schema/compliance.ts @@ -0,0 +1,80 @@ +import { relations } from 'drizzle-orm'; +import { boolean, integer, jsonb, pgEnum, pgTable, text, timestamp, uuid } from 'drizzle-orm/pg-core'; +import { custodians } from './custodians'; + +// --- Enums --- + +export const retentionActionEnum = pgEnum('retention_action', ['delete_permanently', 'notify_admin']); + +// --- Tables --- + +export const retentionPolicies = pgTable('retention_policies', { + id: uuid('id').primaryKey().defaultRandom(), + name: text('name').notNull().unique(), + description: text('description'), + priority: integer('priority').notNull(), + retentionPeriodDays: integer('retention_period_days').notNull(), + actionOnExpiry: retentionActionEnum('action_on_expiry').notNull(), + isEnabled: boolean('is_enabled').notNull().default(true), + conditions: jsonb('conditions'), + createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(), + updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(), +}); + +export const ediscoveryCases = pgTable('ediscovery_cases', { + id: uuid('id').primaryKey().defaultRandom(), + name: text('name').notNull().unique(), + description: text('description'), + status: text('status').notNull().default('open'), + createdByIdentifier: text('created_by_identifier').notNull(), + createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(), + updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(), +}); + +export const legalHolds = pgTable('legal_holds', { + id: uuid('id').primaryKey().defaultRandom(), + caseId: uuid('case_id').notNull().references(() => ediscoveryCases.id, { onDelete: 'cascade' }), + custodianId: uuid('custodian_id').references(() => custodians.id, { onDelete: 'cascade' }), + holdCriteria: jsonb('hold_criteria'), + reason: text('reason'), + appliedByIdentifier: text('applied_by_identifier').notNull(), + appliedAt: timestamp('applied_at', { withTimezone: true }).notNull().defaultNow(), + removedAt: timestamp('removed_at', { withTimezone: true }), +}); + +export const exportJobs = pgTable('export_jobs', { + id: uuid('id').primaryKey().defaultRandom(), + caseId: uuid('case_id').references(() => ediscoveryCases.id, { onDelete: 'set null' }), + format: text('format').notNull(), + status: text('status').notNull().default('pending'), + query: jsonb('query').notNull(), + filePath: text('file_path'), + createdByIdentifier: text('created_by_identifier').notNull(), + createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(), + completedAt: timestamp('completed_at', { withTimezone: true }), +}); + +// --- Relations --- + +export const ediscoveryCasesRelations = relations(ediscoveryCases, ({ many }) => ({ + legalHolds: many(legalHolds), + exportJobs: many(exportJobs), +})); + +export const legalHoldsRelations = relations(legalHolds, ({ one }) => ({ + ediscoveryCase: one(ediscoveryCases, { + fields: [legalHolds.caseId], + references: [ediscoveryCases.id], + }), + custodian: one(custodians, { + fields: [legalHolds.custodianId], + references: [custodians.id], + }), +})); + +export const exportJobsRelations = relations(exportJobs, ({ one }) => ({ + ediscoveryCase: one(ediscoveryCases, { + fields: [exportJobs.caseId], + references: [ediscoveryCases.id], + }), +})); diff --git a/packages/backend/src/database/schema/custodians.ts b/packages/backend/src/database/schema/custodians.ts new file mode 100644 index 0000000..12e0d4c --- /dev/null +++ b/packages/backend/src/database/schema/custodians.ts @@ -0,0 +1,11 @@ +import { pgTable, text, timestamp, uuid } from 'drizzle-orm/pg-core'; +import { ingestionProviderEnum } from './ingestion-sources'; + +export const custodians = pgTable('custodians', { + id: uuid('id').primaryKey().defaultRandom(), + email: text('email').notNull().unique(), + displayName: text('display_name'), + sourceType: ingestionProviderEnum('source_type').notNull(), + createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(), + updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow() +}); diff --git a/packages/backend/src/database/schema/ingestion-sources.ts b/packages/backend/src/database/schema/ingestion-sources.ts new file mode 100644 index 0000000..1d3561a --- /dev/null +++ b/packages/backend/src/database/schema/ingestion-sources.ts @@ -0,0 +1,28 @@ +import { jsonb, pgEnum, pgTable, text, timestamp, uuid } from 'drizzle-orm/pg-core'; + +export const ingestionProviderEnum = pgEnum('ingestion_provider', [ + 'google_workspace', + 'microsoft_365', + 'generic_imap' +]); + +export const ingestionStatusEnum = pgEnum('ingestion_status', [ + 'active', + 'paused', + 'error', + 'pending_auth', + 'syncing' +]); + +export const ingestionSources = pgTable('ingestion_sources', { + id: uuid('id').primaryKey().defaultRandom(), + name: text('name').notNull(), + provider: ingestionProviderEnum('provider').notNull(), + credentials: jsonb('credentials'), + status: ingestionStatusEnum('status').notNull().default('pending_auth'), + lastSyncStartedAt: timestamp('last_sync_started_at', { withTimezone: true }), + lastSyncFinishedAt: timestamp('last_sync_finished_at', { withTimezone: true }), + lastSyncStatusMessage: text('last_sync_status_message'), + createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(), + updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow() +}); diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index 9af51a4..e8a502e 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -1,8 +1,10 @@ import express from 'express'; import dotenv from 'dotenv'; import { AuthController } from './api/controllers/auth.controller'; +import { IngestionController } from './api/controllers/ingestion.controller'; import { requireAuth } from './api/middleware/requireAuth'; import { createAuthRouter } from './api/routes/auth.routes'; +import { createIngestionRouter } from './api/routes/ingestion.routes'; import { AuthService } from './services/AuthService'; import { AdminUserService } from './services/UserService'; @@ -27,6 +29,7 @@ if (!PORT_BACKEND || !JWT_SECRET || !JWT_EXPIRES_IN) { const userService = new AdminUserService(); const authService = new AuthService(userService, JWT_SECRET, JWT_EXPIRES_IN); const authController = new AuthController(authService); +const ingestionController = new IngestionController(); // --- Express App Initialization --- const app = express(); @@ -36,13 +39,15 @@ app.use(express.json()); // For parsing application/json // --- Routes --- const authRouter = createAuthRouter(authController); +const ingestionRouter = createIngestionRouter(ingestionController, authService); app.use('/v1/auth', authRouter); +app.use('/v1/ingestion-sources', ingestionRouter); // Example of a protected route app.get('/v1/protected', requireAuth(authService), (req, res) => { res.json({ message: 'You have accessed a protected route!', - user: req.user, // The user payload is attached by the requireAuth middleware + user: req.user // The user payload is attached by the requireAuth middleware }); }); diff --git a/packages/backend/src/services/IngestionService.ts b/packages/backend/src/services/IngestionService.ts new file mode 100644 index 0000000..d400cbe --- /dev/null +++ b/packages/backend/src/services/IngestionService.ts @@ -0,0 +1,85 @@ +import { db } from '../database'; +import { ingestionSources } from '../database/schema'; +import type { CreateIngestionSourceDto, UpdateIngestionSourceDto } from '@open-archive/types'; +import { eq } from 'drizzle-orm'; +import { Queue } from 'bullmq'; + +// This assumes you have a BullMQ queue instance exported from somewhere +// In a real setup, this would be injected or imported from a central place. +let initialImportQueue: Queue; + +// TODO: Initialize and connect to the actual BullMQ queue. +// For now, we'll use a mock for demonstration purposes. +if (process.env.NODE_ENV !== 'production') { + initialImportQueue = { + add: async (name: string, data: any) => { + console.log(`Mock Queue: Job '${name}' added with data:`, data); + return Promise.resolve({} as any); + } + } as Queue; +} + +export class IngestionService { + public static async create(dto: CreateIngestionSourceDto) { + // The DTO from the frontend uses `providerConfig` for simplicity. + // We map it to the `credentials` column in the database schema. + const { providerConfig, ...rest } = dto; + const valuesToInsert = { + ...rest, + credentials: providerConfig + }; + const [newSource] = await db.insert(ingestionSources).values(valuesToInsert).returning(); + return newSource; + } + + public static async findAll() { + return await db.select().from(ingestionSources); + } + + public static async findById(id: string) { + const [source] = await db.select().from(ingestionSources).where(eq(ingestionSources.id, id)); + if (!source) { + throw new Error('Ingestion source not found'); + } + return source; + } + + public static async update(id: string, dto: UpdateIngestionSourceDto) { + // The DTO from the frontend uses `providerConfig` for simplicity. + // We map it to the `credentials` column in the database schema if it exists. + const { providerConfig, ...rest } = dto; + const valuesToUpdate: Partial = { ...rest }; + if (providerConfig) { + valuesToUpdate.credentials = providerConfig; + } + + const [updatedSource] = await db + .update(ingestionSources) + .set(valuesToUpdate) + .where(eq(ingestionSources.id, id)) + .returning(); + if (!updatedSource) { + throw new Error('Ingestion source not found'); + } + return updatedSource; + } + + public static async delete(id: string) { + const [deletedSource] = await db + .delete(ingestionSources) + .where(eq(ingestionSources.id, id)) + .returning(); + if (!deletedSource) { + throw new Error('Ingestion source not found'); + } + return deletedSource; + } + + public static async triggerInitialImport(id: string) { + const source = await this.findById(id); + + await initialImportQueue.add('initial-import', { ingestionSourceId: source.id }); + + return await this.update(id, { status: 'syncing' }); + } +} diff --git a/packages/frontend/package.json b/packages/frontend/package.json index acaed5b..6a4cbdf 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -14,11 +14,12 @@ "lint": "prettier --check ." }, "dependencies": { - "@open-archive/types": "workspace:*" + "@open-archive/types": "workspace:*", + "lucide-svelte": "^0.525.0" }, "devDependencies": { "@internationalized/date": "^3.8.2", - "@lucide/svelte": "^0.525.0", + "@lucide/svelte": "^0.515.0", "@sveltejs/adapter-auto": "^6.0.0", "@sveltejs/kit": "^2.16.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", diff --git a/packages/frontend/src/lib/api.ts b/packages/frontend/src/lib/api.ts index a14546a..e114f59 100644 --- a/packages/frontend/src/lib/api.ts +++ b/packages/frontend/src/lib/api.ts @@ -9,11 +9,17 @@ const BASE_URL = '/api/v1'; // Using a relative URL for proxying * @param options The standard Fetch API options. * @returns A Promise that resolves to the Fetch Response. */ -export const api = async (url: string, options: RequestInit = {}): Promise => { +type Fetch = typeof fetch; + +export const api = async ( + url: string, + options: RequestInit = {}, + customFetch: Fetch = fetch +): Promise => { const { accessToken } = get(authStore); const defaultHeaders: HeadersInit = { - 'Content-Type': 'application/json', + 'Content-Type': 'application/json' }; if (accessToken) { @@ -24,9 +30,9 @@ export const api = async (url: string, options: RequestInit = {}): Promise + import type { IngestionSource, CreateIngestionSourceDto } from '@open-archive/types'; + import { Button } from '$lib/components/ui/button'; + import * as Dialog from '$lib/components/ui/dialog'; + import { Input } from '$lib/components/ui/input'; + import { Label } from '$lib/components/ui/label'; + import * as Select from '$lib/components/ui/select'; + + let { + source = null, + onSubmit + }: { + source?: IngestionSource | null; + onSubmit: (data: CreateIngestionSourceDto) => void; + } = $props(); + + const providerOptions = [ + { value: 'google_workspace', label: 'Google Workspace' }, + { value: 'microsoft_365', label: 'Microsoft 365' }, + { value: 'generic_imap', label: 'Generic IMAP' } + ]; + + let formData = $state({ + name: source?.name ?? '', + provider: source?.provider ?? 'google_workspace', + providerConfig: source?.providerConfig ?? {} + }); + + const triggerContent = $derived( + providerOptions.find((p) => p.value === formData.provider)?.label ?? 'Select a provider' + ); + + const handleSubmit = (event: Event) => { + event.preventDefault(); + onSubmit(formData); + }; + + +
+
+ + +
+
+ + + + {triggerContent} + + + {#each providerOptions as option} + {option.label} + {/each} + + +
+ + {#if formData.provider === 'google_workspace' || formData.provider === 'microsoft_365'} +
+ + +
+
+ + +
+
+ + +
+ {:else if formData.provider === 'generic_imap'} +
+ + +
+
+ + +
+
+ + +
+
+ + +
+ {/if} + + + +
diff --git a/packages/frontend/src/lib/components/ui/dialog/dialog-close.svelte b/packages/frontend/src/lib/components/ui/dialog/dialog-close.svelte new file mode 100644 index 0000000..840b2f6 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/dialog/dialog-close.svelte @@ -0,0 +1,7 @@ + + + diff --git a/packages/frontend/src/lib/components/ui/dialog/dialog-content.svelte b/packages/frontend/src/lib/components/ui/dialog/dialog-content.svelte new file mode 100644 index 0000000..99cc73b --- /dev/null +++ b/packages/frontend/src/lib/components/ui/dialog/dialog-content.svelte @@ -0,0 +1,43 @@ + + + + + + {@render children?.()} + {#if showCloseButton} + + + Close + + {/if} + + diff --git a/packages/frontend/src/lib/components/ui/dialog/dialog-description.svelte b/packages/frontend/src/lib/components/ui/dialog/dialog-description.svelte new file mode 100644 index 0000000..3845023 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/dialog/dialog-description.svelte @@ -0,0 +1,17 @@ + + + diff --git a/packages/frontend/src/lib/components/ui/dialog/dialog-footer.svelte b/packages/frontend/src/lib/components/ui/dialog/dialog-footer.svelte new file mode 100644 index 0000000..e7ff446 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/dialog/dialog-footer.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/packages/frontend/src/lib/components/ui/dialog/dialog-header.svelte b/packages/frontend/src/lib/components/ui/dialog/dialog-header.svelte new file mode 100644 index 0000000..fc90cd9 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/dialog/dialog-header.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/packages/frontend/src/lib/components/ui/dialog/dialog-overlay.svelte b/packages/frontend/src/lib/components/ui/dialog/dialog-overlay.svelte new file mode 100644 index 0000000..f81ad83 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/dialog/dialog-overlay.svelte @@ -0,0 +1,20 @@ + + + diff --git a/packages/frontend/src/lib/components/ui/dialog/dialog-title.svelte b/packages/frontend/src/lib/components/ui/dialog/dialog-title.svelte new file mode 100644 index 0000000..067e55e --- /dev/null +++ b/packages/frontend/src/lib/components/ui/dialog/dialog-title.svelte @@ -0,0 +1,17 @@ + + + diff --git a/packages/frontend/src/lib/components/ui/dialog/dialog-trigger.svelte b/packages/frontend/src/lib/components/ui/dialog/dialog-trigger.svelte new file mode 100644 index 0000000..9d1e801 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/dialog/dialog-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/packages/frontend/src/lib/components/ui/dialog/index.ts b/packages/frontend/src/lib/components/ui/dialog/index.ts new file mode 100644 index 0000000..dce1d9d --- /dev/null +++ b/packages/frontend/src/lib/components/ui/dialog/index.ts @@ -0,0 +1,37 @@ +import { Dialog as DialogPrimitive } from "bits-ui"; + +import Title from "./dialog-title.svelte"; +import Footer from "./dialog-footer.svelte"; +import Header from "./dialog-header.svelte"; +import Overlay from "./dialog-overlay.svelte"; +import Content from "./dialog-content.svelte"; +import Description from "./dialog-description.svelte"; +import Trigger from "./dialog-trigger.svelte"; +import Close from "./dialog-close.svelte"; + +const Root = DialogPrimitive.Root; +const Portal = DialogPrimitive.Portal; + +export { + Root, + Title, + Portal, + Footer, + Header, + Trigger, + Overlay, + Content, + Description, + Close, + // + Root as Dialog, + Title as DialogTitle, + Portal as DialogPortal, + Footer as DialogFooter, + Header as DialogHeader, + Trigger as DialogTrigger, + Overlay as DialogOverlay, + Content as DialogContent, + Description as DialogDescription, + Close as DialogClose, +}; diff --git a/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte new file mode 100644 index 0000000..e03f949 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte @@ -0,0 +1,41 @@ + + + + {#snippet children({ checked, indeterminate })} + + {#if indeterminate} + + {:else} + + {/if} + + {@render childrenProp?.()} + {/snippet} + diff --git a/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte new file mode 100644 index 0000000..498c4b9 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte @@ -0,0 +1,27 @@ + + + + + diff --git a/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte new file mode 100644 index 0000000..48d14a9 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte @@ -0,0 +1,22 @@ + + + diff --git a/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte new file mode 100644 index 0000000..aca1f7b --- /dev/null +++ b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte @@ -0,0 +1,7 @@ + + + diff --git a/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte new file mode 100644 index 0000000..64bb283 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte @@ -0,0 +1,27 @@ + + + diff --git a/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte new file mode 100644 index 0000000..f72e477 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte @@ -0,0 +1,24 @@ + + +
+ {@render children?.()} +
diff --git a/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte new file mode 100644 index 0000000..189aef4 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte @@ -0,0 +1,16 @@ + + + diff --git a/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte new file mode 100644 index 0000000..513170a --- /dev/null +++ b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte @@ -0,0 +1,31 @@ + + + + {#snippet children({ checked })} + + {#if checked} + + {/if} + + {@render childrenProp?.({ checked })} + {/snippet} + diff --git a/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte new file mode 100644 index 0000000..90f1b6f --- /dev/null +++ b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte @@ -0,0 +1,17 @@ + + + diff --git a/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte new file mode 100644 index 0000000..6974947 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte new file mode 100644 index 0000000..30deb9e --- /dev/null +++ b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte @@ -0,0 +1,20 @@ + + + diff --git a/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte new file mode 100644 index 0000000..f9b286a --- /dev/null +++ b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte @@ -0,0 +1,29 @@ + + + + {@render children?.()} + + diff --git a/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte new file mode 100644 index 0000000..cb05344 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/packages/frontend/src/lib/components/ui/dropdown-menu/index.ts b/packages/frontend/src/lib/components/ui/dropdown-menu/index.ts new file mode 100644 index 0000000..1cf9f70 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/dropdown-menu/index.ts @@ -0,0 +1,49 @@ +import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui"; +import CheckboxItem from "./dropdown-menu-checkbox-item.svelte"; +import Content from "./dropdown-menu-content.svelte"; +import Group from "./dropdown-menu-group.svelte"; +import Item from "./dropdown-menu-item.svelte"; +import Label from "./dropdown-menu-label.svelte"; +import RadioGroup from "./dropdown-menu-radio-group.svelte"; +import RadioItem from "./dropdown-menu-radio-item.svelte"; +import Separator from "./dropdown-menu-separator.svelte"; +import Shortcut from "./dropdown-menu-shortcut.svelte"; +import Trigger from "./dropdown-menu-trigger.svelte"; +import SubContent from "./dropdown-menu-sub-content.svelte"; +import SubTrigger from "./dropdown-menu-sub-trigger.svelte"; +import GroupHeading from "./dropdown-menu-group-heading.svelte"; +const Sub = DropdownMenuPrimitive.Sub; +const Root = DropdownMenuPrimitive.Root; + +export { + CheckboxItem, + Content, + Root as DropdownMenu, + CheckboxItem as DropdownMenuCheckboxItem, + Content as DropdownMenuContent, + Group as DropdownMenuGroup, + Item as DropdownMenuItem, + Label as DropdownMenuLabel, + RadioGroup as DropdownMenuRadioGroup, + RadioItem as DropdownMenuRadioItem, + Separator as DropdownMenuSeparator, + Shortcut as DropdownMenuShortcut, + Sub as DropdownMenuSub, + SubContent as DropdownMenuSubContent, + SubTrigger as DropdownMenuSubTrigger, + Trigger as DropdownMenuTrigger, + GroupHeading as DropdownMenuGroupHeading, + Group, + GroupHeading, + Item, + Label, + RadioGroup, + RadioItem, + Root, + Separator, + Shortcut, + Sub, + SubContent, + SubTrigger, + Trigger, +}; diff --git a/packages/frontend/src/lib/components/ui/select/index.ts b/packages/frontend/src/lib/components/ui/select/index.ts new file mode 100644 index 0000000..9e8d3e9 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/select/index.ts @@ -0,0 +1,37 @@ +import { Select as SelectPrimitive } from "bits-ui"; + +import Group from "./select-group.svelte"; +import Label from "./select-label.svelte"; +import Item from "./select-item.svelte"; +import Content from "./select-content.svelte"; +import Trigger from "./select-trigger.svelte"; +import Separator from "./select-separator.svelte"; +import ScrollDownButton from "./select-scroll-down-button.svelte"; +import ScrollUpButton from "./select-scroll-up-button.svelte"; +import GroupHeading from "./select-group-heading.svelte"; + +const Root = SelectPrimitive.Root; + +export { + Root, + Group, + Label, + Item, + Content, + Trigger, + Separator, + ScrollDownButton, + ScrollUpButton, + GroupHeading, + // + Root as Select, + Group as SelectGroup, + Label as SelectLabel, + Item as SelectItem, + Content as SelectContent, + Trigger as SelectTrigger, + Separator as SelectSeparator, + ScrollDownButton as SelectScrollDownButton, + ScrollUpButton as SelectScrollUpButton, + GroupHeading as SelectGroupHeading, +}; diff --git a/packages/frontend/src/lib/components/ui/select/select-content.svelte b/packages/frontend/src/lib/components/ui/select/select-content.svelte new file mode 100644 index 0000000..dc16d65 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/select/select-content.svelte @@ -0,0 +1,40 @@ + + + + + + + {@render children?.()} + + + + diff --git a/packages/frontend/src/lib/components/ui/select/select-group-heading.svelte b/packages/frontend/src/lib/components/ui/select/select-group-heading.svelte new file mode 100644 index 0000000..1fab5f0 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/select/select-group-heading.svelte @@ -0,0 +1,21 @@ + + + + {@render children?.()} + diff --git a/packages/frontend/src/lib/components/ui/select/select-group.svelte b/packages/frontend/src/lib/components/ui/select/select-group.svelte new file mode 100644 index 0000000..5454fdb --- /dev/null +++ b/packages/frontend/src/lib/components/ui/select/select-group.svelte @@ -0,0 +1,7 @@ + + + diff --git a/packages/frontend/src/lib/components/ui/select/select-item.svelte b/packages/frontend/src/lib/components/ui/select/select-item.svelte new file mode 100644 index 0000000..49dbbd7 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/select/select-item.svelte @@ -0,0 +1,38 @@ + + + + {#snippet children({ selected, highlighted })} + + {#if selected} + + {/if} + + {#if childrenProp} + {@render childrenProp({ selected, highlighted })} + {:else} + {label || value} + {/if} + {/snippet} + diff --git a/packages/frontend/src/lib/components/ui/select/select-label.svelte b/packages/frontend/src/lib/components/ui/select/select-label.svelte new file mode 100644 index 0000000..4696025 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/select/select-label.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/packages/frontend/src/lib/components/ui/select/select-scroll-down-button.svelte b/packages/frontend/src/lib/components/ui/select/select-scroll-down-button.svelte new file mode 100644 index 0000000..3629205 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/select/select-scroll-down-button.svelte @@ -0,0 +1,20 @@ + + + + + diff --git a/packages/frontend/src/lib/components/ui/select/select-scroll-up-button.svelte b/packages/frontend/src/lib/components/ui/select/select-scroll-up-button.svelte new file mode 100644 index 0000000..1aa2300 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/select/select-scroll-up-button.svelte @@ -0,0 +1,20 @@ + + + + + diff --git a/packages/frontend/src/lib/components/ui/select/select-separator.svelte b/packages/frontend/src/lib/components/ui/select/select-separator.svelte new file mode 100644 index 0000000..0eac3eb --- /dev/null +++ b/packages/frontend/src/lib/components/ui/select/select-separator.svelte @@ -0,0 +1,18 @@ + + + diff --git a/packages/frontend/src/lib/components/ui/select/select-trigger.svelte b/packages/frontend/src/lib/components/ui/select/select-trigger.svelte new file mode 100644 index 0000000..d405187 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/select/select-trigger.svelte @@ -0,0 +1,29 @@ + + + + {@render children?.()} + + diff --git a/packages/frontend/src/lib/components/ui/separator/index.ts b/packages/frontend/src/lib/components/ui/separator/index.ts new file mode 100644 index 0000000..82442d2 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/separator/index.ts @@ -0,0 +1,7 @@ +import Root from "./separator.svelte"; + +export { + Root, + // + Root as Separator, +}; diff --git a/packages/frontend/src/lib/components/ui/separator/separator.svelte b/packages/frontend/src/lib/components/ui/separator/separator.svelte new file mode 100644 index 0000000..09d88f4 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/separator/separator.svelte @@ -0,0 +1,20 @@ + + + diff --git a/packages/frontend/src/lib/components/ui/table/index.ts b/packages/frontend/src/lib/components/ui/table/index.ts new file mode 100644 index 0000000..14695c8 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/table/index.ts @@ -0,0 +1,28 @@ +import Root from "./table.svelte"; +import Body from "./table-body.svelte"; +import Caption from "./table-caption.svelte"; +import Cell from "./table-cell.svelte"; +import Footer from "./table-footer.svelte"; +import Head from "./table-head.svelte"; +import Header from "./table-header.svelte"; +import Row from "./table-row.svelte"; + +export { + Root, + Body, + Caption, + Cell, + Footer, + Head, + Header, + Row, + // + Root as Table, + Body as TableBody, + Caption as TableCaption, + Cell as TableCell, + Footer as TableFooter, + Head as TableHead, + Header as TableHeader, + Row as TableRow, +}; diff --git a/packages/frontend/src/lib/components/ui/table/table-body.svelte b/packages/frontend/src/lib/components/ui/table/table-body.svelte new file mode 100644 index 0000000..29e9687 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/table/table-body.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/packages/frontend/src/lib/components/ui/table/table-caption.svelte b/packages/frontend/src/lib/components/ui/table/table-caption.svelte new file mode 100644 index 0000000..4696cff --- /dev/null +++ b/packages/frontend/src/lib/components/ui/table/table-caption.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/packages/frontend/src/lib/components/ui/table/table-cell.svelte b/packages/frontend/src/lib/components/ui/table/table-cell.svelte new file mode 100644 index 0000000..1a2f033 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/table/table-cell.svelte @@ -0,0 +1,23 @@ + + + + {@render children?.()} + diff --git a/packages/frontend/src/lib/components/ui/table/table-footer.svelte b/packages/frontend/src/lib/components/ui/table/table-footer.svelte new file mode 100644 index 0000000..b9b14eb --- /dev/null +++ b/packages/frontend/src/lib/components/ui/table/table-footer.svelte @@ -0,0 +1,20 @@ + + +tr]:last:border-b-0", className)} + {...restProps} +> + {@render children?.()} + diff --git a/packages/frontend/src/lib/components/ui/table/table-head.svelte b/packages/frontend/src/lib/components/ui/table/table-head.svelte new file mode 100644 index 0000000..e9dd237 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/table/table-head.svelte @@ -0,0 +1,23 @@ + + + + {@render children?.()} + diff --git a/packages/frontend/src/lib/components/ui/table/table-header.svelte b/packages/frontend/src/lib/components/ui/table/table-header.svelte new file mode 100644 index 0000000..f47d259 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/table/table-header.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/packages/frontend/src/lib/components/ui/table/table-row.svelte b/packages/frontend/src/lib/components/ui/table/table-row.svelte new file mode 100644 index 0000000..0df769e --- /dev/null +++ b/packages/frontend/src/lib/components/ui/table/table-row.svelte @@ -0,0 +1,23 @@ + + +svelte-css-wrapper]:[&>th,td]:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors", + className + )} + {...restProps} +> + {@render children?.()} + diff --git a/packages/frontend/src/lib/components/ui/table/table.svelte b/packages/frontend/src/lib/components/ui/table/table.svelte new file mode 100644 index 0000000..a334956 --- /dev/null +++ b/packages/frontend/src/lib/components/ui/table/table.svelte @@ -0,0 +1,22 @@ + + +
+ + {@render children?.()} +
+
diff --git a/packages/frontend/src/routes/dashboard/ingestions/+page.svelte b/packages/frontend/src/routes/dashboard/ingestions/+page.svelte new file mode 100644 index 0000000..7376ae7 --- /dev/null +++ b/packages/frontend/src/routes/dashboard/ingestions/+page.svelte @@ -0,0 +1,143 @@ + + +
+
+

Ingestion Sources

+ +
+ +
+ + + + Name + Provider + Status + Created At + Actions + + + + {#if ingestionSources.length > 0} + {#each ingestionSources as source (source.id)} + + {source.name} + {source.provider} + {source.status} + {new Date(source.createdAt).toLocaleDateString()} + + + + + + + Actions + openEditDialog(source)} + >Edit + handleSync(source.id)}>Sync + + handleDelete(source.id)} + >Delete + + + + + {/each} + {:else} + + No ingestion sources found. + + {/if} + + +
+
+ + + + + {selectedSource ? 'Edit' : 'Create'} Ingestion Source + + {selectedSource + ? 'Make changes to your ingestion source here.' + : 'Add a new ingestion source to start archiving emails.'} + + + + + diff --git a/packages/frontend/src/routes/dashboard/ingestions/+page.ts b/packages/frontend/src/routes/dashboard/ingestions/+page.ts new file mode 100644 index 0000000..cb62064 --- /dev/null +++ b/packages/frontend/src/routes/dashboard/ingestions/+page.ts @@ -0,0 +1,22 @@ +import { api } from '$lib/api'; +import type { PageLoad } from './$types'; +import type { IngestionSource } from '@open-archive/types'; + +export const load: PageLoad = async ({ fetch }) => { + try { + const response = await api('/ingestion-sources', {}, fetch); + if (!response.ok) { + throw new Error(`Failed to fetch ingestion sources: ${response.statusText}`); + } + const ingestionSources: IngestionSource[] = await response.json(); + return { + ingestionSources + }; + } catch (error) { + console.error('Failed to load ingestion sources:', error); + return { + ingestionSources: [], + error: 'Failed to load ingestion sources' + }; + } +}; diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 219d19b..170867c 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -1,2 +1,3 @@ export * from './auth.types'; export * from './user.types'; +export * from './ingestion.types'; diff --git a/packages/types/src/ingestion.types.ts b/packages/types/src/ingestion.types.ts new file mode 100644 index 0000000..736257a --- /dev/null +++ b/packages/types/src/ingestion.types.ts @@ -0,0 +1,26 @@ +export type IngestionProvider = 'google_workspace' | 'microsoft_365' | 'generic_imap'; + +export type IngestionStatus = 'active' | 'paused' | 'error' | 'pending_auth' | 'syncing'; + +export interface IngestionSource { + id: string; + name: string; + provider: IngestionProvider; + status: IngestionStatus; + createdAt: Date; + updatedAt: Date; + providerConfig: Record; +} + +export interface CreateIngestionSourceDto { + name: string; + provider: IngestionProvider; + providerConfig: Record; +} + +export interface UpdateIngestionSourceDto { + name?: string; + provider?: IngestionProvider; + status?: IngestionStatus; + providerConfig?: Record; +} diff --git a/packages/types/tsconfig.tsbuildinfo b/packages/types/tsconfig.tsbuildinfo index 3338e15..6539615 100644 --- a/packages/types/tsconfig.tsbuildinfo +++ b/packages/types/tsconfig.tsbuildinfo @@ -1 +1 @@ -{"fileNames":["../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2023.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2024.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.esnext.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.dom.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.dom.iterable.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.dom.asynciterable.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.webworker.importscripts.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.scripthost.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2016.intl.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.date.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2023.array.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2023.collection.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2023.intl.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2024.collection.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2024.object.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2024.promise.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2024.regexp.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2024.string.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.esnext.array.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.esnext.collection.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.esnext.intl.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.esnext.disposable.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.esnext.promise.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.esnext.decorators.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.esnext.iterator.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.esnext.float16.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.decorators.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.esnext.full.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/types.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwe/compact/decrypt.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwe/flattened/decrypt.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwe/general/decrypt.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwe/general/encrypt.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jws/compact/verify.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jws/flattened/verify.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jws/general/verify.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwt/verify.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwt/decrypt.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwe/compact/encrypt.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwe/flattened/encrypt.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jws/compact/sign.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jws/flattened/sign.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jws/general/sign.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwt/sign.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwt/encrypt.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwk/thumbprint.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwk/embedded.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwks/local.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwks/remote.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwt/unsecured.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/key/export.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/key/import.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/util/decode_protected_header.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/util/decode_jwt.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/util/errors.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/key/generate_key_pair.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/key/generate_secret.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/util/base64url.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/index.d.ts","./src/user.types.ts","./src/auth.types.ts","./src/index.ts"],"fileIdsList":[[85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114],[85],[115,116],[116,117]],"fileInfos":[{"version":"69684132aeb9b5642cbcd9e22dff7818ff0ee1aa831728af0ecf97d3364d5546","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"27bdc30a0e32783366a5abeda841bc22757c1797de8681bbe81fbc735eeb1c10","impliedFormat":1},{"version":"8fd575e12870e9944c7e1d62e1f5a73fcf23dd8d3a321f2a2c74c20d022283fe","impliedFormat":1},{"version":"8bf8b5e44e3c9c36f98e1007e8b7018c0f38d8adc07aecef42f5200114547c70","impliedFormat":1},{"version":"092c2bfe125ce69dbb1223c85d68d4d2397d7d8411867b5cc03cec902c233763","affectsGlobalScope":true,"impliedFormat":1},{"version":"07f073f19d67f74d732b1adea08e1dc66b1b58d77cb5b43931dee3d798a2fd53","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7a3c8b952931daebdfc7a2897c53c0a1c73624593fa070e46bd537e64dcd20a","affectsGlobalScope":true,"impliedFormat":1},{"version":"80e18897e5884b6723488d4f5652167e7bb5024f946743134ecc4aa4ee731f89","affectsGlobalScope":true,"impliedFormat":1},{"version":"cd034f499c6cdca722b60c04b5b1b78e058487a7085a8e0d6fb50809947ee573","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"936e80ad36a2ee83fc3caf008e7c4c5afe45b3cf3d5c24408f039c1d47bdc1df","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"fef8cfad2e2dc5f5b3d97a6f4f2e92848eb1b88e897bb7318cef0e2820bceaab","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"b5ce7a470bc3628408429040c4e3a53a27755022a32fd05e2cb694e7015386c7","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"df83c2a6c73228b625b0beb6669c7ee2a09c914637e2d35170723ad49c0f5cd4","affectsGlobalScope":true,"impliedFormat":1},{"version":"436aaf437562f276ec2ddbee2f2cdedac7664c1e4c1d2c36839ddd582eeb3d0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e3c06ea092138bf9fa5e874a1fdbc9d54805d074bee1de31b99a11e2fec239d","affectsGlobalScope":true,"impliedFormat":1},{"version":"87dc0f382502f5bbce5129bdc0aea21e19a3abbc19259e0b43ae038a9fc4e326","affectsGlobalScope":true,"impliedFormat":1},{"version":"b1cb28af0c891c8c96b2d6b7be76bd394fddcfdb4709a20ba05a7c1605eea0f9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2fef54945a13095fdb9b84f705f2b5994597640c46afeb2ce78352fab4cb3279","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac77cb3e8c6d3565793eb90a8373ee8033146315a3dbead3bde8db5eaf5e5ec6","affectsGlobalScope":true,"impliedFormat":1},{"version":"56e4ed5aab5f5920980066a9409bfaf53e6d21d3f8d020c17e4de584d29600ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ece9f17b3866cc077099c73f4983bddbcb1dc7ddb943227f1ec070f529dedd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a6282c8827e4b9a95f4bf4f5c205673ada31b982f50572d27103df8ceb8013c","affectsGlobalScope":true,"impliedFormat":1},{"version":"1c9319a09485199c1f7b0498f2988d6d2249793ef67edda49d1e584746be9032","affectsGlobalScope":true,"impliedFormat":1},{"version":"e3a2a0cee0f03ffdde24d89660eba2685bfbdeae955a6c67e8c4c9fd28928eeb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811c71eee4aa0ac5f7adf713323a5c41b0cf6c4e17367a34fbce379e12bbf0a4","affectsGlobalScope":true,"impliedFormat":1},{"version":"51ad4c928303041605b4d7ae32e0c1ee387d43a24cd6f1ebf4a2699e1076d4fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"60037901da1a425516449b9a20073aa03386cce92f7a1fd902d7602be3a7c2e9","affectsGlobalScope":true,"impliedFormat":1},{"version":"d4b1d2c51d058fc21ec2629fff7a76249dec2e36e12960ea056e3ef89174080f","affectsGlobalScope":true,"impliedFormat":1},{"version":"22adec94ef7047a6c9d1af3cb96be87a335908bf9ef386ae9fd50eeb37f44c47","affectsGlobalScope":true,"impliedFormat":1},{"version":"4245fee526a7d1754529d19227ecbf3be066ff79ebb6a380d78e41648f2f224d","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"bde31fd423cd93b0eff97197a3f66df7c93e8c0c335cbeb113b7ff1ac35c23f4","impliedFormat":1},{"version":"dc9e7909f3edca55a7da578ab1f2b473490cf1cea844fd05af2daee94e17e518","impliedFormat":99},{"version":"a380cd0a371b5b344c2f679a932593f02445571f9de0014bdf013dddf2a77376","impliedFormat":99},{"version":"dbbcd13911daafc1554acc17dad18ab92f91b5b8f084c6c4370cb8c60520c3b6","impliedFormat":99},{"version":"ab17464cd8391785c29509c629aa8477c8e86d4d3013f4c200b71ac574774ec2","impliedFormat":99},{"version":"d7f1043cbc447d09c8962c973d9f60e466c18e6bbaa470777901d9c2d357cfbe","impliedFormat":99},{"version":"e130a73d7e1e34953b1964c17c218fd14fccd1df6f15f111352b0d53291311bb","impliedFormat":99},{"version":"4ddecad872558e2b3df434ef0b01114d245e7a18a86afa6e7b5c68e75f9b8f76","impliedFormat":99},{"version":"a0ab7a82c3f844d4d4798f68f7bd6dc304e9ad6130631c90a09fb2636cb62756","impliedFormat":99},{"version":"270ceb915b1304c042b6799de28ff212cfa4baf06900d3a8bc4b79f62f00c8a7","impliedFormat":99},{"version":"1b3174ea6e3b4ae157c88eb28bf8e6d67f044edc9c552daf5488628fd8e5be97","impliedFormat":99},{"version":"1d1c0e6bda55b6fdcc247c4abd1ba2a36b50aac71bbf78770cbd172713c4e05f","impliedFormat":99},{"version":"d7d8a5f6a306b755dfa5a9b101cb800fd912b256222fb7d4629b5de416b4b8d5","impliedFormat":99},{"version":"5585ed538922e2e58655218652dcb262f08afa902f26f490cdec4967887ac31a","impliedFormat":99},{"version":"b46de7238d9d2243b27a21797e4772ba91465caae9c31f21dc43748dc9de9cd0","impliedFormat":99},{"version":"625fdbce788630c62f793cb6c80e0072ce0b8bf1d4d0a9922430671164371e0b","impliedFormat":99},{"version":"b6790300d245377671c085e76e9ef359b3cbba6821b913d6ce6b2739d00b9fb1","impliedFormat":99},{"version":"6beaff23ae0b12aa3b7672c7fd4e924f5088efa899b58fe83c7cc5675234ff14","impliedFormat":99},{"version":"a36c717362d06d76e7332d9c1d2744c2c5e4b4a5da6218ef7b4a299a62d23a6d","impliedFormat":99},{"version":"a61f8455fd21cec75a8288cd761f5bcc72441848841eb64aa09569e9d8929ff0","impliedFormat":99},{"version":"7539c82be2eb9b83ec335b11bb06dc35497f0b7dab8830b2c08b650d62707160","impliedFormat":99},{"version":"0eaa77f9ed4c3eb8fac011066c987b6faa7c70db95cfe9e3fb434573e095c4c8","impliedFormat":99},{"version":"466e7296272b827c55b53a7858502de733733558966e2e3a7cc78274e930210a","impliedFormat":99},{"version":"364a5c527037fdd7d494ab0a97f510d3ceda30b8a4bc598b490c135f959ff3c6","impliedFormat":99},{"version":"d26c255888cc20d5ab7397cc267ad81c8d7e97624c442a218afec00949e7316e","impliedFormat":99},{"version":"83d2dab980f2d1a2fe333f0001de8f42c831a438159d47b77c686ae405891b7f","impliedFormat":99},{"version":"ca369bcbdafc423d1a9dccd69de98044534900ff8236d2dd970b52438afb5355","impliedFormat":99},{"version":"5b90280e84e8eba347caaefc18210de3ce6ac176f5e82705a28e7f497dcc8689","impliedFormat":99},{"version":"6fc2d85e6d20a566b97001ee9a74dacc18d801bc9e9b735988119036db992932","impliedFormat":99},{"version":"d57bf30bf951ca5ce0119fcce3810bd03205377d78f08dfe6fca9d350ce73edc","impliedFormat":99},{"version":"e7878d8cd1fd0d0f1c55dcd8f5539f4c22e44993852f588dd194bd666b230727","impliedFormat":99},{"version":"638575c7a309a595c5ac3a65f03a643438fd81bf378aac93eadb84461cdd247c","impliedFormat":99},{"version":"70eebdf8cb991b4b5a1bfd9540698012cf9b2f11d265f7349e2fb7b7cb82d07b","signature":"4c60eadea5f3da0a00a59d1d46e3c9e106da50e89df04f75bd88e81c2d3cb42d"},{"version":"7f729540963914f308742abcebd1c93cf6634ca85e4024177705d811301a09ab","signature":"9033c48366f3826f3e362190c39da048e43e4fe22b27eb7b3f5550d47c41dfec"},"3de70454fdf1e9353eb3f80b94564dd39c15e5760867c4bcd32671eae7959f02"],"root":[[116,118]],"options":{"composite":true,"declaration":true,"esModuleInterop":true,"module":1,"outDir":"./dist","rootDir":"./src","skipLibCheck":true,"strict":true,"target":99},"referencedMap":[[115,1],[86,2],[95,2],[87,2],[96,2],[88,2],[89,2],[103,2],[102,2],[104,2],[105,2],[97,2],[90,2],[98,2],[91,2],[99,2],[92,2],[94,2],[101,2],[100,2],[106,2],[93,2],[107,2],[112,2],[113,2],[108,2],[110,2],[109,2],[111,2],[117,3],[118,4]],"latestChangedDtsFile":"./dist/auth.types.d.ts","version":"5.8.3"} \ No newline at end of file +{"fileNames":["../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2023.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2024.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.esnext.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.dom.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.dom.iterable.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.dom.asynciterable.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.webworker.importscripts.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.scripthost.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2016.intl.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.date.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2023.array.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2023.collection.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2023.intl.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2024.collection.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2024.object.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2024.promise.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2024.regexp.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2024.string.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.esnext.array.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.esnext.collection.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.esnext.intl.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.esnext.disposable.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.esnext.promise.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.esnext.decorators.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.esnext.iterator.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.esnext.float16.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.decorators.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.esnext.full.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/types.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwe/compact/decrypt.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwe/flattened/decrypt.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwe/general/decrypt.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwe/general/encrypt.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jws/compact/verify.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jws/flattened/verify.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jws/general/verify.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwt/verify.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwt/decrypt.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwe/compact/encrypt.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwe/flattened/encrypt.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jws/compact/sign.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jws/flattened/sign.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jws/general/sign.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwt/sign.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwt/encrypt.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwk/thumbprint.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwk/embedded.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwks/local.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwks/remote.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/jwt/unsecured.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/key/export.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/key/import.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/util/decode_protected_header.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/util/decode_jwt.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/util/errors.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/key/generate_key_pair.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/key/generate_secret.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/util/base64url.d.ts","../../node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/types/index.d.ts","./src/user.types.ts","./src/auth.types.ts","./src/ingestion.types.ts","./src/index.ts"],"fileIdsList":[[85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114],[85],[115,116],[116,117,118]],"fileInfos":[{"version":"69684132aeb9b5642cbcd9e22dff7818ff0ee1aa831728af0ecf97d3364d5546","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"27bdc30a0e32783366a5abeda841bc22757c1797de8681bbe81fbc735eeb1c10","impliedFormat":1},{"version":"8fd575e12870e9944c7e1d62e1f5a73fcf23dd8d3a321f2a2c74c20d022283fe","impliedFormat":1},{"version":"8bf8b5e44e3c9c36f98e1007e8b7018c0f38d8adc07aecef42f5200114547c70","impliedFormat":1},{"version":"092c2bfe125ce69dbb1223c85d68d4d2397d7d8411867b5cc03cec902c233763","affectsGlobalScope":true,"impliedFormat":1},{"version":"07f073f19d67f74d732b1adea08e1dc66b1b58d77cb5b43931dee3d798a2fd53","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7a3c8b952931daebdfc7a2897c53c0a1c73624593fa070e46bd537e64dcd20a","affectsGlobalScope":true,"impliedFormat":1},{"version":"80e18897e5884b6723488d4f5652167e7bb5024f946743134ecc4aa4ee731f89","affectsGlobalScope":true,"impliedFormat":1},{"version":"cd034f499c6cdca722b60c04b5b1b78e058487a7085a8e0d6fb50809947ee573","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"936e80ad36a2ee83fc3caf008e7c4c5afe45b3cf3d5c24408f039c1d47bdc1df","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"fef8cfad2e2dc5f5b3d97a6f4f2e92848eb1b88e897bb7318cef0e2820bceaab","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"b5ce7a470bc3628408429040c4e3a53a27755022a32fd05e2cb694e7015386c7","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"df83c2a6c73228b625b0beb6669c7ee2a09c914637e2d35170723ad49c0f5cd4","affectsGlobalScope":true,"impliedFormat":1},{"version":"436aaf437562f276ec2ddbee2f2cdedac7664c1e4c1d2c36839ddd582eeb3d0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e3c06ea092138bf9fa5e874a1fdbc9d54805d074bee1de31b99a11e2fec239d","affectsGlobalScope":true,"impliedFormat":1},{"version":"87dc0f382502f5bbce5129bdc0aea21e19a3abbc19259e0b43ae038a9fc4e326","affectsGlobalScope":true,"impliedFormat":1},{"version":"b1cb28af0c891c8c96b2d6b7be76bd394fddcfdb4709a20ba05a7c1605eea0f9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2fef54945a13095fdb9b84f705f2b5994597640c46afeb2ce78352fab4cb3279","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac77cb3e8c6d3565793eb90a8373ee8033146315a3dbead3bde8db5eaf5e5ec6","affectsGlobalScope":true,"impliedFormat":1},{"version":"56e4ed5aab5f5920980066a9409bfaf53e6d21d3f8d020c17e4de584d29600ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ece9f17b3866cc077099c73f4983bddbcb1dc7ddb943227f1ec070f529dedd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a6282c8827e4b9a95f4bf4f5c205673ada31b982f50572d27103df8ceb8013c","affectsGlobalScope":true,"impliedFormat":1},{"version":"1c9319a09485199c1f7b0498f2988d6d2249793ef67edda49d1e584746be9032","affectsGlobalScope":true,"impliedFormat":1},{"version":"e3a2a0cee0f03ffdde24d89660eba2685bfbdeae955a6c67e8c4c9fd28928eeb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811c71eee4aa0ac5f7adf713323a5c41b0cf6c4e17367a34fbce379e12bbf0a4","affectsGlobalScope":true,"impliedFormat":1},{"version":"51ad4c928303041605b4d7ae32e0c1ee387d43a24cd6f1ebf4a2699e1076d4fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"60037901da1a425516449b9a20073aa03386cce92f7a1fd902d7602be3a7c2e9","affectsGlobalScope":true,"impliedFormat":1},{"version":"d4b1d2c51d058fc21ec2629fff7a76249dec2e36e12960ea056e3ef89174080f","affectsGlobalScope":true,"impliedFormat":1},{"version":"22adec94ef7047a6c9d1af3cb96be87a335908bf9ef386ae9fd50eeb37f44c47","affectsGlobalScope":true,"impliedFormat":1},{"version":"4245fee526a7d1754529d19227ecbf3be066ff79ebb6a380d78e41648f2f224d","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"bde31fd423cd93b0eff97197a3f66df7c93e8c0c335cbeb113b7ff1ac35c23f4","impliedFormat":1},{"version":"dc9e7909f3edca55a7da578ab1f2b473490cf1cea844fd05af2daee94e17e518","impliedFormat":99},{"version":"a380cd0a371b5b344c2f679a932593f02445571f9de0014bdf013dddf2a77376","impliedFormat":99},{"version":"dbbcd13911daafc1554acc17dad18ab92f91b5b8f084c6c4370cb8c60520c3b6","impliedFormat":99},{"version":"ab17464cd8391785c29509c629aa8477c8e86d4d3013f4c200b71ac574774ec2","impliedFormat":99},{"version":"d7f1043cbc447d09c8962c973d9f60e466c18e6bbaa470777901d9c2d357cfbe","impliedFormat":99},{"version":"e130a73d7e1e34953b1964c17c218fd14fccd1df6f15f111352b0d53291311bb","impliedFormat":99},{"version":"4ddecad872558e2b3df434ef0b01114d245e7a18a86afa6e7b5c68e75f9b8f76","impliedFormat":99},{"version":"a0ab7a82c3f844d4d4798f68f7bd6dc304e9ad6130631c90a09fb2636cb62756","impliedFormat":99},{"version":"270ceb915b1304c042b6799de28ff212cfa4baf06900d3a8bc4b79f62f00c8a7","impliedFormat":99},{"version":"1b3174ea6e3b4ae157c88eb28bf8e6d67f044edc9c552daf5488628fd8e5be97","impliedFormat":99},{"version":"1d1c0e6bda55b6fdcc247c4abd1ba2a36b50aac71bbf78770cbd172713c4e05f","impliedFormat":99},{"version":"d7d8a5f6a306b755dfa5a9b101cb800fd912b256222fb7d4629b5de416b4b8d5","impliedFormat":99},{"version":"5585ed538922e2e58655218652dcb262f08afa902f26f490cdec4967887ac31a","impliedFormat":99},{"version":"b46de7238d9d2243b27a21797e4772ba91465caae9c31f21dc43748dc9de9cd0","impliedFormat":99},{"version":"625fdbce788630c62f793cb6c80e0072ce0b8bf1d4d0a9922430671164371e0b","impliedFormat":99},{"version":"b6790300d245377671c085e76e9ef359b3cbba6821b913d6ce6b2739d00b9fb1","impliedFormat":99},{"version":"6beaff23ae0b12aa3b7672c7fd4e924f5088efa899b58fe83c7cc5675234ff14","impliedFormat":99},{"version":"a36c717362d06d76e7332d9c1d2744c2c5e4b4a5da6218ef7b4a299a62d23a6d","impliedFormat":99},{"version":"a61f8455fd21cec75a8288cd761f5bcc72441848841eb64aa09569e9d8929ff0","impliedFormat":99},{"version":"7539c82be2eb9b83ec335b11bb06dc35497f0b7dab8830b2c08b650d62707160","impliedFormat":99},{"version":"0eaa77f9ed4c3eb8fac011066c987b6faa7c70db95cfe9e3fb434573e095c4c8","impliedFormat":99},{"version":"466e7296272b827c55b53a7858502de733733558966e2e3a7cc78274e930210a","impliedFormat":99},{"version":"364a5c527037fdd7d494ab0a97f510d3ceda30b8a4bc598b490c135f959ff3c6","impliedFormat":99},{"version":"d26c255888cc20d5ab7397cc267ad81c8d7e97624c442a218afec00949e7316e","impliedFormat":99},{"version":"83d2dab980f2d1a2fe333f0001de8f42c831a438159d47b77c686ae405891b7f","impliedFormat":99},{"version":"ca369bcbdafc423d1a9dccd69de98044534900ff8236d2dd970b52438afb5355","impliedFormat":99},{"version":"5b90280e84e8eba347caaefc18210de3ce6ac176f5e82705a28e7f497dcc8689","impliedFormat":99},{"version":"6fc2d85e6d20a566b97001ee9a74dacc18d801bc9e9b735988119036db992932","impliedFormat":99},{"version":"d57bf30bf951ca5ce0119fcce3810bd03205377d78f08dfe6fca9d350ce73edc","impliedFormat":99},{"version":"e7878d8cd1fd0d0f1c55dcd8f5539f4c22e44993852f588dd194bd666b230727","impliedFormat":99},{"version":"638575c7a309a595c5ac3a65f03a643438fd81bf378aac93eadb84461cdd247c","impliedFormat":99},{"version":"70eebdf8cb991b4b5a1bfd9540698012cf9b2f11d265f7349e2fb7b7cb82d07b","signature":"4c60eadea5f3da0a00a59d1d46e3c9e106da50e89df04f75bd88e81c2d3cb42d"},{"version":"7f729540963914f308742abcebd1c93cf6634ca85e4024177705d811301a09ab","signature":"9033c48366f3826f3e362190c39da048e43e4fe22b27eb7b3f5550d47c41dfec"},{"version":"416b476b4f4187ef6fe1e85748e4a1dc2bca269eb3625f13e89dfc1f6d069343","signature":"3b15c3c1cf162474caab21ab5c58f87b9253202ca07c9fa0756c92dee8401bf3"},"6e688d22344613c97ba38edc733ee214529c2e45d0267d32e89613ee4385de4e"],"root":[[116,119]],"options":{"composite":true,"declaration":true,"esModuleInterop":true,"module":1,"outDir":"./dist","rootDir":"./src","skipLibCheck":true,"strict":true,"target":99},"referencedMap":[[115,1],[86,2],[95,2],[87,2],[96,2],[88,2],[89,2],[103,2],[102,2],[104,2],[105,2],[97,2],[90,2],[98,2],[91,2],[99,2],[92,2],[94,2],[101,2],[100,2],[106,2],[93,2],[107,2],[112,2],[113,2],[108,2],[110,2],[109,2],[111,2],[117,3],[119,4]],"latestChangedDtsFile":"./dist/index.d.ts","version":"5.8.3"} \ No newline at end of file