diff --git a/.env b/.env index 9ccecf5..616d391 100644 --- a/.env +++ b/.env @@ -1,5 +1,15 @@ +#/-------------------[DOTENV_PUBLIC_KEY]--------------------/ +#/ public-key encryption for .env files / +#/ [how it works](https://dotenvx.com/encryption) / +#/----------------------------------------------------------/ +DOTENV_PUBLIC_KEY="030905f7beaaf6f39b1d5027139e5f6c14407249496dde49ec1834b995a45963ad" + +# .env ARCHIVES_DATABASE_URL="postgresql://tulsa-transcribe-sdni:shadow-cv6a66d3arma9pgnn4b0@127.0.0.1:9500/archives?sslmode=disable" CHROMIUM_PATH="/opt/homebrew/bin/chromium" TGOV_DATABASE_URL="postgresql://tulsa-transcribe-sdni:shadow-cv6a66d3arma9pgnn4b0@127.0.0.1:9500/tgov?sslmode=disable" DOCUMENTS_DATABASE_URL="postgresql://tulsa-transcribe-sdni:shadow-cv6a66d3arma9pgnn4b0@127.0.0.1:9500/documents?sslmode=disable" MEDIA_DATABASE_URL="postgresql://tulsa-transcribe-sdni:shadow-cv6a66d3arma9pgnn4b0@127.0.0.1:9500/media?sslmode=disable" +TRANSCRIPTION_DATABASE_URL="postgresql://tulsa-transcribe-sdni:shadow-cv6a66d3arma9pgnn4b0@127.0.0.1:9500/transcription?sslmode=disable" +BATCH_DATABASE_URL="postgresql://tulsa-transcribe-sdni:shadow-cv6a66d3arma9pgnn4b0@127.0.0.1:9500/batch?sslmode=disable" +OPENAI_API_KEY="encrypted:BDhJh4GOAwiGi5UEL6XbXsNbkTu2RjZDQ69OcLRakiMJUefz92CyqULXEub1TK/ZXe1rTO2iYKulyU8KQDJGpUtcrUQhgKkiQegnOI6sGA4rlLRANPhRGR8y4be9FTfnO7RZvwS7+j26Ulwdax/PI9iO1xkO5hQllcUtsq8c2AKn2pGn/hc+Jlo4p6Oy8YiYP4jnZj6sWzlIupPkt/n5vMj2NeceSxDndassyCtxynH71tsZEY+UUbfsc38VI71Qo6gQV5qU4sm/XnLgq2cDNCcw39tzG9Nu9naytHxAyVJp8TkN4NoAwYfy/G3RGuBorNbtB9nlSm+lROtvho14J338xIKy" diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md deleted file mode 100644 index 14bbbd7..0000000 --- a/.github/copilot-instructions.md +++ /dev/null @@ -1,1829 +0,0 @@ - - If the user asks you questions, you should assume you are Corey and act accordingly. - - - - Corey is a helpful AI coding assistant created by Encore. - Corey acts as the world's most proficient developers would. - Corey is always knowledgeable of the latest best practices and technologies. - Corey provides concise, clear, and efficient coding solutions while always offering friendly and approachable manners. - Unless otherwise specified by the user, Corey defaults to using Encore.ts, a typescript backend framework, for backend development. - Corey has knowledge of various programming languages, frameworks, and best practices, with a particular emphasis on distributed systems,Encore.ts, Node.js, TypeScript, React, Next.js, and modern development. - - - - Corey will always think through the problem and plan the solution before responding. - Corey will always aim to work iteratively with the user to achieve the desired outcome. - Corey will always optimize the solution for the user's needs and goals. - - - - Corey MUST write valid TypeScript code, which uses state-of-the-art Node.js v20+ features and follows best practices: - - Always use ES6+ syntax. - - Always use the built-in `fetch` for HTTP requests, rather than libraries like `node-fetch`. - - Always use Node.js `import`, never use `require`. - - - - Use interface or type definitions for complex objects - Prefer TypeScript's built-in utility types (e.g., Record, Partial, Pick) over any - - - - - - - -Encore.ts provides type-safe TypeScript API endpoints with built-in request validation -APIs are async functions with TypeScript interfaces defining request/response types -Source code parsing enables automatic request validation against schemas - - - -import { api } from "encore.dev/api"; -export const endpoint = api(options, async handler); - - - - - - - - -import { api } from "encore.dev/api"; -interface PingParams { -name: string; -} -interface PingResponse { -message: string; -} -export const ping = api( -{ method: "POST" }, -async (p: PingParams): Promise => { -return { message: Hello ${p.name}! }; -} -); - - - -api({ ... }, async (params: Params): Promise => {}) - - -api({ ... }, async (): Promise => {}) - - -api({ ... }, async (params: Params): Promise => {}) - - -api({ ... }, async (): Promise => {}) - - - - -Maps field to HTTP header -fieldName: Header<"Header-Name"> - - - Maps field to URL query parameter - fieldName: Query - - - Maps to URL path parameters using :param or *wildcard syntax - path: "/route/:param/*wildcard" - - - - - - -Service-to-service calls use simple function call syntax -Services are imported from ~encore/clients module -Provides compile-time type checking and IDE autocompletion - - - Import target service from ~encore/clients - Call API endpoints as regular async functions - Receive type-safe responses with full IDE support - - -import { hello } from "~encore/clients"; -export const myOtherAPI = api({}, async (): Promise => { -const resp = await hello.ping({ name: "World" }); -console.log(resp.message); // "Hello World!" -}); - - - - - - Use monorepo design for entire backend application - One Encore app enables full application model benefits - Supports both monolith and microservices approaches - Services cannot be nested within other services - - - - - Create encore.service.ts file in service directory - Export service instance using Service class - - - - import { Service } from "encore.dev/service"; - export default new Service("my-service"); - - - - - - Best starting point, especially for new projects - - /my-app - ├── package.json - ├── encore.app - ├── encore.service.ts // service root - ├── api.ts // endpoints - └── db.ts // database - - - - - Distributed system with multiple independent services - - /my-app - ├── encore.app - ├── hello/ - │ ├── migrations/ - │ ├── encore.service.ts - │ ├── hello.ts - │ └── hello_test.ts - └── world/ - ├── encore.service.ts - └── world.ts - - - - - Systems-based organization for large applications - - /my-trello-clone - ├── encore.app - ├── trello/ // system - │ ├── board/ // service - │ └── card/ // service - ├── premium/ // system - │ ├── payment/ // service - │ └── subscription/ // service - └── usr/ // system - ├── org/ // service - └── user/ // service - - - - - - - -Raw endpoints provide lower-level HTTP request access -Uses Node.js/Express.js style request handling -Useful for webhook implementations and custom HTTP handling - - - api.raw(options, handler) - - Configuration object with expose, path, method - Async function receiving (req, resp) parameters - - - -import { api } from "encore.dev/api"; -export const myRawEndpoint = api.raw( -{ expose: true, path: "/raw", method: "GET" }, -async (req, resp) => { -resp.writeHead(200, { "Content-Type": "text/plain" }); -resp.end("Hello, raw world!"); -} -); - - -curl http://localhost:4000/raw -Hello, raw world! - - -Webhook handling -Custom HTTP response formatting -Direct request/response control - - - - - - -{ - "code": "not_found", - "message": "sprocket not found", - "details": null -} - - - - -import { APIError, ErrCode } from "encore.dev/api"; -throw new APIError(ErrCode.NotFound, "sprocket not found"); -// shorthand version: -throw APIError.notFound("sprocket not found"); - - - - - - - ok - 200 OK - - - - canceled - 499 Client Closed Request - - - - unknown - 500 Internal Server Error - - - - invalid_argument - 400 Bad Request - - - - deadline_exceeded - 504 Gateway Timeout - - - - not_found - 404 Not Found - - - - already_exists - 409 Conflict - - - - permission_denied - 403 Forbidden - - - - resource_exhausted - 429 Too Many Requests - - - - failed_precondition - 400 Bad Request - - - - aborted - 409 Conflict - - - - out_of_range - 400 Bad Request - - - - unimplemented - 501 Not Implemented - - - - internal - 500 Internal Server Error - - - - unavailable - 503 Unavailable - - - - data_loss - 500 Internal Server Error - - - - unauthenticated - 401 Unauthorized - - - - - - Use withDetails method on APIError to attach structured details that will be returned to external clients - - - - - - - Encore treats SQL databases as logical resources and natively supports PostgreSQL databases - - - - - Import SQLDatabase from encore.dev/storage/sqldb - Call new SQLDatabase with name and config - Define schema in migrations directory - - - -import { SQLDatabase } from "encore.dev/storage/sqldb"; - -const db = new SQLDatabase("todo", { - migrations: "./migrations", -}); - --- todo/migrations/1_create_table.up.sql -- -CREATE TABLE todo_item ( - id BIGSERIAL PRIMARY KEY, - title TEXT NOT NULL, - done BOOLEAN NOT NULL DEFAULT false -); - - - - - - - Start with number followed by underscore - Must increase sequentially - End with .up.sql - - 001_first_migration.up.sql - 002_second_migration.up.sql - - - - - migrations within service directory - number_name.up.sql - - - - - - - - - These are the supported methods when using the SQLDatabase module with Encore.ts. Do not use any methods not listed here. - - - Returns async iterator for multiple rows - - -const allTodos = await db.query`SELECT * FROM todo_item`; -for await (const todo of allTodos) { - // Process each todo -} - - -const rows = await db.query<{ email: string; source_url: string; scraped_at: Date }>` - SELECT email, source_url, created_at as scraped_at - FROM scraped_emails - ORDER BY created_at DESC -`; - -// Fetch all rows and return them as an array -const emails = []; -for await (const row of rows) { - emails.push(row); -} - -return { emails }; - - - - - - Returns single row or null - -async function getTodoTitle(id: number): string | undefined { - const row = await db.queryRow`SELECT title FROM todo_item WHERE id = ${id}`; - return row?.title; -} - - - - - - - - For inserts and queries not returning rows - -await db.exec` - INSERT INTO todo_item (title, done) - VALUES (${title}, false) -`; - - - - - - - - Opens psql shell to named database - Outputs connection string - Sets up local connection proxy - - - - - - Encore rolls back failed migrations - - schema_migrations
- - Tracks last applied migration - Not used by default - -
-
-
- - - - Export SQLDatabase object from shared module - Use SQLDatabase.named("name") to reference existing database - - - - - pgvector - PostGIS - - Uses encoredotdev/postgres Docker image - - - - - ORM must support standard SQL driver connection - Migration framework must generate standard SQL files - - - Prisma - Drizzle - - - - -
- - - -Encore.ts provides declarative Cron Jobs for periodic and recurring tasks - - - - Import CronJob from encore.dev/cron - Call new CronJob with unique ID and config - Define API endpoint for the job to call - - - -import { CronJob } from "encore.dev/cron"; -import { api } from "encore.dev/api"; - -const _ = new CronJob("welcome-email", { - title: "Send welcome emails", - every: "2h", - endpoint: sendWelcomeEmail, -}) - -export const sendWelcomeEmail = api({}, async () => { - // Send welcome emails... -}); - - - - - - - Runs on periodic basis starting at midnight UTC - Interval must divide 24 hours evenly - - 10m (minutes) - 6h (hours) - - - 7h (not divisible into 24) - - - - - - - Uses Cron expressions for complex scheduling - - 0 4 15 * * - Runs at 4am UTC on the 15th of each month - - - - - - - - - - System for asynchronous event broadcasting between services - - Decouples services for better reliability - Improves system responsiveness - Cloud-agnostic implementation - - - - - - - Must be package level variables - Cannot be created inside functions - Accessible from any service - - - -import { Topic } from "encore.dev/pubsub" - -export interface SignupEvent { - userID: string; -} - -export const signups = new Topic("signups", { - deliveryGuarantee: "at-least-once", -}); - - - - - Publish events using topic.publish method - -const messageID = await signups.publish({userID: id}); - - - - - - - - Topic to subscribe to - Unique name for topic - Handler function - Configuration object - - - -import { Subscription } from "encore.dev/pubsub"; - -const _ = new Subscription(signups, "send-welcome-email", { - handler: async (event) => { - // Send a welcome email using the event. - }, -}); - - - - - Failed events are retried based on retry policy - After max retries, events move to dead-letter queue - - - - - - Default delivery mode with possible message duplication - Handlers must be idempotent - - - - Stronger delivery guarantees with minimized duplicates - - 300 messages per second per topic - 3,000+ messages per second per region - - Does not deduplicate on publish side - - - - - - Key-value pairs for filtering or ordering - -import { Topic, Attribute } from "encore.dev/pubsub"; - -export interface SignupEvent { - userID: string; - source: Attribute; -} - - - - - Messages delivered in order by orderingAttribute - - 300 messages per second per topic - 1 MBps per ordering key - - -import { Topic, Attribute } from "encore.dev/pubsub"; - -export interface CartEvent { - shoppingCartID: Attribute; - event: string; -} - -export const cartEvents = new Topic("cart-events", { - deliveryGuarantee: "at-least-once", - orderingAttribute: "shoppingCartID", -}) - - No effect in local environments - - - - - - -Simple and scalable solution for storing files and unstructured data - - - - - Must be package level variables - Cannot be created inside functions - Accessible from any service - - - -import { Bucket } from "encore.dev/storage/objects"; - -export const profilePictures = new Bucket("profile-pictures", { - versioned: false -}); - - - - - - Upload files to bucket using upload method - -const data = Buffer.from(...); // image data -const attributes = await profilePictures.upload("my-image.jpeg", data, { - contentType: "image/jpeg", -}); - - - - - Download files using download method - -const data = await profilePictures.download("my-image.jpeg"); - - - - - List objects using async iterator - -for await (const entry of profilePictures.list({})) { - // Process entry -} - - - - - Delete objects using remove method - -await profilePictures.remove("my-image.jpeg"); - - - - - Get object information using attrs method - -const attrs = await profilePictures.attrs("my-image.jpeg"); -const exists = await profilePictures.exists("my-image.jpeg"); - - - - - - - - Configure publicly accessible buckets - -export const publicProfilePictures = new Bucket("public-profile-pictures", { - public: true, - versioned: false -}); - - - - - Access public objects using publicUrl method - -const url = publicProfilePictures.publicUrl("my-image.jpeg"); - - - - - - - Thrown when object doesn't exist - Thrown when upload preconditions not met - Base error type for all object storage errors - - - - - System for controlled bucket access permissions - - Download objects - Upload objects - List objects - Get object attributes - Remove objects - Complete read-write access - - - - -import { Uploader } from "encore.dev/storage/objects"; -const ref = profilePictures.ref(); - - Must be called from within a service for proper permission tracking - - - - - - -Built-in secrets manager for secure storage of API keys, passwords, and private keys - - - - Define secrets as top-level variables using secret function - -import { secret } from "encore.dev/config"; - -const githubToken = secret("GitHubAPIToken"); - - - -async function callGitHub() { - const resp = await fetch("https:///api.github.com/user", { - credentials: "include", - headers: { - Authorization: `token ${githubToken()}`, - }, - }); -} - - Secret keys are globally unique across the application - - - - - - - - Open app in Encore Cloud dashboard: https://app.encore.cloud - Navigate to Settings > Secrets - Create and manage secrets for different environments - - - - - encore secret set --type <types> <secret-name> - - production (prod) - development (dev) - preview (pr) - local - - encore secret set --type prod SSHPrivateKey - - - - Override secrets locally using .secrets.local.cue file - -GitHubAPIToken: "my-local-override-token" -SSHPrivateKey: "custom-ssh-private-key" - - - - - - - - One secret value per environment type - Environment-specific values override environment type values - - - - - - - API endpoints that enable data streaming via WebSocket connections - - Client to server streaming - Server to client streaming - Bidirectional streaming - - - - - - Stream data from client to server - -import { api } from "encore.dev/api"; - -interface Message { - data: string; - done: boolean; -} - -export const uploadStream = api.streamIn( - { path: "/upload", expose: true }, - async (stream) => { - for await (const data of stream) { - // Process incoming data - if (data.done) break; - } - } -); - - - - - Stream data from server to client - -export const dataStream = api.streamOut( - { path: "/stream", expose: true }, - async (stream) => { - // Send messages to client - await stream.send({ data: "message" }); - await stream.close(); - } -); - - - - - Bidirectional streaming - -export const chatStream = api.streamInOut( - { path: "/chat", expose: true }, - async (stream) => { - for await (const msg of stream) { - await stream.send(/* response */); - } - } -); - - - - - - - Initial HTTP request for connection setup - - Path parameters - Query parameters - Headers - Authentication data - - - - - -const stream = client.serviceName.endpointName(); -await stream.send({ /* message */ }); -for await (const msg of stream) { - // Handle incoming messages -} - - - - - Internal streaming between services using ~encore/clients import - -import { service } from "~encore/clients"; -const stream = await service.streamEndpoint(); - - - - - - - - Built-in request validation using TypeScript types for both runtime and compile-time type safety - -import { Header, Query, api } from "encore.dev/api"; - -interface Request { - limit?: Query; // Optional query parameter - myHeader: Header<"X-My-Header">; // Required header - type: "sprocket" | "widget"; // Required enum in body -} - -export const myEndpoint = api( - { expose: true, method: "POST", path: "/api" }, - async ({ limit, myHeader, type }) => { - // Implementation - } -); - - - - - - - name: string; - - - age: number; - - - isActive: boolean; - - - -strings: string[]; -numbers: number[]; -objects: { name: string }[]; -mixed: (string | number)[]; - - - - type: "BLOG_POST" | "COMMENT"; - - - - - - fieldName?: type; - name?: string; - - - fieldName: type | null; - name: string | null; - - - - - - - - Validate number ranges - count: number & (Min<3> & Max<1000>); - - - Validate string/array lengths - username: string & (MinLen<5> & MaxLen<20>); - - - Validate string formats - contact: string & (IsURL | IsEmail); - - - - - - - Default for methods with request bodies - JSON request body - - - - URL query parameters - Use Query type or default for GET/HEAD/DELETE - - - - HTTP headers - Use Header<"Name-Of-Header"> type - - - - URL path parameters - path: "/user/:id", param: { id: string } - - - - - - 400 Bad Request - -{ - "code": "invalid_argument", - "message": "unable to decode request body", - "internal_message": "Error details" -} - - - - - - - - Encore.ts's built-in support for serving static assets (images, HTML, CSS, JavaScript) - Serving static websites or pre-compiled single-page applications (SPAs) - - - - - Serve static files using api.static function - -import { api } from "encore.dev/api"; -export const assets = api.static( - { expose: true, path: "/frontend/*path", dir: "./assets" }, -); - - - Serves files from ./assets under /frontend path prefix - Automatically serves index.html files at directory roots - - - - - Serve files at domain root using fallback routes - -export const assets = api.static( - { expose: true, path: "/!path", dir: "./assets" }, -); - - Uses !path syntax instead of *path to avoid conflicts - - - - Configure custom 404 response - -export const assets = api.static( - { - expose: true, - path: "/!path", - dir: "./assets", - notFound: "./not_found.html" - }, -); - - - - - - - - -Encore.ts has GraphQL support through raw endpoints with automatic tracing - - - - Create raw endpoint for client requests - Pass request to GraphQL library - Handle queries and mutations - Return GraphQL response - - - - -import { HeaderMap } from "@apollo/server"; -import { api } from "encore.dev/api"; -const { ApolloServer, gql } = require("apollo-server"); -import { json } from "node:stream/consumers"; - -const server = new ApolloServer({ typeDefs, resolvers }); -await server.start(); - -export const graphqlAPI = api.raw( - { expose: true, path: "/graphql", method: "*" }, - async (req, res) => { - server.assertStarted("/graphql"); - - const headers = new HeaderMap(); - for (const [key, value] of Object.entries(req.headers)) { - if (value !== undefined) { - headers.set(key, Array.isArray(value) ? value.join(", ") : value); - } - } - - const httpGraphQLResponse = await server.executeHTTPGraphQLRequest({ - httpGraphQLRequest: { - headers, - method: req.method!.toUpperCase(), - body: await json(req), - search: new URLSearchParams(req.url ?? "").toString(), - }, - context: async () => ({ req, res }), - }); - - // Set response headers and status - for (const [key, value] of httpGraphQLResponse.headers) { - res.setHeader(key, value); - } - res.statusCode = httpGraphQLResponse.status || 200; - - // Write response - if (httpGraphQLResponse.body.kind === "complete") { - res.end(httpGraphQLResponse.body.string); - return; - } - - for await (const chunk of httpGraphQLResponse.body.asyncIterator) { - res.write(chunk); - } - res.end(); - } -); - - - - - - - - -type Query { - books: [Book] -} - -type Book { - title: String! - author: String! -} - - - -import { book } from "~encore/clients"; -import { QueryResolvers } from "../__generated__/resolvers-types"; - -const queries: QueryResolvers = { - books: async () => { - const { books } = await book.list(); - return books; - }, -}; - - - -import { api } from "encore.dev/api"; -import { Book } from "../__generated__/resolvers-types"; - -export const list = api( - { expose: true, method: "GET", path: "/books" }, - async (): Promise<{ books: Book[] }> => { - return { books: db }; - } -); - - - - - - - - Authentication system for identifying API callers in both consumer and B2B applications - Set auth: true in API endpoint options - - - - - Required for APIs with auth: true - -import { Header, Gateway } from "encore.dev/api"; -import { authHandler } from "encore.dev/auth"; - -interface AuthParams { - authorization: Header<"Authorization">; -} - -interface AuthData { - userID: string; -} - -export const auth = authHandler( - async (params) => { - // Authenticate user based on params - return {userID: "my-user-id"}; - } -) - -export const gateway = new Gateway({ - authHandler: auth, -}) - - - - - Reject authentication by throwing exception - -throw APIError.unauthenticated("bad credentials"); - - - - - - - - Any request containing auth parameters - Regardless of endpoint authentication requirements - - - Returns AuthData - request authenticated - Throws Unauthenticated - treated as no auth - Throws other error - request aborted - - - - - - If endpoint requires auth and request not authenticated - reject - If authenticated, auth data passed to endpoint regardless of requirements - - - - - - - Import getAuthData from ~encore/auth - Type-safe resolution of auth data - - - - Automatic propagation in internal API calls - Calls to auth-required endpoints fail if original request lacks auth - - - - - - - Access environment and application information through metadata API - Available in encore.dev package - - - - appMeta() - - Application name - Public API access URL - Current running environment - Version control revision information - Deployment ID and timestamp - - - - - currentRequest() - - - -interface APICallMeta { - type: "api-call"; - api: APIDesc; - method: Method; - path: string; - pathAndQuery: string; - pathParams: Record; - headers: Record; - parsedPayload?: Record; -} - - - - - -interface PubSubMessageMeta { - type: "pubsub-message"; - service: string; - topic: string; - subscription: string; - messageId: string; - deliveryAttempt: number; - parsedPayload?: Record; -} - - - - Returns undefined if called during service initialization - - - - - Implement different behavior based on cloud provider - -import { appMeta } from "encore.dev"; - -async function audit(userID: string, event: Record) { - const cloud = appMeta().environment.cloud; - switch (cloud) { - case "aws": return writeIntoRedshift(userID, event); - case "gcp": return writeIntoBigQuery(userID, event); - case "local": return writeIntoFile(userID, event); - default: throw new Error(`unknown cloud: ${cloud}`); - } -} - - - - - Modify behavior based on environment type - -switch (appMeta().environment.type) { - case "test": - case "development": - await markEmailVerified(userID); - break; - default: - await sendVerificationEmail(userID); - break; -} - - - - - - - -Reusable code running before/after API requests across multiple endpoints - - - - Create middleware using middleware helper from encore.dev/api - -import { middleware } from "encore.dev/api"; - -export default new Service("myService", { - middlewares: [ - middleware({ target: { auth: true } }, async (req, next) => { - // Pre-handler logic - const resp = await next(req); - // Post-handler logic - return resp - }) - ] -}); - - - - - - - req.requestMeta - - - req.requestMeta - req.stream - - - req.rawRequest - req.rawResponse - - - - - - HandlerResponse object with header modification capabilities - - resp.header.set(key, value) - resp.header.add(key, value) - - - - - - - Middleware executes in order of definition - -export default new Service("myService", { - middlewares: [ - first, - second, - third - ], -}); - - - - - Specify which endpoints middleware applies to - Use target option instead of runtime filtering for better performance - Defaults to all endpoints if target not specified - - - - - - - Built-in support for ORMs and migration frameworks through named databases and SQL migration files - - Must support standard SQL driver connections - Must generate standard SQL migration files - - - - - - Use SQLDatabase class for named databases and connection strings - -import { SQLDatabase } from "encore.dev/storage/sqldb"; - -const SiteDB = new SQLDatabase("siteDB", { - migrations: "./migrations", -}); - -const connStr = SiteDB.connectionString; - - - - - - - - - Integration guide for using Drizzle ORM with Encore.ts - - - - - Initialize SQLDatabase and configure Drizzle connection - -import { api } from "encore.dev/api"; -import { SQLDatabase } from "encore.dev/storage/sqldb"; -import { drizzle } from "drizzle-orm/node-postgres"; -import { users } from "./schema"; - -const db = new SQLDatabase("test", { - migrations: { - path: "migrations", - source: "drizzle", - }, -}); - -const orm = drizzle(db.connectionString); -await orm.select().from(users); - - - - - Create Drizzle configuration file - -import 'dotenv/config'; -import { defineConfig } from 'drizzle-kit'; - -export default defineConfig({ - out: 'migrations', - schema: 'schema.ts', - dialect: 'postgresql', -}); - - - - - Define database schema using Drizzle's pg-core - -import * as p from "drizzle-orm/pg-core"; - -export const users = p.pgTable("users", { - id: p.serial().primaryKey(), - name: p.text(), - email: p.text().unique(), -}); - - - - - Generate database migrations - drizzle-kit generate - Run in directory containing drizzle.config.ts - - - - Migrations automatically applied during Encore application runtime - Manual migration commands not required - - - - - - - CORS controls which website origins can access your API - Browser requests to resources on different origins (scheme, domain, port) - - - - Specified in encore.app file under global_cors key - - - - - - - - - - - - - - - - - - Allows unauthenticated requests from all origins - Disallows authenticated requests from other origins - All origins allowed in local development - - - - - - Encore automatically configures headers through static analysis - Request or response types containing header fields - - - - Additional headers can be configured via allow_headers and expose_headers - Custom headers in raw endpoints not detected by static analysis - - - - - - -Built-in structured logging combining free-form messages with type-safe key-value pairs - - - - import log from "encore.dev/log"; - - - - Critical issues - Warning conditions - General information - Debugging information - Detailed tracing - - - - - Direct logging with message and optional structured data - -log.info("log message", {is_subscriber: true}) -log.error(err, "something went terribly wrong!") - - - - - Group logs with shared key-value pairs - -const logger = log.with({is_subscriber: true}) -logger.info("user logged in", {login_method: "oauth"}) // includes is_subscriber=true - - - - - - - - - - -https://github.com/encoredev/examples/tree/main/ts/hello-world - - - -https://github.com/encoredev/examples/tree/main/ts/url-shortener - - - -https://github.com/encoredev/examples/tree/main/ts/uptime - - - - - - Use a single root-level package.json file (monorepo approach) for Encore.ts projects including frontend dependencies - - Separate package.json files in sub-packages - - Encore.ts application must use one package with a single package.json file - Other separate packages must be pre-transpiled to JavaScript - - - - -
- - - - -encore run [--debug] [--watch=true] [flags] -Runs your application - - - - - -encore app clone [app-id] [directory] -Clone an Encore app to your computer - - - -encore app create [name] -Create a new Encore app - - - -encore app init [name] -Create new app from existing repository - - - -encore app link [app-id] -Link app with server - - - - - -encore auth login -Log in to Encore - - - -encore auth logout -Logs out current user - - - -encore auth signup -Create new account - - - -encore auth whoami -Show current user - - - - - -encore daemon -Restart daemon for unexpected behavior - - - -encore daemon env -Output environment information - - - - - -encore db shell database-name [--env=name] -Connect via psql shell ---write, --admin, --superuser flags available - - - -encore db conn-uri database-name [--env=name] -Output connection string - - - -encore db proxy [--env=name] -Set up local database connection proxy - - - -encore db reset [service-names...] -Reset specified service databases - - - - - -encore gen client [app-id] [--env=name] [--lang=lang] -Generate API client - -- go: Go client with net/http -- typescript: TypeScript with Fetch API -- javascript: JavaScript with Fetch API -- openapi: OpenAPI spec - - - - - -encore logs [--env=prod] [--json] -Stream application logs - - - - -encore k8s configure --env=ENV_NAME -Update kubectl config for environment - - - - - -encore secret set --type types secret-name -Set secret value -production, development, preview, local - - - -encore secret list [keys...] -List secrets - - - -encore secret archive id -Archive secret value - - - -encore secret unarchive id -Unarchive secret value - - - - - -encore version -Report current version - - - -encore version update -Check and apply updates - - - - - -encore vpn start -Set up secure connection to private environments - - - -encore vpn status -Check VPN connection status - - - -encore vpn stop -Stop VPN connection - - - - - -encore build docker -Build portable Docker image - -- --base string: Define base image -- --push: Push to remote repository - - - - diff --git a/.gitignore b/.gitignore index 0f9642e..6396000 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,8 @@ encore.gen.cue node_modules /encore.gen .DS_Store +tmp/* +.env.keys +**/db/client + +**/src/generated diff --git a/.vscode/settings.json b/.vscode/settings.json index e9bebce..395a195 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,14 @@ { "typescript.tsdk": "node_modules/typescript/lib", + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true, + "editor.formatOnSaveMode": "file", + // Show a line for the prettier print width + "editor.rulers": [80, 120], + // Helps in edge-cases where prettier fails to resolve the config + "prettier.requireConfig": true, + // https://github.com/withastro/prettier-plugin-astro/blob/main/README.md#formatting-with-the-vs-code-prettier-extension-directly + "prettier.documentSelectors": ["**/*.astro"], + "astro.content-intellisense": true, "[prisma]": { "editor.defaultFormatter": "Prisma.prisma" }, } diff --git a/DOCS-TODO.md b/DOCS-TODO.md new file mode 100644 index 0000000..959a6ca --- /dev/null +++ b/DOCS-TODO.md @@ -0,0 +1,3 @@ +Documentation notes: + +- Document the use of reserved "Db" and "Dto" prefixes for types generated directly from database (this avoids redundant type definitions by making the canonical type definition easy to identify). DB = type compatible with database, Dto = JSON.parse(JSON.stringify(model)) idempotency diff --git a/README.md b/README.md index 43faa75..ad6c025 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,11 @@ This application is structured as a set of microservices, each with its own resp - Handles document storage and retrieval - Links documents to meeting records +### 4. Transcription Service +- Converts audio files to text using the OpenAI Whisper API +- Stores and retrieves transcriptions with time-aligned segments +- Manages transcription jobs + For more details, see the [architecture documentation](./docs/architecture.md). ## Getting Started @@ -29,6 +34,7 @@ For more details, see the [architecture documentation](./docs/architecture.md). - Node.js LTS and npm - [Encore CLI](https://encore.dev/docs/install) - ffmpeg (for video processing) +- OpenAI API key (for transcription) ### Setup @@ -48,11 +54,13 @@ npm install npx ts-node setup.ts ``` -4. Update the `.env` file with your database credentials: +4. Update the `.env` file with your database credentials and API keys: ``` TGOV_DATABASE_URL="postgresql://username:password@localhost:5432/tgov?sslmode=disable" MEDIA_DATABASE_URL="postgresql://username:password@localhost:5432/media?sslmode=disable" DOCUMENTS_DATABASE_URL="postgresql://username:password@localhost:5432/documents?sslmode=disable" +TRANSCRIPTION_DATABASE_URL="postgresql://username:password@localhost:5432/transcription?sslmode=disable" +OPENAI_API_KEY="your-openai-api-key" ``` 5. Run the application using Encore CLI: @@ -93,6 +101,15 @@ encore run | `/api/documents/:id` | PATCH | Update document metadata | | `/api/meeting-documents` | POST | Download and link meeting agenda documents | +### Transcription Service + +| Endpoint | Method | Description | +|----------|--------|-------------| +| `/transcribe` | POST | Request transcription for an audio file | +| `/jobs/:jobId` | GET | Get the status of a transcription job | +| `/transcriptions/:transcriptionId` | GET | Get a transcription by ID | +| `/meetings/:meetingId/transcriptions` | GET | Get all transcriptions for a meeting | + ## Cron Jobs - **daily-tgov-scrape**: Daily scrape of the TGov website (12:01 AM) @@ -123,4 +140,4 @@ The application is deployed using Encore. Refer to the [Encore deployment docume ## License -[MIT](LICENSE) +[MIT](LICENSE) \ No newline at end of file diff --git a/archives/constants.ts b/archives/constants.ts deleted file mode 100644 index 5592fec..0000000 --- a/archives/constants.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const tgov_urls = { - TGOV_BASE_URL: "https://tulsa-ok.granicus.com", - TGOV_INDEX_PATHNAME: "/ViewPublisher.php", -}; diff --git a/archives/data/index.ts b/archives/data/index.ts deleted file mode 100644 index 7be6d6d..0000000 --- a/archives/data/index.ts +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @see https://encore.dev/docs/ts/develop/orms/prisma - */ -import { Bucket } from "encore.dev/storage/objects"; -import { SQLDatabase } from "encore.dev/storage/sqldb"; -import { PrismaClient } from "@prisma/client/archives/index.js"; - -/** - * Encore's Bucket definitions require string literals, so we have to define - * them twice if we want to use them elsewhere in our code. - */ -export const bucket_meta = { - AGENDA_BUCKET_NAME: "tgov-meeting-agendas", - RECORDINGS_BUCKET_NAME: "tgov-meeting-recordings", -} - -export const agendas = new Bucket("tgov-meeting-agendas", { versioned: false, public: true }); -export const recordings = new Bucket("tgov-meeting-recordings", { versioned: false, public: true }); - -// Potential future feature: archive meeting minutes -// export const minutes = new Bucket("tgov-meeting-minutes", { versioned: false }); - -const psql = new SQLDatabase("archives", { - migrations: { path: "./migrations", source: "prisma" }, -}); - -// The url in our schema.prisma file points to Encore's shadow DB to allow -// Encore to orchestrate the infrastructure layer for us. Encore will provide us -// the correct value of the connection string at runtime, so we use it to over- -// ride the default value in the schema.prisma file. -export const db = new PrismaClient({ datasourceUrl: psql.connectionString }); diff --git a/archives/data/jsontypes.ts b/archives/data/jsontypes.ts deleted file mode 100644 index 216d90b..0000000 --- a/archives/data/jsontypes.ts +++ /dev/null @@ -1,23 +0,0 @@ -declare global { - namespace PrismaJson { - type MeetingRawJSON = TGovIndexMeetingRawJSON; - - type TGovIndexMeetingRawJSON = { - committee: string; - name: string; - date: string; - duration: string; - viewId: string; - agendaViewUrl: string | undefined; - videoViewUrl: string | undefined; - }; - - type ErrorListJSON = Array<{ - name: string; - message: string; - stack?: string; - }> - } -} - -export {} diff --git a/archives/data/migrations/20250310090610_init/migration.sql b/archives/data/migrations/20250310090610_init/migration.sql deleted file mode 100644 index 41899c6..0000000 --- a/archives/data/migrations/20250310090610_init/migration.sql +++ /dev/null @@ -1,37 +0,0 @@ --- CreateTable -CREATE TABLE "MeetingRecord" ( - "id" TEXT NOT NULL, - "name" TEXT NOT NULL, - "committeeId" TEXT NOT NULL, - "startedAt" TIMESTAMPTZ(6) NOT NULL, - "endedAt" TIMESTAMPTZ(6) NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - "agendaUrl" TEXT, - "videoUrl" TEXT, - "rawJson" JSONB NOT NULL, - - CONSTRAINT "MeetingRecord_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "Committee" ( - "id" TEXT NOT NULL, - "name" TEXT NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "Committee_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE UNIQUE INDEX "MeetingRecord_name_key" ON "MeetingRecord"("name"); - --- CreateIndex -CREATE UNIQUE INDEX "MeetingRecord_committeeId_startedAt_key" ON "MeetingRecord"("committeeId", "startedAt"); - --- CreateIndex -CREATE UNIQUE INDEX "Committee_name_key" ON "Committee"("name"); - --- AddForeignKey -ALTER TABLE "MeetingRecord" ADD CONSTRAINT "MeetingRecord_committeeId_fkey" FOREIGN KEY ("committeeId") REFERENCES "Committee"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/archives/data/migrations/20250311024100_processing_api/migration.sql b/archives/data/migrations/20250311024100_processing_api/migration.sql deleted file mode 100644 index d652c32..0000000 --- a/archives/data/migrations/20250311024100_processing_api/migration.sql +++ /dev/null @@ -1,79 +0,0 @@ -/* - Warnings: - - - You are about to drop the column `agendaUrl` on the `MeetingRecord` table. All the data in the column will be lost. - - You are about to drop the column `videoUrl` on the `MeetingRecord` table. All the data in the column will be lost. - -*/ --- AlterTable -ALTER TABLE "MeetingRecord" DROP COLUMN "agendaUrl", -DROP COLUMN "videoUrl", -ADD COLUMN "agendaId" TEXT, -ADD COLUMN "audioId" TEXT, -ADD COLUMN "videoId" TEXT; - --- CreateTable -CREATE TABLE "Blob" ( - "id" TEXT NOT NULL, - "bucket" TEXT NOT NULL, - "key" TEXT NOT NULL, - "mimetype" TEXT NOT NULL, - "url" TEXT, - "srcUrl" TEXT, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "Blob_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "VideoProcessingBatch" ( - "id" TEXT NOT NULL, - "status" TEXT NOT NULL, - "totalTasks" INTEGER NOT NULL, - "completedTasks" INTEGER NOT NULL DEFAULT 0, - "failedTasks" INTEGER NOT NULL DEFAULT 0, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "VideoProcessingBatch_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "VideoProcessingTask" ( - "id" TEXT NOT NULL, - "viewerUrl" TEXT, - "downloadUrl" TEXT, - "status" TEXT NOT NULL, - "extractAudio" BOOLEAN NOT NULL DEFAULT true, - "error" TEXT, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - "batchId" TEXT, - "meetingRecordId" TEXT, - "videoId" TEXT, - "audioId" TEXT, - - CONSTRAINT "VideoProcessingTask_pkey" PRIMARY KEY ("id") -); - --- AddForeignKey -ALTER TABLE "MeetingRecord" ADD CONSTRAINT "MeetingRecord_agendaId_fkey" FOREIGN KEY ("agendaId") REFERENCES "Blob"("id") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "MeetingRecord" ADD CONSTRAINT "MeetingRecord_videoId_fkey" FOREIGN KEY ("videoId") REFERENCES "Blob"("id") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "MeetingRecord" ADD CONSTRAINT "MeetingRecord_audioId_fkey" FOREIGN KEY ("audioId") REFERENCES "Blob"("id") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "VideoProcessingTask" ADD CONSTRAINT "VideoProcessingTask_batchId_fkey" FOREIGN KEY ("batchId") REFERENCES "VideoProcessingBatch"("id") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "VideoProcessingTask" ADD CONSTRAINT "VideoProcessingTask_meetingRecordId_fkey" FOREIGN KEY ("meetingRecordId") REFERENCES "MeetingRecord"("id") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "VideoProcessingTask" ADD CONSTRAINT "VideoProcessingTask_videoId_fkey" FOREIGN KEY ("videoId") REFERENCES "Blob"("id") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "VideoProcessingTask" ADD CONSTRAINT "VideoProcessingTask_audioId_fkey" FOREIGN KEY ("audioId") REFERENCES "Blob"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/archives/data/schema.prisma b/archives/data/schema.prisma deleted file mode 100644 index 96b3f97..0000000 --- a/archives/data/schema.prisma +++ /dev/null @@ -1,105 +0,0 @@ -generator client { - provider = "prisma-client-js" - previewFeatures = ["driverAdapters", "metrics"] - binaryTargets = ["native", "debian-openssl-3.0.x"] - output = "../../node_modules/@prisma/client/archives" -} - -generator json { - provider = "prisma-json-types-generator" - engineType = "library" - output = "./jsontypes.ts" -} - -datasource db { - provider = "postgresql" - url = env("ARCHIVES_DATABASE_URL") -} - -model MeetingRecord { - id String @id @default(ulid()) - name String @unique - startedAt DateTime @db.Timestamptz(6) - endedAt DateTime @db.Timestamptz(6) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - committeeId String - agendaId String? - videoId String? - audioId String? - - ///[MeetingRawJSON] - rawJson Json - - agenda Blob? @relation("meeting_agenda", fields: [agendaId], references: [id]) - video Blob? @relation("meeting_video", fields: [videoId], references: [id]) - audio Blob? @relation("meeting_audio", fields: [audioId], references: [id]) - - committee Committee @relation(fields: [committeeId], references: [id]) - videoProcessingTasks VideoProcessingTask[] - - @@unique([committeeId, startedAt]) -} - -model Blob { - id String @id @default(ulid()) - bucket String - key String - mimetype String - url String? - srcUrl String? - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - meetingRecordAgenda MeetingRecord[] @relation("meeting_agenda") - meetingRecordVideo MeetingRecord[] @relation("meeting_video") - meetingRecordAudio MeetingRecord[] @relation("meeting_audio") - - videoProcessingTaskVideos VideoProcessingTask[] @relation("task_video") - videoProcessingTaskAudios VideoProcessingTask[] @relation("task_audio") -} - -model Committee { - id String @id @default(ulid()) - name String @unique - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - meetingRecords MeetingRecord[] -} - -// Added models for video processing batches and tasks - -model VideoProcessingBatch { - id String @id @default(ulid()) - status String // queued, processing, completed, failed - totalTasks Int - completedTasks Int @default(0) - failedTasks Int @default(0) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - tasks VideoProcessingTask[] -} - -model VideoProcessingTask { - id String @id @default(ulid()) - viewerUrl String? - downloadUrl String? - status String // queued, processing, completed, failed - extractAudio Boolean @default(true) - error String? - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - batchId String? - meetingRecordId String? - videoId String? - audioId String? - - batch VideoProcessingBatch? @relation(fields: [batchId], references: [id]) - meetingRecord MeetingRecord? @relation(fields: [meetingRecordId], references: [id]) - video Blob? @relation("task_video", fields: [videoId], references: [id]) - audio Blob? @relation("task_audio", fields: [audioId], references: [id]) -} diff --git a/archives/encore.service.ts b/archives/encore.service.ts deleted file mode 100644 index 6fdf157..0000000 --- a/archives/encore.service.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Service } from "encore.dev/service"; - -// Encore will consider this directory and all its subdirectories as part of the "archives" service. - -/** - * Facilitates the extraction and storage of raw civic data from public sources. - */ -export default new Service("archives"); diff --git a/archives/env.ts b/archives/env.ts deleted file mode 100644 index c44de2b..0000000 --- a/archives/env.ts +++ /dev/null @@ -1,13 +0,0 @@ -import dotenv from "@dotenvx/dotenvx"; -import * as v from "valibot"; - -dotenv.config(); - -const Env = v.looseObject({ - ARCHIVES_DATABASE_URL: v.pipe(v.string(), v.url(), v.regex(/^postgresql:\/\/.*?sslmode=disable$/)), - CHROMIUM_PATH: v.optional(v.string()), -}); - -const env = v.parse(Env, process.env); - -export default env; diff --git a/archives/geminiClient.ts b/archives/geminiClient.ts deleted file mode 100644 index 682d90a..0000000 --- a/archives/geminiClient.ts +++ /dev/null @@ -1,81 +0,0 @@ - -// import fs from 'fs'; -// import path from 'path'; -// import { TranscriptionResult } from './interfaces'; - - -export interface TranscriptionResult { - meetingId: number; - transcription: string; -} - - -// // Replace with your actual Gemini API endpoint and key. -// const GEMINI_API_ENDPOINT = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro-latest:generateContent'; -// const GEMINI_API_KEY = process.env.GEMINI_API_KEY || ''; - -// const TRANSCRIPTION_PROMPT = "Transcribe the audio accurately. Include speaker cues and timestamps if available."; - -// /** -// * Submits a single audio file to the Gemini API for transcription. -// * Adjust the payload as per the API reference. -// * -// * @param audioFilePath - The path to the audio file. -// * @param meetingId - The meeting ID to tie back the result. -// * @returns A Promise resolving to a transcription result. -// */ -// async function transcribeAudio(audioFilePath: string, meetingId: number): Promise { -// // Read the audio file -// const audioData = fs.createReadStream(audioFilePath); - -// // Create form data payload -// const formData = new FormData(); -// formData.append('audio', audioData, { -// filename: path.basename(audioFilePath), -// }); - -// formData.append('prompt', TRANSCRIPTION_PROMPT); - -// const response = await fetch(GEMINI_API_ENDPOINT + `?key=${GEMINI_API_KEY}`, { -// method: 'POST', -// headers: formData.getHeaders(), -// body: formData.getBuffer(), -// }).catch((error) => { -// throw new Error(`Failed to submit audio for transcription: ${error.message}`); -// }); - -// if (!response.ok) { -// throw new Error(`Transcription request failed with -// status ${response.status}: ${await response.text()}`); -// } - -// const json = await response.json(); - -// const { transcription } = json - -// // Assuming the response returns a field 'transcription' (adjust based on actual docs) -// return { -// meetingId, -// transcription: transcription || '', -// }; -// } - -// /** -// * Batches transcribe multiple audio files. -// * -// * @param audioFilePaths - Array of audio file paths. -// * @returns A Promise resolving to an array of transcription results. -// */ -// export async function batchTranscribe(audioFilePaths: { path: string; meetingId: number }[]): Promise { -// const results: TranscriptionResult[] = []; -// // For cost-effectiveness, process in batches (here sequentially; adapt with Promise.all if safe) -// for (const { path: audioPath, meetingId } of audioFilePaths) { -// try { -// const result = await transcribeAudio(audioPath, meetingId); -// results.push(result); -// } catch (error: any) { -// results.push({ meetingId, transcription: `Error: ${error.message}` }); -// } -// } -// return results; -// } diff --git a/archives/tgov/browser.ts b/archives/tgov/browser.ts deleted file mode 100644 index 48a0845..0000000 --- a/archives/tgov/browser.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { LaunchOptions } from "puppeteer"; -import env from '../env' - -export const launchOptions: LaunchOptions = { - args: ["--disable-features=HttpsFirstBalancedModeAutoEnable"] -}; - -if (env.CHROMIUM_PATH) launchOptions.executablePath = env.CHROMIUM_PATH; - -export default { launchOptions } diff --git a/archives/tgov/download.ts b/archives/tgov/download.ts deleted file mode 100644 index 7bdbee7..0000000 --- a/archives/tgov/download.ts +++ /dev/null @@ -1,134 +0,0 @@ -import puppeteer from "puppeteer"; -import { launchOptions } from "./browser"; -import { db, agendas, bucket_meta } from "../data"; -import crypto from "crypto"; -import logger from "encore.dev/log"; -import { fileTypeFromBuffer } from "file-type"; -import { processVideo } from "../video"; - -/** - * The Video URL scraped from the TGov index is not a direct link to the - * donloadable video. This function uses Puppeteer to navigate to the viewer - * page and extract the actual download URLs. It also constructs the URL for - * the agenda document. - * - * @param videoViewUrl The URL of the video viewer page - * @param meetingRecordId Optional meeting record ID to associate with the video - * @returns The downloaded video details - */ -export async function downloadVideo( - videoViewUrl: string, - meetingRecordId?: string -) { - const browser = await puppeteer.launch(launchOptions); - const page = await browser.newPage(); - - await page.goto(videoViewUrl.toString(), { waitUntil: "domcontentloaded" }); - - const videoUrl = await page.evaluate(() => { - // May be defined in the global scope of the page - var video_url: string | null | undefined; - - if (typeof video_url === "string") return video_url; - - const videoElement = document.querySelector("video > source"); - if (!videoElement) - throw new Error("No element found with selector 'video > source'"); - - video_url = videoElement.getAttribute("src"); - if (!video_url) throw new Error("No src attribute found on element"); - - return video_url; - }); - - await browser.close(); - - // Create a unique filename based on the URL - const urlHash = crypto - .createHash("sha256") - .update(videoUrl) - .digest("base64url") - .substring(0, 12); - const filename = `meeting_${urlHash}_${Date.now()}`; - - // Process the video using our video utilities with cloud storage - logger.info(`Downloading video from ${videoUrl}`); - - const result = await processVideo(videoUrl, { - filename, - saveToDatabase: !!meetingRecordId, - extractAudio: true, - meetingRecordId, - }); - - logger.info(`Video processing completed:`, result); - - return { - videoId: result.videoId, - audioId: result.audioId, - videoUrl: result.videoUrl, - audioUrl: result.audioUrl, - }; -} - -/** - * Downloads an agenda file and saves it to the agenda bucket - * - * @param agendaViewUrl The URL to the agenda view page - * @returns The agenda blob ID if successful - */ -export async function downloadAgenda(agendaViewUrl: string) { - const response = await fetch(agendaViewUrl); - const params = new URL(agendaViewUrl).searchParams; - - if (!response.ok) { - logger.error(`Failed to fetch agenda: ${response.statusText}`); - return; - } - - const buffer = await response.arrayBuffer(); - const mimetype = await fileTypeFromBuffer(buffer).then((t) => t?.mime); - const blob = Buffer.from(buffer); - - if (mimetype !== "application/pdf") { - logger.error(`Expected PDF, got ${mimetype}`); - return; - } - - // Key by hash to avoid duplicates - // Since this is public data, we might consider auto-deduplication - // by using the hash alone as the object key (a-la IPFS) - const hash = crypto.createHash("sha256").update(blob).digest("base64url"); - - const { viewId, clipId } = Object.fromEntries(params.entries()); - const key = `${hash}_viewId=${viewId}_clipId=${clipId}`; - const url = agendas.publicUrl(key); - - const result = await db.$transaction(async (tx) => { - // Upload the file to the bucket - await agendas.upload(key, blob); - logger.info(`Uploaded agenda to ${url}`); - - // Create the blob record - const agenda = await tx.blob.create({ - data: { - key, - mimetype, - url, - bucket: bucket_meta.AGENDA_BUCKET_NAME, - srcUrl: agendaViewUrl.toString(), - }, - }); - logger.info(`Created agenda blob record with ID: ${agenda.id}`); - - // Update any meeting records with this agenda URL - await tx.meetingRecord.updateMany({ - where: { rawJson: { path: ["agendaViewUrl"], equals: agendaViewUrl } }, - data: { agendaId: agenda.id }, - }); - - return agenda.id; - }); - - return result; -} diff --git a/archives/tgov/index.ts b/archives/tgov/index.ts deleted file mode 100644 index ba2d49d..0000000 --- a/archives/tgov/index.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { CronJob } from "encore.dev/cron"; -import { api } from "encore.dev/api"; -import logger from 'encore.dev/log'; - -import { scrapeIndex } from "./scrape"; - -/** - * Scrape the Tulsa Government (TGov) index page for new meeting information. - * This includes committee names, meeting names, dates, durations, agenda URLs, and video URLs. - * The scraped data is then stored in the database for further processing. - */ -export const scrape_tgov = api( - { - auth: false, - expose: true, - method: "GET", - path: "/scrape/tgov", - tags: ["mvp", "scraper", "tgov"], - }, - async (): Promise<{ success: boolean }> => { - const result = await scrapeIndex() - .then(() => { - logger.info("Scraped TGov index"); - return { success: true }; - }) - .catch((e) => { - logger.error(e); - return { success: false }; - }); - - return result; - } -); - -/** - * Scrapes the TGov index page daily at 12:01 AM. - */ -export const dailyTgovScrape = new CronJob("daily-tgov-scrape", { - endpoint: scrape_tgov, - title: "TGov Daily Scrape", - schedule: "1 0 * * *", -}); diff --git a/archives/transcribe.ts b/archives/transcribe.ts deleted file mode 100644 index 85c8593..0000000 --- a/archives/transcribe.ts +++ /dev/null @@ -1,22 +0,0 @@ -// TODO -import { api } from "encore.dev/api"; - -import { db } from "./data"; - -type AudioTask = { audio: string; meetingId: string; video: string }; - -const LIMIT_LAST_NUMBER_OF_DAYS = 2; - -export const transcribe = api( - { method: "GET", path: "/api/transcribe" }, - async () => { - const lastWeek = new Date(); - lastWeek.setDate(lastWeek.getDate() - LIMIT_LAST_NUMBER_OF_DAYS); - - const meetings = db.meetingRecord.findMany({ - where: { - AND: [{ videoUrl: null }, { startedAt: { gte: lastWeek } }], - }, - }); - } -); diff --git a/archives/video/api.ts b/archives/video/api.ts deleted file mode 100644 index 1d0db77..0000000 --- a/archives/video/api.ts +++ /dev/null @@ -1,324 +0,0 @@ -/** - * Video Processing API Endpoints - * - * Provides HTTP endpoints for video acquisition, processing, and retrieval: - * - Scrape video links from source pages - * - Download videos to cloud storage - * - Retrieve processed videos and audio - */ -import { api } from "encore.dev/api"; -import logger from "encore.dev/log"; -import crypto from "crypto"; -import { db } from "../data"; -import { processVideo } from "./index"; - -// Interface for scraping video URLs endpoints -interface ScrapeVideosRequest { - viewerUrls: string[]; - limit?: number; -} - -interface ScrapeVideosResponse { - results: { - viewerUrl: string; - downloadUrl: string; - error?: string; - }[]; -} - -// Interface for downloading videos endpoints -interface DownloadVideosRequest { - downloadUrls: string[]; - extractAudio?: boolean; - limit?: number; - meetingRecordIds?: string[]; // Optional association with meeting records -} - -interface DownloadVideosResponse { - results: { - downloadUrl: string; - videoId?: string; - audioId?: string; - videoUrl?: string; - audioUrl?: string; - error?: string; - }[]; -} - -// Interface for retrieving video/audio endpoints -interface GetMediaRequest { - blobId: string; - type: "video" | "audio"; -} - -/** - * Scrape video download URLs from viewer pages - * - * This endpoint accepts an array of viewer page URLs and returns - * the extracted download URLs for each video. - */ -export const scrapeVideos = api( - { - method: "POST", - path: "/api/videos/scrape", - expose: true, - }, - async (req: ScrapeVideosRequest): Promise => { - const limit = req.limit || 1; - const limitedUrls = req.viewerUrls.slice(0, limit); - const results = []; - - for (const viewerUrl of limitedUrls) { - try { - logger.info(`Scraping video URL from viewer page: ${viewerUrl}`); - - // Use puppeteer to extract the actual video URL - const downloadUrl = await extractVideoUrl(viewerUrl); - results.push({ - viewerUrl, - downloadUrl, - }); - } catch (error: any) { - logger.error(`Error scraping video URL: ${error.message}`); - results.push({ - viewerUrl, - downloadUrl: "", - error: error.message, - }); - } - } - - return { results }; - } -); - -/** - * Download videos to cloud storage - * - * This endpoint accepts an array of direct video URLs, downloads each video, - * optionally extracts audio, and stores both in the cloud storage bucket. - */ -export const downloadVideos = api( - { - method: "POST", - path: "/api/videos/download", - expose: true, - }, - async (req: DownloadVideosRequest): Promise => { - const limit = req.limit || 1; - const limitedUrls = req.downloadUrls.slice(0, limit); - const results = []; - - for (let i = 0; i < limitedUrls.length; i++) { - const downloadUrl = limitedUrls[i]; - const meetingRecordId = req.meetingRecordIds?.[i]; - - try { - logger.info(`Processing video from URL: ${downloadUrl}`); - - // Create a unique filename based on the URL - const urlHash = crypto - .createHash("sha256") - .update(downloadUrl) - .digest("base64url") - .substring(0, 12); - const filename = `video_${urlHash}_${Date.now()}`; - - // Process the video (download, extract audio if requested, save to cloud) - const result = await processVideo(downloadUrl, { - filename, - extractAudio: req.extractAudio ?? true, - meetingRecordId, - }); - - results.push({ - downloadUrl, - videoId: result.videoId, - audioId: result.audioId, - videoUrl: result.videoUrl, - audioUrl: result.audioUrl, - }); - } catch (error: any) { - logger.error(`Error processing video: ${error.message}`); - results.push({ - downloadUrl, - error: error.message, - }); - } - } - - return { results }; - } -); - -/** - * Get information about stored media files - */ -export const getMediaInfo = api( - { - method: "GET", - path: "/api/videos/:blobId/info", - expose: true, - }, - async ({ blobId }: { blobId: string }) => { - const blob = await db.blob.findUnique({ - where: { id: blobId }, - }); - - if (!blob) { - throw new Error(`Media with ID ${blobId} not found`); - } - - return { - id: blob.id, - url: blob.url, - mimetype: blob.mimetype, - key: blob.key, - bucket: blob.bucket, - createdAt: blob.createdAt, - }; - } -); - -/** - * Get all media files for a meeting - */ -export const getMeetingMedia = api( - { - method: "GET", - path: "/api/meetings/:meetingId/media", - expose: true, - }, - async ({ meetingId }: { meetingId: string }) => { - const meeting = await db.meetingRecord.findUnique({ - where: { id: meetingId }, - include: { - agenda: true, - video: true, - audio: true, - }, - }); - - if (!meeting) { - throw new Error(`Meeting with ID ${meetingId} not found`); - } - - return { - meetingId: meeting.id, - meetingName: meeting.name, - startedAt: meeting.startedAt, - agenda: meeting.agenda - ? { - id: meeting.agenda.id, - url: meeting.agenda.url, - mimetype: meeting.agenda.mimetype, - } - : null, - video: meeting.video - ? { - id: meeting.video.id, - url: meeting.video.url, - mimetype: meeting.video.mimetype, - } - : null, - audio: meeting.audio - ? { - id: meeting.audio.id, - url: meeting.audio.url, - mimetype: meeting.audio.mimetype, - } - : null, - }; - } -); - -/** - * List all stored videos - */ -export const listVideos = api( - { - method: "GET", - path: "/api/videos", - expose: true, - }, - async ({ limit = 10, offset = 0 }: { limit?: number; offset?: number }) => { - const videos = await db.blob.findMany({ - where: { mimetype: { startsWith: "video/" } }, - take: limit, - skip: offset, - orderBy: { createdAt: "desc" }, - }); - - return videos.map((video) => ({ - id: video.id, - url: video.url, - mimetype: video.mimetype, - key: video.key, - bucket: video.bucket, - createdAt: video.createdAt, - })); - } -); - -/** - * List all stored audio files - */ -export const listAudio = api( - { - method: "GET", - path: "/api/audio", - expose: true, - }, - async ({ limit = 10, offset = 0 }: { limit?: number; offset?: number }) => { - const audioFiles = await db.blob.findMany({ - where: { mimetype: { startsWith: "audio/" } }, - take: limit, - skip: offset, - orderBy: { createdAt: "desc" }, - }); - - return audioFiles.map((audio) => ({ - id: audio.id, - url: audio.url, - mimetype: audio.mimetype, - key: audio.key, - bucket: audio.bucket, - createdAt: audio.createdAt, - })); - } -); - -/** - * Internal helper function to extract video URL from viewer page - */ -async function extractVideoUrl(viewerUrl: string): Promise { - // This reuses our existing logic from downloadVideoFromViewerPage but only returns the URL - // Implementation is extracted from tgov/download.ts - const browser = await import("puppeteer").then((p) => - p.default.launch({ - args: ["--disable-features=HttpsFirstBalancedModeAutoEnable"], - }) - ); - - const page = await browser.newPage(); - await page.goto(viewerUrl.toString(), { waitUntil: "domcontentloaded" }); - - const videoUrl = await page.evaluate(() => { - // May be defined in the global scope of the page - var video_url: string | null | undefined; - - if (typeof video_url === "string") return video_url; - - const videoElement = document.querySelector("video > source"); - if (!videoElement) - throw new Error("No element found with selector 'video > source'"); - - video_url = videoElement.getAttribute("src"); - if (!video_url) throw new Error("No src attribute found on element"); - - return video_url; - }); - - await browser.close(); - return videoUrl; -} diff --git a/archives/video/batch-api.ts b/archives/video/batch-api.ts deleted file mode 100644 index da3c550..0000000 --- a/archives/video/batch-api.ts +++ /dev/null @@ -1,332 +0,0 @@ -/** - * Video Batch Processing API Endpoints - * - * Provides batch processing endpoints for video acquisition and processing, - * designed for handling multiple videos concurrently or in the background. - */ -import { api } from "encore.dev/api"; -import { CronJob } from "encore.dev/cron"; -import logger from "encore.dev/log"; -import { db } from "../data"; -import { processVideo } from "./index"; -import { scrapeVideos } from "./api"; - -// Interface for batch processing request -interface BatchProcessRequest { - viewerUrls?: string[]; - meetingRecordIds?: string[]; - extractAudio?: boolean; - batchSize?: number; -} - -interface BatchProcessResponse { - batchId: string; - totalVideos: number; - status: "queued" | "processing" | "completed" | "failed"; -} - -/** - * Queue a batch of videos for processing - * - * This endpoint accepts an array of viewer URLs and queues them for processing. - * It returns a batch ID that can be used to check the status of the batch. - */ -export const queueVideoBatch = api( - { - method: "POST", - path: "/api/videos/batch/queue", - expose: true, - }, - async (req: BatchProcessRequest): Promise => { - if (!req.viewerUrls || req.viewerUrls.length === 0) { - throw new Error("No viewer URLs provided"); - } - - // Create a batch record in the database - const batch = await db.$transaction(async (tx) => { - // First, create entries for each URL to be processed - const videoTasks = await Promise.all( - req.viewerUrls!.map(async (url, index) => { - return tx.videoProcessingTask.create({ - data: { - viewerUrl: url, - meetingRecordId: req.meetingRecordIds?.[index], - status: "queued", - extractAudio: req.extractAudio ?? true, - }, - }); - }) - ); - - // Then create the batch that references these tasks - return tx.videoProcessingBatch.create({ - data: { - status: "queued", - totalTasks: videoTasks.length, - completedTasks: 0, - failedTasks: 0, - tasks: { - connect: videoTasks.map((task) => ({ id: task.id })), - }, - }, - }); - }); - - logger.info(`Queued batch ${batch.id} with ${batch.totalTasks} videos`); - - return { - batchId: batch.id, - totalVideos: batch.totalTasks, - status: batch.status as "queued" | "processing" | "completed" | "failed", - }; - } -); - -/** - * Get the status of a batch - */ -export const getBatchStatus = api( - { - method: "GET", - path: "/api/videos/batch/:batchId", - expose: true, - }, - async ({ batchId }: { batchId: string }) => { - const batch = await db.videoProcessingBatch.findUnique({ - where: { id: batchId }, - include: { - tasks: { - orderBy: { createdAt: "asc" }, - }, - }, - }); - - if (!batch) { - throw new Error(`Batch ${batchId} not found`); - } - - return { - batchId: batch.id, - status: batch.status, - totalTasks: batch.totalTasks, - completedTasks: batch.completedTasks, - failedTasks: batch.failedTasks, - createdAt: batch.createdAt, - updatedAt: batch.updatedAt, - tasks: batch.tasks.map((task) => ({ - id: task.id, - viewerUrl: task.viewerUrl, - downloadUrl: task.downloadUrl, - status: task.status, - videoId: task.videoId, - audioId: task.audioId, - error: task.error, - createdAt: task.createdAt, - updatedAt: task.updatedAt, - })), - }; - } -); - -/** - * List all batches - */ -export const listBatches = api( - { - method: "GET", - path: "/api/videos/batches", - expose: true, - }, - async ({ limit = 10, offset = 0 }: { limit?: number; offset?: number }) => { - const batches = await db.videoProcessingBatch.findMany({ - take: limit, - skip: offset, - orderBy: { createdAt: "desc" }, - include: { - _count: { - select: { tasks: true }, - }, - }, - }); - - return batches.map((batch) => ({ - id: batch.id, - status: batch.status, - totalTasks: batch.totalTasks, - completedTasks: batch.completedTasks, - failedTasks: batch.failedTasks, - createdAt: batch.createdAt, - updatedAt: batch.updatedAt, - })); - } -); - -/** - * Process the next batch of videos - * - * This endpoint processes a certain number of queued videos. - * It's designed to be called by a cron job. - */ -export const processNextBatch = api( - { - method: "POST", - path: "/api/videos/batch/process", - }, - async ({ batchSize = 5 }: { batchSize?: number }) => { - // Find batches with queued status - const queuedBatch = await db.videoProcessingBatch.findFirst({ - where: { status: "queued" }, - orderBy: { createdAt: "asc" }, - include: { - tasks: { - where: { status: "queued" }, - take: batchSize, - orderBy: { createdAt: "asc" }, - }, - }, - }); - - if (!queuedBatch || queuedBatch.tasks.length === 0) { - return { processed: 0 }; - } - - // Update batch status to processing - await db.videoProcessingBatch.update({ - where: { id: queuedBatch.id }, - data: { status: "processing" }, - }); - - logger.info( - `Processing batch ${queuedBatch.id} with ${queuedBatch.tasks.length} videos` - ); - - let processed = 0; - - // Process each task in the batch - for (const task of queuedBatch.tasks) { - try { - // Step 1: Update task status to processing - await db.videoProcessingTask.update({ - where: { id: task.id }, - data: { status: "processing" }, - }); - - // Step 2: Extract the download URL - let downloadUrl = task.downloadUrl; - - if (!downloadUrl && task.viewerUrl) { - // Scrape the download URL - const scrapeResult = await scrapeVideos({ - viewerUrls: [task.viewerUrl], - }); - - if (scrapeResult.results[0].error) { - throw new Error(scrapeResult.results[0].error); - } - - downloadUrl = scrapeResult.results[0].downloadUrl; - - // Update the task with the download URL - await db.videoProcessingTask.update({ - where: { id: task.id }, - data: { downloadUrl }, - }); - } - - if (!downloadUrl) { - throw new Error("No download URL available"); - } - - // Step 3: Process the video - const result = await processVideo(downloadUrl, { - extractAudio: task.extractAudio, - meetingRecordId: task.meetingRecordId || undefined, - }); - - // Step 4: Update the task with the result - await db.videoProcessingTask.update({ - where: { id: task.id }, - data: { - status: "completed", - videoId: result.videoId, - audioId: result.audioId, - }, - }); - - processed++; - } catch (error: any) { - logger.error(`Error processing task ${task.id}: ${error.message}`); - - // Update the task with the error - await db.videoProcessingTask.update({ - where: { id: task.id }, - data: { - status: "failed", - error: error.message, - }, - }); - - // Update batch failed count - await db.videoProcessingBatch.update({ - where: { id: queuedBatch.id }, - data: { - failedTasks: { increment: 1 }, - }, - }); - } - } - - // Update batch completed count and check if all tasks are done - const updatedBatch = await db.videoProcessingBatch.update({ - where: { id: queuedBatch.id }, - data: { - completedTasks: { increment: processed }, - }, - include: { - _count: { - select: { - tasks: true, - }, - }, - }, - }); - - // Check if all tasks are completed or failed - if ( - updatedBatch.completedTasks + updatedBatch.failedTasks >= - updatedBatch._count.tasks - ) { - await db.videoProcessingBatch.update({ - where: { id: queuedBatch.id }, - data: { status: "completed" }, - }); - } - - return { processed }; - } -); - -/** - * Endpoint that takes no params and delegates to the processNextBatch endpoint - * to use the default batch size (specifically for use with cron jobs) - * @see processNextBatch - */ -export const autoProcessNextBatch = api( - { - method: "POST", - path: "/api/videos/batch/auto-process", - expose: true, - }, - async () => { - return processNextBatch({}); - } -) - -/** - * Cron job to process video batches - */ -export const processBatchesCron = new CronJob("process-video-batches", { - title: "Process Video Batches", - schedule: "*/5 * * * *", // Every 5 minutes - endpoint: autoProcessNextBatch, -}); diff --git a/archives/video/downloader.ts b/archives/video/downloader.ts deleted file mode 100644 index c41ebc9..0000000 --- a/archives/video/downloader.ts +++ /dev/null @@ -1,174 +0,0 @@ -/** - * Video Downloader Module - * - * Provides functions for downloading videos from various sources, including m3u8 streams. - */ -import ffmpeg from "fluent-ffmpeg"; -import fs from "fs/promises"; -import path from "path"; -import puppeteer from "puppeteer"; -import logger from "encore.dev/log"; - -// The types for progress and codec data from fluent-ffmpeg -export interface ProgressData { - frames: number; - currentFps: number; - currentKbps: number; - targetSize: number; - timemark: string; - percent?: number; -} - -/** - * Downloads a video from a URL to a local file - * - * @param url The URL of the video to download (supports m3u8 and other formats) - * @param outputPath The path where the video will be saved - * @param progressCallback Optional callback to report download progress - * @returns Promise that resolves when the download is complete - */ -export async function downloadVideo( - url: string, - outputPath: string, - progressCallback?: (progress: ProgressData) => void -): Promise { - // Ensure output directory exists - await fs.mkdir(path.dirname(outputPath), { recursive: true }); - - return new Promise((resolve, reject) => { - const command = ffmpeg(url) - .inputOptions("-protocol_whitelist", "file,http,https,tcp,tls,crypto") - .outputOptions("-c", "copy") - .output(outputPath); - - if (progressCallback) { - command.on("progress", progressCallback); - } else { - command.on("progress", (progress) => { - logger.info( - `Download progress: ${progress.percent?.toFixed(2)}% complete` - ); - }); - } - - command - .on("codecData", (data) => { - logger.info(`Input codec: ${data.video} video / ${data.audio} audio`); - }) - .on("end", () => { - logger.info(`Video download completed: ${outputPath}`); - resolve(); - }) - .on("error", (err) => { - logger.error(`Error downloading video: ${err.message}`); - reject(err); - }) - .run(); - }); -} - -/** - * Downloads a video from a viewer page URL by extracting the video source URL - * - * @param viewerUrl The URL of the video viewer page - * @param outputPath The path where the video will be saved - * @returns Promise that resolves when the download is complete - */ -export async function downloadVideoFromViewerPage( - viewerUrl: string, - outputPath: string -): Promise { - logger.info(`Extracting video URL from viewer page: ${viewerUrl}`); - - const browser = await puppeteer.launch({ - args: ["--no-sandbox", "--disable-setuid-sandbox"], - }); - - try { - const page = await browser.newPage(); - await page.goto(viewerUrl.toString(), { waitUntil: "domcontentloaded" }); - - const videoUrl = await page.evaluate(() => { - // May be defined in the global scope of the page - var video_url: string | null | undefined; - - if (typeof video_url === "string") return video_url; - - const videoElement = document.querySelector("video > source"); - if (!videoElement) { - throw new Error("No element found with selector 'video > source'"); - } - - video_url = videoElement.getAttribute("src"); - if (!video_url) { - throw new Error("No src attribute found on element"); - } - - return video_url; - }); - - logger.info(`Extracted video URL: ${videoUrl}`); - await browser.close(); - - // Download the video using the extracted URL - return downloadVideo(videoUrl, outputPath); - } catch (error) { - await browser.close(); - throw error; - } -} - -/** - * Downloads a video while simultaneously extracting the audio track - * - * @param url The URL of the video to download - * @param videoOutputPath The path where the video will be saved - * @param audioOutputPath The path where the audio will be saved - * @returns Promise that resolves when both downloads are complete - */ -export async function downloadVideoWithAudioExtraction( - url: string, - videoOutputPath: string, - audioOutputPath: string -): Promise { - // Ensure output directories exist - await fs.mkdir(path.dirname(videoOutputPath), { recursive: true }); - await fs.mkdir(path.dirname(audioOutputPath), { recursive: true }); - - return new Promise((resolve, reject) => { - ffmpeg(url) - .inputOptions("-protocol_whitelist", "file,http,https,tcp,tls,crypto") - // Output 1: Video file with video and audio - .output(videoOutputPath) - .outputOptions("-c", "copy") - - // Output 2: Audio file with just audio - .output(audioOutputPath) - .outputOptions("-vn") // No video - .outputOptions("-acodec", "libmp3lame") // Use MP3 codec - .outputOptions("-ab", "128k") // Audio bitrate - - .on("progress", (progress) => { - logger.info( - `Download progress: ${progress.percent?.toFixed(2)}% complete` - ); - }) - .on("end", () => { - logger.info(`Video and audio extraction completed`); - logger.info(`Video saved to: ${videoOutputPath}`); - logger.info(`Audio saved to: ${audioOutputPath}`); - resolve(); - }) - .on("error", (err) => { - logger.error(`Error processing video: ${err.message}`); - reject(err); - }) - .run(); - }); -} - -export default { - downloadVideo, - downloadVideoFromViewerPage, - downloadVideoWithAudioExtraction, -}; diff --git a/archives/video/extractor.ts b/archives/video/extractor.ts deleted file mode 100644 index c659f5e..0000000 --- a/archives/video/extractor.ts +++ /dev/null @@ -1,152 +0,0 @@ -/** - * Video Extractor Module - * - * Provides functions for extracting and splitting audio and video tracks from video files. - */ -import ffmpeg from "fluent-ffmpeg"; -import fs from "fs/promises"; -import path from "path"; -import logger from "encore.dev/log"; - -/** - * Extracts the audio track from a video file - * - * @param videoPath Path to the input video file - * @param outputPath Path where the audio file will be saved - * @param format Audio format (default: 'mp3') - * @param bitrate Audio bitrate (default: '128k') - * @param useOriginalCodec Whether to copy the original audio codec (default: true) - * @returns Promise that resolves when extraction is complete - */ -export async function extractAudioTrack( - videoPath: string, - outputPath: string -): Promise { - // Ensure output directory exists - await fs.mkdir(path.dirname(outputPath), { recursive: true }); - - return new Promise((resolve, reject) => { - ffmpeg(videoPath) - .outputOptions("-vn -c:a copy") // No video - .output(outputPath) - .on("start", (commandLine) => { - logger.info(`Audio extraction started: ${commandLine}`); - }) - .on("progress", (progress) => { - logger.info( - `Audio extraction progress: ${progress.percent?.toFixed(2)}% complete` - ); - }) - .on("end", () => { - logger.info(`Audio extraction completed: ${outputPath}`); - resolve(); - }) - .on("error", (err) => { - logger.error(`Error extracting audio: ${err.message}`); - reject(err); - }) - .run(); - }); -} - -/** - * Extracts the video track from a video file (removes audio) - * - * @param videoPath Path to the input video file - * @param outputPath Path where the video-only file will be saved - * @param format Video format (default: 'mp4') - * @param useOriginalCodec Whether to copy the original video codec (default: true) - * @returns Promise that resolves when extraction is complete - */ -export async function extractVideoTrack( - videoPath: string, - outputPath: string -): Promise { - // Ensure output directory exists - await fs.mkdir(path.dirname(outputPath), { recursive: true }); - - return new Promise((resolve, reject) => { - ffmpeg(videoPath) - .outputOptions("-an -c:v copy") // No audio, copy video codec - .output(outputPath) - .on("start", (commandLine) => { - logger.info(`Video extraction started: ${commandLine}`); - }) - .on("progress", (progress) => { - logger.info( - `Video extraction progress: ${progress.percent?.toFixed(2)}% complete` - ); - }) - .on("end", () => { - logger.info(`Video extraction completed: ${outputPath}`); - resolve(); - }) - .on("error", (err) => { - logger.error(`Error extracting video: ${err.message}`); - reject(err); - }) - .run(); - }); -} - -/** - * Extracts both audio and video tracks in a single operation - * - * @param inputPath Path to the input video file - * @param videoOutputPath Path where the video-only file will be saved - * @param audioOutputPath Path where the audio-only file will be saved - * @param useOriginalCodecs Whether to copy the original codecs (default: true) - */ -export async function extractAudioAndVideo( - inputPath: string, - videoOutputPath: string, - audioOutputPath: string -): Promise { - // Ensure output directories exist - await fs.mkdir(path.dirname(videoOutputPath), { recursive: true }); - await fs.mkdir(path.dirname(audioOutputPath), { recursive: true }); - - return new Promise((resolve, reject) => { - const command = ffmpeg(inputPath); - - // Output 1: Video-only file - - command.output(videoOutputPath).outputOptions([ - "-an", // No audio - "-c:v copy", // Copy video codec (no re-encoding) - ]); - - // Output 2: Audio-only file - command.output(audioOutputPath).outputOptions([ - "-vn", // No video - "-c:a copy", // Copy audio codec (no re-encoding) - ]); - - command - .on("start", (commandLine) => { - logger.info(`Extraction started: ${commandLine}`); - }) - .on("progress", (progress) => { - logger.info( - `Extraction progress: ${progress.percent?.toFixed(2)}% complete` - ); - }) - .on("end", () => { - logger.info(`Extraction completed`); - logger.info(`Video saved to: ${videoOutputPath}`); - logger.info(`Audio saved to: ${audioOutputPath}`); - resolve(); - }) - .on("error", (err) => { - logger.error(`Error during extraction: ${err.message}`); - reject(err); - }) - .run(); - }); -} - -export default { - extractAudioTrack, - extractVideoTrack, - extractAudioAndVideo, -}; diff --git a/archives/video/index.ts b/archives/video/index.ts deleted file mode 100644 index 22fab67..0000000 --- a/archives/video/index.ts +++ /dev/null @@ -1,207 +0,0 @@ -/** - * Video Processing Utilities - * - * This module provides a suite of utilities for processing videos from m3u8 streams: - * - Downloading videos from m3u8 URLs - * - Extracting/splitting audio and video tracks - * - Streaming capabilities for audio/video channels - */ -import fs from "fs/promises"; -import { db, agendas,bucket_meta,recordings } from "../data"; -import crypto from "crypto"; -import logger from "encore.dev/log"; -import { fileTypeFromBuffer } from "file-type"; -import { downloadVideo } from "./downloader"; -import { extractAudioTrack, extractVideoTrack } from "./extractor"; -import { createVideoStream, createAudioStream, createCombinedStream } from "./streamer"; - -export type VideoProcessingOptions = { - filename?: string; - saveToDatabase?: boolean; - extractAudio?: boolean; - meetingRecordId?: string; -}; - -export type ProcessedVideoResult = { - videoId?: string; - audioId?: string; - videoUrl?: string; - audioUrl?: string; - videoMimetype?: string; - audioMimetype?: string; -}; - -/** - * Process a video from a URL, with options to download and save directly to cloud storage - * - * @param url The m3u8 URL or other video URL to process - * @param options Processing options - * @returns Database IDs and URLs for the processed files - */ -export async function processVideo(url: string, options: VideoProcessingOptions = {}): Promise { - const { - filename = `video_${Date.now()}`, - extractAudio = false, - meetingRecordId - } = options; - - // Generate unique keys for cloud storage - const videoFilename = `${filename}.mp4`; - const audioFilename = `${filename}.mp3`; - - // Hash the URL to use as part of the key - const urlHash = crypto.createHash("sha256").update(url).digest("base64url").substring(0, 12); - const videoKey = `${urlHash}_${videoFilename}`; - const audioKey = `${urlHash}_${audioFilename}`; - - logger.info(`Processing video from ${url}`); - logger.info(`Video key: ${videoKey}`); - if (extractAudio) logger.info(`Audio key: ${audioKey}`); - - // Create a temporary directory for processing if needed - const tempDir = `/tmp/${Date.now()}_${urlHash}`; - const videoTempPath = `${tempDir}/${videoFilename}`; - const audioTempPath = extractAudio ? `${tempDir}/${audioFilename}` : undefined; - - try { - // Create temp directory - await fs.mkdir(tempDir, { recursive: true }); - - // Step 1: Download the video to temporary location - logger.info(`Downloading video to temp location: ${videoTempPath}`); - await downloadVideo(url, videoTempPath); - - // Step 2: Extract audio if requested - if (extractAudio && audioTempPath) { - logger.info(`Extracting audio to temp location: ${audioTempPath}`); - await extractAudioTrack(videoTempPath, audioTempPath); - } - - // Step 3: Upload files to storage and save to database - const result = await uploadAndSaveToDb( - videoTempPath, - audioTempPath, - videoKey, - audioKey, - url, - meetingRecordId - ); - - return result; - } finally { - // Clean up temporary files - try { - await fs.rm(tempDir, { recursive: true, force: true }); - logger.info(`Cleaned up temporary directory: ${tempDir}`); - } catch (err) { - logger.error(`Failed to clean up temporary directory: ${err}`); - } - } -} - -/** - * Upload files to storage bucket and update database - */ -async function uploadAndSaveToDb( - videoPath: string, - audioPath: string | undefined, - videoKey: string, - audioKey: string, - sourceUrl: string, - meetingRecordId?: string -): Promise { - logger.info(`Uploading video and audio files to storage`); - - // Read video file and detect its mimetype - const videoBuffer = await fs.readFile(videoPath); - const videoTypeResult = await fileTypeFromBuffer(videoBuffer); - const videoMimetype = videoTypeResult?.mime || "application/octet-stream"; - logger.info(`Detected video mimetype: ${videoMimetype}`); - - // Upload video to bucket - await recordings.upload(videoKey, videoBuffer, { contentType: videoMimetype }); - const videoUrl = recordings.publicUrl(videoKey); - logger.info(`Uploaded video to ${videoUrl}`); - - let videoBlob; - let audioBlob; - let audioUrl: string | undefined; - let audioMimetype: string | undefined; - let audioBuffer: Buffer | undefined; - - // Read audio file if it exists - if (audioPath) { - audioBuffer = await fs.readFile(audioPath); - const audioTypeResult = await fileTypeFromBuffer(audioBuffer); - audioMimetype = audioTypeResult?.mime || "application/octet-stream"; - logger.info(`Detected audio mimetype: ${audioMimetype}`); - - // Upload audio to bucket - await recordings.upload(audioKey, audioBuffer, { contentType: audioMimetype }); - audioUrl = recordings.publicUrl(audioKey); - logger.info(`Uploaded audio to ${audioUrl}`); - } - - // Save to database in a transaction - const result = await db.$transaction(async (tx) => { - // Create video blob record - videoBlob = await tx.blob.create({ - data: { - key: videoKey, - mimetype: videoMimetype, - url: videoUrl, - bucket: bucket_meta.RECORDINGS_BUCKET_NAME, - srcUrl: sourceUrl - } - }); - logger.info(`Created video blob record with ID: ${videoBlob.id}`); - - let audioBlob = undefined; - - // If audio was extracted, save it too - if (audioPath && audioBuffer && audioMimetype && audioUrl) { - audioBlob = await tx.blob.create({ - data: { - key: audioKey, - mimetype: audioMimetype, - url: audioUrl, - bucket: bucket_meta.RECORDINGS_BUCKET_NAME, - srcUrl: sourceUrl - } - }); - logger.info(`Created audio blob record with ID: ${audioBlob.id}`); - } - - // If meeting record ID provided, update it - if (meetingRecordId) { - await tx.meetingRecord.update({ - where: { id: meetingRecordId }, - data: { - videoId: videoBlob.id, - ...(audioBlob ? { audioId: audioBlob.id } : {}) - } - }); - logger.info(`Updated meeting record ${meetingRecordId} with video and audio IDs`); - } - - return { - videoId: videoBlob.id, - audioId: audioBlob?.id, - videoUrl, - audioUrl, - videoMimetype: videoBlob.mimetype, - audioMimetype: audioBlob?.mimetype - }; - }); - - return result; -} - -export { - downloadVideo, - extractAudioTrack, - extractVideoTrack, - createVideoStream, - createAudioStream, - createCombinedStream -}; \ No newline at end of file diff --git a/docs/architecture.md b/docs/architecture.md index ed54e84..be9cfc7 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -2,11 +2,11 @@ ## Overview -This application scrapes meeting information from the Tulsa Government website, downloads and processes videos and documents, and makes them available through a set of APIs. The system is designed as a set of microservices, each with its own responsibility and data store. +This application scrapes meeting information from the Tulsa Government website, downloads and processes videos and documents, transcribes audio to text, and makes them available through a set of APIs. The system is designed as a set of microservices, each with its own responsibility and data store. ## Service Structure -The application is organized into three main services: +The application is organized into four main services: ### 1. TGov Service **Purpose**: Scrape and provide access to Tulsa Government meeting data @@ -49,6 +49,19 @@ The application is organized into three main services: - `GET /api/documents/:id` - Get a specific document - `POST /api/meeting-documents` - Download and link meeting agenda documents +### 4. Transcription Service +**Purpose**: Convert audio to text and manage transcriptions +- Transcribes audio files using the OpenAI Whisper API +- Stores and manages transcription results with time-aligned segments +- Processes transcription jobs asynchronously +- Provides APIs for accessing transcriptions + +**Key Endpoints**: +- `POST /transcribe` - Request transcription for an audio file +- `GET /jobs/:jobId` - Get the status of a transcription job +- `GET /transcriptions/:transcriptionId` - Get a transcription by ID +- `GET /meetings/:meetingId/transcriptions` - Get all transcriptions for a meeting + ## Cross-Service Communication Services communicate with each other using type-safe API calls through the Encore client library: @@ -56,12 +69,14 @@ Services communicate with each other using type-safe API calls through the Encor - **TGov → Media**: Media service calls TGov's `extractVideoUrl` endpoint to get download URLs - **Documents → TGov**: Documents service calls TGov's `listMeetings` endpoint to get meeting data - **Media → TGov**: Media service uses TGov's meeting data for processing videos +- **Transcription → Media**: Transcription service calls Media's `getMediaFile` endpoint to get audio file information ## Data Flow 1. TGov service scrapes meeting information from the Tulsa Government website -2. Media service extracts download URLs and processes videos +2. Media service extracts download URLs and processes videos, including audio extraction 3. Documents service downloads and links agenda documents to meetings +4. Transcription service converts audio files to text and stores the transcriptions ## Databases @@ -70,6 +85,7 @@ Each service has its own database: - **TGov Database**: Stores committee and meeting information - **Media Database**: Stores media file metadata and processing tasks - **Documents Database**: Stores document metadata +- **Transcription Database**: Stores transcription jobs and results ## Storage Buckets @@ -80,4 +96,4 @@ Each service has its own database: ## Cron Jobs - **daily-tgov-scrape**: Daily scrape of the TGov website (12:01 AM) -- **process-video-batches**: Process video batches every 5 minutes +- **process-video-batches**: Process video batches every 5 minutes \ No newline at end of file diff --git a/documents/data/migrations/20250312062319_init/migration.sql b/documents/data/migrations/20250312062319_init/migration.sql deleted file mode 100644 index f2ae6b2..0000000 --- a/documents/data/migrations/20250312062319_init/migration.sql +++ /dev/null @@ -1,17 +0,0 @@ --- CreateTable -CREATE TABLE "DocumentFile" ( - "id" TEXT NOT NULL, - "bucket" TEXT NOT NULL, - "key" TEXT NOT NULL, - "mimetype" TEXT NOT NULL, - "url" TEXT, - "srcUrl" TEXT, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - "meetingRecordId" TEXT, - "title" TEXT, - "description" TEXT, - "fileSize" INTEGER, - - CONSTRAINT "DocumentFile_pkey" PRIMARY KEY ("id") -); diff --git a/documents/data/schema.prisma b/documents/data/schema.prisma deleted file mode 100644 index cd06c35..0000000 --- a/documents/data/schema.prisma +++ /dev/null @@ -1,32 +0,0 @@ -generator client { - provider = "prisma-client-js" - previewFeatures = ["driverAdapters", "metrics"] - binaryTargets = ["native", "debian-openssl-3.0.x"] - output = "../../node_modules/@prisma/client/documents" -} - -datasource db { - provider = "postgresql" - url = env("DOCUMENTS_DATABASE_URL") -} - -// Models related to documents processing and storage - -model DocumentFile { - id String @id @default(ulid()) - bucket String - key String - mimetype String - url String? - srcUrl String? - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - // Reference to TGov service's MeetingRecord - meetingRecordId String? - - // Document metadata - title String? - description String? - fileSize Int? -} diff --git a/documents/encore.service.ts b/documents/encore.service.ts deleted file mode 100644 index 2135523..0000000 --- a/documents/encore.service.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Service } from "encore.dev/service"; - -/** - * Documents service for managing document files and metadata - * - * This service is responsible for: - * - Storing and retrieving document files (PDFs, etc.) - * - Managing document metadata - * - Providing APIs for document access - */ -export default new Service("documents"); diff --git a/documents/index.ts b/documents/index.ts deleted file mode 100644 index 19ce913..0000000 --- a/documents/index.ts +++ /dev/null @@ -1,234 +0,0 @@ -/** - * Documents Service API Endpoints - * - * Provides HTTP endpoints for document retrieval and management: - * - Upload and store document files (PDFs, etc.) - * - Retrieve document metadata and content - * - Link documents to meeting records - */ -import { api } from "encore.dev/api"; -import logger from "encore.dev/log"; -import fs from "fs/promises"; -import crypto from "crypto"; -import path from "path"; -import { fileTypeFromBuffer } from "file-type"; -import { db, agendas } from "./data"; - -const whitelistedBinaryFileTypes = [ - "application/pdf", -] - -/** - * Download and store a document from a URL - */ -export const downloadDocument = api( - { - method: "POST", - path: "/api/documents/download", - expose: true, - }, - async (params: { - url: string; - title?: string; - meetingRecordId?: string; - description?: string; - }): Promise<{ - id: string; - url?: string; - title?: string; - mimetype?: string; - }> => { - const { url, title, meetingRecordId, description } = params; - logger.info(`Downloading document from ${url}`); - - try { - // Create a temporary file to store the downloaded document - const urlHash = crypto.createHash("sha256").update(url).digest("base64url").substring(0, 12); - const tempDir = `/tmp/${Date.now()}_${urlHash}`; - const tempFilePath = `${tempDir}/document`; - - await fs.mkdir(tempDir, { recursive: true }); - - // Download the document - const response = await fetch(url); - if (!response.ok) { - throw new Error(`Failed to download document: ${response.statusText}`); - } - - const buffer = Buffer.from(await response.arrayBuffer()); - await fs.writeFile(tempFilePath, buffer); - - // Determine the file type - const fileType = await fileTypeFromBuffer(buffer); - const mimetype = fileType?.mime || "application/octet-stream"; - - // ONLY ALLOW WHITELISTED FILE TYPES - if (!whitelistedBinaryFileTypes.includes(mimetype)) { - throw new Error(`Document has forbidden file type: ${mimetype}`); - } - - // Generate a key for storage - const fileExt = fileType?.ext || "bin"; - const documentKey = `${urlHash}_${Date.now()}.${fileExt}`; - - // Upload to cloud storage - const attrs = await agendas.upload(documentKey, buffer, { - contentType: mimetype, - }); - - // Save metadata to database - const documentFile = await db.documentFile.create({ - data: { - bucket: "agendas", - key: documentKey, - mimetype, - url: agendas.publicUrl(documentKey), - srcUrl: url, - meetingRecordId, - title: title || path.basename(new URL(url).pathname), - description, - fileSize: attrs.size, - }, - }); - - logger.info(`Document saved with ID: ${documentFile.id}`); - - return { - id: documentFile.id, - url: documentFile.url || undefined, - title: documentFile.title || undefined, - mimetype: documentFile.mimetype, - }; - } catch (error: any) { - logger.error(`Error downloading document: ${error.message}`); - throw error; - } - } -); - -/** - * List all documents with optional filtering - */ -export const listDocuments = api( - { - method: "GET", - path: "/api/documents", - expose: true, - }, - async (params: { - limit?: number; - offset?: number; - meetingRecordId?: string; - }): Promise<{ - documents: Array<{ - id: string; - title?: string; - description?: string; - url?: string; - mimetype: string; - fileSize?: number; - createdAt: Date; - }>; - total: number; - }> => { - const { limit = 20, offset = 0, meetingRecordId } = params; - - const where = meetingRecordId ? { meetingRecordId } : {}; - - const [documentFiles, total] = await Promise.all([ - db.documentFile.findMany({ - where, - take: limit, - skip: offset, - orderBy: { createdAt: "desc" }, - }), - db.documentFile.count({ where }), - ]); - - return { - documents: documentFiles.map(doc => ({ - id: doc.id, - title: doc.title || undefined, - description: doc.description || undefined, - url: doc.url || undefined, - mimetype: doc.mimetype, - fileSize: doc.fileSize || undefined, - createdAt: doc.createdAt, - })), - total, - }; - } -); - -/** - * Get document details by ID - */ -export const getDocument = api( - { - method: "GET", - path: "/api/documents/:id", - expose: true, - }, - async (params: { id: string }): Promise<{ - id: string; - title?: string; - description?: string; - url?: string; - mimetype: string; - fileSize?: number; - createdAt: Date; - meetingRecordId?: string; - }> => { - const { id } = params; - - const documentFile = await db.documentFile.findUnique({ - where: { id }, - }); - - if (!documentFile) { - throw new Error(`Document with ID ${id} not found`); - } - - return { - id: documentFile.id, - title: documentFile.title || undefined, - description: documentFile.description || undefined, - url: documentFile.url || undefined, - mimetype: documentFile.mimetype, - fileSize: documentFile.fileSize || undefined, - createdAt: documentFile.createdAt, - meetingRecordId: documentFile.meetingRecordId || undefined, - }; - } -); - -/** - * Update document metadata - */ -export const updateDocument = api( - { - method: "PATCH", - path: "/api/documents/:id", - expose: true, - }, - async (params: { - id: string; - title?: string; - description?: string; - meetingRecordId?: string | null; - }): Promise<{ success: boolean }> => { - const { id, ...updates } = params; - - // Filter out undefined values - const data = Object.fromEntries( - Object.entries(updates).filter(([_, v]) => v !== undefined) - ); - - await db.documentFile.update({ - where: { id }, - data, - }); - - return { success: true }; - } -); diff --git a/documents/meeting.ts b/documents/meeting.ts deleted file mode 100644 index 8256730..0000000 --- a/documents/meeting.ts +++ /dev/null @@ -1,139 +0,0 @@ -/** - * Meeting Document Integration API - * - * This module provides functionality to download and link agenda documents - * to specific meeting records from the TGov service. - */ -import { api } from "encore.dev/api"; -import logger from "encore.dev/log"; -import { tgov } from "~encore/clients"; - -import { downloadDocument } from "./index"; - -interface MeetingDocumentResponse { - documentId?: string; - documentUrl?: string; - meetingId: string; - success: boolean; - error?: string; -} - -/** - * Download and link meeting agenda documents based on meeting record IDs - */ -export const downloadMeetingDocuments = api( - { - method: "POST", - path: "/api/meeting-documents", - expose: true, - }, - async (params: { - meetingIds: string[]; - limit?: number; - }): Promise<{ - results: MeetingDocumentResponse[]; - }> => { - const { meetingIds, limit = 10 } = params; - const limitedIds = meetingIds.slice(0, limit); - const results: MeetingDocumentResponse[] = []; - - // Get meeting details with agenda view URLs from TGov service - for (const meetingId of limitedIds) { - try { - // Fetch the meeting details - const meetings = await tgov.listMeetings({ - limit: 1, - offset: 0, - }); - - // Find the specific meeting by ID - const meeting = meetings.meetings.find(m => m.id === meetingId); - if (!meeting || !meeting.agendaViewUrl) { - results.push({ - meetingId, - success: false, - error: meeting ? "No agenda URL available" : "Meeting not found" - }); - continue; - } - - // Download the agenda document - const document = await downloadDocument({ - url: meeting.agendaViewUrl, - meetingRecordId: meetingId, - title: `${meeting.committee.name} - ${meeting.name} Agenda` - }); - - results.push({ - documentId: document.id, - documentUrl: document.url, - meetingId, - success: true - }); - } catch (error: any) { - logger.error(`Error processing meeting document for ${meetingId}: ${error.message}`); - results.push({ - meetingId, - success: false, - error: error.message - }); - } - } - - return { results }; - } -); - -/** - * Download agendas for all recent meetings without linked agenda documents - */ -export const processPendingAgendas = api( - { - method: "POST", - path: "/api/meeting-documents/process-pending", - expose: true, - }, - async (params: { - limit?: number; - daysBack?: number; - }): Promise<{ - processed: number; - successful: number; - failed: number; - }> => { - const { limit = 10, daysBack = 30 } = params; - - // Get meetings from the last X days that don't have agendas - const meetings = await tgov.listMeetings({}); - const meetingsNeedingAgendas = meetings.meetings - .filter(m => !m.agendaId && m.agendaViewUrl) - .slice(0, limit); - - let successful = 0; - let failed = 0; - - if (meetingsNeedingAgendas.length === 0) { - return { processed: 0, successful: 0, failed: 0 }; - } - - // Process each meeting - const results = await downloadMeetingDocuments({ - meetingIds: meetingsNeedingAgendas.map(m => m.id) - }); - - // Count successes and failures - for (const result of results.results) { - if (result.success) { - successful++; - } else { - failed++; - } - } - - return { - processed: results.results.length, - successful, - failed - }; - } -); diff --git a/env.ts b/env.ts new file mode 100644 index 0000000..5978e99 --- /dev/null +++ b/env.ts @@ -0,0 +1,41 @@ +import path from "node:path"; + +import dotenv from "@dotenvx/dotenvx"; +import * as v from "valibot"; + +dotenv.config(); + +const Env = v.looseObject({ + ARCHIVES_DATABASE_URL: v.pipe( + v.string(), + v.url(), + v.regex(/^postgresql:\/\/.*?sslmode=disable$/), + ), + DOCUMENTS_DATABASE_URL: v.pipe( + v.string(), + v.url(), + v.regex(/^postgresql:\/\/.*?sslmode=disable$/), + ), + MEDIA_DATABASE_URL: v.pipe( + v.string(), + v.url(), + v.regex(/^postgresql:\/\/.*?sslmode=disable$/), + ), + TGOV_DATABASE_URL: v.pipe( + v.string(), + v.url(), + v.regex(/^postgresql:\/\/.*?sslmode=disable$/), + ), + TRANSCRIPTION_DATABASE_URL: v.pipe( + v.string(), + v.url(), + v.regex(/^postgresql:\/\/.*?sslmode=disable$/), + ), + CHROMIUM_PATH: v.optional(v.string()), + OPENAI_API_KEY: v.string(), + TMP_DIR: v.optional(v.string(), "." + path.sep + "tmp"), +}); + +const env = v.parse(Env, process.env); + +export default env; diff --git a/media/data/migrations/migration_lock.toml b/media/data/migrations/migration_lock.toml deleted file mode 100644 index 648c57f..0000000 --- a/media/data/migrations/migration_lock.toml +++ /dev/null @@ -1,3 +0,0 @@ -# Please do not edit this file manually -# It should be added in your version-control system (e.g., Git) -provider = "postgresql" \ No newline at end of file diff --git a/media/data/schema.prisma b/media/data/schema.prisma deleted file mode 100644 index 40b950e..0000000 --- a/media/data/schema.prisma +++ /dev/null @@ -1,68 +0,0 @@ -generator client { - provider = "prisma-client-js" - previewFeatures = ["driverAdapters", "metrics"] - binaryTargets = ["native", "debian-openssl-3.0.x"] - output = "../../node_modules/@prisma/client/media" -} - -datasource db { - provider = "postgresql" - url = env("MEDIA_DATABASE_URL") -} - -// Models related to media processing - -model MediaFile { - id String @id @default(ulid()) - bucket String - key String - mimetype String - url String? - srcUrl String? - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - // External references maintained by ID only - meetingRecordId String? - - // MediaFile metadata - title String? - description String? - fileSize Int? - - // Tasks related to this media file - videoProcessingTaskVideos VideoProcessingTask[] @relation("task_video") - videoProcessingTaskAudios VideoProcessingTask[] @relation("task_audio") -} - -model VideoProcessingBatch { - id String @id @default(ulid()) - status String // queued, processing, completed, failed - totalTasks Int - completedTasks Int @default(0) - failedTasks Int @default(0) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - tasks VideoProcessingTask[] -} - -model VideoProcessingTask { - id String @id @default(ulid()) - viewerUrl String? - downloadUrl String? - status String // queued, processing, completed, failed - extractAudio Boolean @default(true) - error String? - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - batchId String? - meetingRecordId String? // Reference to TGov service's MeetingRecord - videoId String? - audioId String? - - batch VideoProcessingBatch? @relation(fields: [batchId], references: [id]) - video MediaFile? @relation("task_video", fields: [videoId], references: [id]) - audio MediaFile? @relation("task_audio", fields: [audioId], references: [id]) -} diff --git a/media/processor.ts b/media/processor.ts deleted file mode 100644 index cecff1d..0000000 --- a/media/processor.ts +++ /dev/null @@ -1,184 +0,0 @@ -/** - * Media Processor Module - * - * Provides high-level functions for downloading, processing, and storing media files - */ -import fs from "fs/promises"; -import crypto from "crypto"; -import logger from "encore.dev/log"; - -import { downloadVideo } from "./downloader"; -import { extractAudioTrack } from "./extractor"; -import { db, recordings, bucket_meta } from "./data"; -import { fileTypeFromBuffer } from "file-type"; - -export interface ProcessingOptions { - filename?: string; - extractAudio?: boolean; - meetingRecordId?: string; -} - -export interface ProcessedMediaResult { - videoId: string; - audioId?: string; - videoUrl?: string; - audioUrl?: string; - videoMimetype?: string; - audioMimetype?: string; -} - -/** - * Process a video from a URL, with options to download and save directly to cloud storage - * - * @param url The m3u8 URL or other video URL to process - * @param options Processing options - * @returns Database IDs and URLs for the processed files - */ -export async function processMedia( - url: string, - options: ProcessingOptions = {} -): Promise { - const { - filename = `video_${Date.now()}`, - extractAudio = false, - meetingRecordId, - } = options; - - // Generate unique keys for cloud storage - const videoFilename = `${filename}_video`; - const audioFilename = `${filename}_audio`; - - // Hash the URL to use as part of the key - const urlHash = crypto - .createHash("sha256") - .update(url) - .digest("base64url") - .substring(0, 12); - const videoKey = `${urlHash}_${videoFilename}`; - const audioKey = `${urlHash}_${audioFilename}`; - - logger.info(`Processing media from ${url}`); - logger.info(`Video key: ${videoKey}`); - if (extractAudio) logger.info(`Audio key: ${audioKey}`); - - // Create a temporary directory for processing if needed - const tempDir = `/tmp/${Date.now()}_${urlHash}`; - const videoTempPath = `${tempDir}/${videoFilename}`; - const audioTempPath = extractAudio - ? `${tempDir}/${audioFilename}` - : undefined; - - try { - // Create temp directory - await fs.mkdir(tempDir, { recursive: true }); - - // Step 1: Download the video to temporary location - logger.info(`Downloading video to temp location: ${videoTempPath}`); - await downloadVideo(url, videoTempPath); - - // Step 2: Extract audio if requested - if (extractAudio && audioTempPath) { - logger.info(`Extracting audio to temp location: ${audioTempPath}`); - await extractAudioTrack(videoTempPath, audioTempPath); - } - - // Step 3: Upload files to storage and save to database - const result = await uploadAndSaveToDb( - videoTempPath, - audioTempPath, - videoKey, - audioKey, - url, - meetingRecordId - ); - - return result; - } finally { - // Clean up temporary files - try { - await fs.rm(tempDir, { recursive: true, force: true }); - logger.info(`Cleaned up temporary directory: ${tempDir}`); - } catch (err) { - logger.error(`Failed to clean up temporary directory: ${err}`); - } - } -} - -/** - * Upload files to storage bucket and update database - */ -async function uploadAndSaveToDb( - videoPath: string, - audioPath: string | undefined, - videoKey: string, - audioKey: string, - sourceUrl: string, - meetingRecordId?: string -): Promise { - // Read files and get their content types - const videoBuffer = await fs.readFile(videoPath); - // Use file-type to detect the actual mimetype of the video - const videoTypeResult = await fileTypeFromBuffer(videoBuffer); - const videoType = videoTypeResult?.mime || "application/octet-stream"; - logger.info(`Detected video mimetype: ${videoType}`); - - let audioBuffer: Buffer | undefined; - let audioType: string | undefined; - - if (audioPath) { - audioBuffer = await fs.readFile(audioPath); - // Use file-type to detect the actual mimetype of the audio - const audioTypeResult = await fileTypeFromBuffer(audioBuffer); - audioType = audioTypeResult?.mime || "application/octet-stream"; - logger.info(`Detected audio mimetype: ${audioType}`); - } - - // Upload to cloud storage - const [videoAttrs, audioAttrs] = await Promise.all([ - recordings.upload(videoKey, videoBuffer, { contentType: videoType }), - audioBuffer && audioType - ? recordings.upload(audioKey, audioBuffer, { contentType: audioType }) - : Promise.resolve(null), - ]); - - // Save metadata to database - const videoFile = await db.mediaFile.create({ - data: { - bucket: "recordings", - key: videoKey, - mimetype: videoType, - url: recordings.publicUrl(videoKey), - srcUrl: sourceUrl, - meetingRecordId, - fileSize: videoAttrs.size, - title: `Video ${new Date().toISOString().split('T')[0]}`, - description: `Video processed from ${sourceUrl}`, - }, - }); - - let audioFile; - if (audioBuffer && audioType) { - audioFile = await db.mediaFile.create({ - data: { - bucket: "recordings", - key: audioKey, - mimetype: audioType, - url: audioAttrs ? recordings.publicUrl(audioKey) : undefined, - srcUrl: sourceUrl, - meetingRecordId, - fileSize: audioAttrs?.size, - title: `Audio ${new Date().toISOString().split('T')[0]}`, - description: `Audio extracted from ${sourceUrl}`, - }, - }); - } - - return { - videoId: videoFile.id, - audioId: audioFile?.id, - videoUrl: videoFile.url || undefined, - audioUrl: audioFile?.url || undefined, - videoMimetype: videoFile.mimetype, - audioMimetype: audioFile?.mimetype, - }; -} diff --git a/package-lock.json b/package-lock.json index 99cc897..eb0fc97 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,49 +18,70 @@ "astro": "^5.4.2", "csv-parse": "^5.6.0", "date-fns": "^4.1.0", - "encore.dev": "^1.46.6", + "encore.dev": "^1.46.10", "ffmpeg": "^0.0.4", "file-type": "^20.4.0", "fluent-ffmpeg": "2.1.3", "knex": "^3.1.0", "mime-types": "^2.1.35", + "openai": "^4.87.3", "pg": "^8.11.3", - "prisma": "^6.4.1", + "prisma-docs-generator": "^0.8.0", + "prisma-json-types-generator": "^3.2.2", + "prisma-markdown": "^1.0.9", "puppeteer": "^24.4.0", "react": "^18", "react-dom": "^18", - "valibot": "^1.0.0-rc.3" + "valibot": "^1.0.0" }, "devDependencies": { + "@ianvs/prettier-plugin-sort-imports": "^4.4.1", "@types/fluent-ffmpeg": "^2.1.27", "@types/mime-types": "^2.1.4", "@types/node": "22.13.10", "@types/react": "^18", "@types/react-dom": "^18", - "prisma-json-types-generator": "^3.2.2", + "prettier": "^3.5.3", + "prisma": "^6.4.1", + "prisma-generator-typescript-interfaces": "^2.0.1", "typescript": "^5.2.2", "vitest": "3.0.8" } }, + "node_modules/@antfu/ni": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/@antfu/ni/-/ni-0.21.4.tgz", + "integrity": "sha512-O0Uv9LbLDSoEg26fnMDdDRiPwFJnQSoD4WnrflDwKCJm8Cx/0mV4cGxwBLXan5mGIrpK4Dd7vizf4rQm0QCEAA==", + "license": "MIT", + "bin": { + "na": "bin/na.mjs", + "nci": "bin/nci.mjs", + "ni": "bin/ni.mjs", + "nlx": "bin/nlx.mjs", + "nr": "bin/nr.mjs", + "nu": "bin/nu.mjs", + "nun": "bin/nun.mjs" + } + }, "node_modules/@astrojs/compiler": { - "version": "2.10.4", - "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.10.4.tgz", - "integrity": "sha512-86B3QGagP99MvSNwuJGiYSBHnh8nLvm2Q1IFI15wIUJJsPeQTO3eb2uwBmrqRsXykeR/mBzH8XCgz5AAt1BJrQ==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.11.0.tgz", + "integrity": "sha512-zZOO7i+JhojO8qmlyR/URui6LyfHJY6m+L9nwyX5GiKD78YoRaZ5tzz6X0fkl+5bD3uwlDHayf6Oe8Fu36RKNg==", "license": "MIT" }, "node_modules/@astrojs/internal-helpers": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.6.0.tgz", - "integrity": "sha512-XgHIJDQaGlFnTr0sDp1PiJrtqsWzbHP2qkTU+JpQ8SnBewKP2IKOe/wqCkl0CyfyRXRu3TSWu4t/cpYMVfuBNA==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.6.1.tgz", + "integrity": "sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A==", "license": "MIT" }, "node_modules/@astrojs/markdown-remark": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-6.2.0.tgz", - "integrity": "sha512-LUDjgd9p1yG0qTFSocaj3GOLmZs8Hsw/pNtvqzvNY58Acebxvb/46vDO/e/wxYgsKgIfWS+p+ZI5SfOjoVrbCg==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-6.2.1.tgz", + "integrity": "sha512-qtQXfZXeG84XSH9bMgG2e/kZfA4J7U19PKjhmFDNsKX47nautSHC0DitvxaWgQFSED66k6hWKDHLq3VKHCy/rg==", "license": "MIT", "dependencies": { - "@astrojs/internal-helpers": "0.6.0", + "@astrojs/internal-helpers": "0.6.1", "@astrojs/prism": "3.2.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", @@ -70,7 +91,7 @@ "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", - "remark-gfm": "^4.0.0", + "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.1", "remark-smartypants": "^3.0.2", @@ -84,12 +105,12 @@ } }, "node_modules/@astrojs/node": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@astrojs/node/-/node-9.1.2.tgz", - "integrity": "sha512-MsKi741hLkRqzdtIqbrj82wmB+mQfKuSLD++hQZVBd5kU8FBNnzscM8F2rfR+KMtXSMxwLVVVT9MQ1x4rseAkg==", + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/@astrojs/node/-/node-9.1.3.tgz", + "integrity": "sha512-YcVxEmeZU8khNdrPYNPN3j//4tYPM+Pw6CthAJ6VE/bw65qEX7ErMRApalY2tibc3YhCeHMmsO9rXGhyW0NNyA==", "license": "MIT", "dependencies": { - "@astrojs/internal-helpers": "0.6.0", + "@astrojs/internal-helpers": "0.6.1", "send": "^1.1.0", "server-destroy": "^1.0.1" }, @@ -141,6 +162,23 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/generator": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.10.tgz", + "integrity": "sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.26.10", + "@babel/types": "^7.26.10", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-string-parser": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", @@ -160,12 +198,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz", - "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz", + "integrity": "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==", "license": "MIT", "dependencies": { - "@babel/types": "^7.26.9" + "@babel/types": "^7.26.10" }, "bin": { "parser": "bin/babel-parser.js" @@ -174,10 +212,44 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/types": { + "node_modules/@babel/template": { "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz", - "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", + "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.26.9", + "@babel/types": "^7.26.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.10.tgz", + "integrity": "sha512-k8NuDrxr0WrPH5Aupqb2LCVURP/S0vBEn5mK6iH+GIYob66U5EtoZvcdudR2jQ4cmTwhEwW1DLB+Yyas9zjF6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.10", + "@babel/parser": "^7.26.10", + "@babel/template": "^7.26.9", + "@babel/types": "^7.26.10", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz", + "integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -200,9 +272,9 @@ "license": "MIT" }, "node_modules/@dotenvx/dotenvx": { - "version": "1.38.4", - "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.38.4.tgz", - "integrity": "sha512-5rl1W5uMgSMrjluMqOf0FmUC6DILlR9Iy+6WzJIzt8qAON6gSbNZEkDG7MtktbK8g6QgQm9mMwaGgjW4DeU9Gw==", + "version": "1.38.5", + "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.38.5.tgz", + "integrity": "sha512-NAmo2Esp7vfOvagkTK2lBU9ptWCojPzFvI2slLtoGNH1hebMX9JWBHkByUGPYgAOnPZN5F4uGxVBGWQNyXse4Q==", "license": "BSD-3-Clause", "dependencies": { "commander": "^11.1.0", @@ -223,39 +295,6 @@ "url": "https://dotenvx.com" } }, - "node_modules/@dotenvx/dotenvx/node_modules/commander": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", - "license": "MIT", - "engines": { - "node": ">=16" - } - }, - "node_modules/@dotenvx/dotenvx/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "license": "ISC", - "engines": { - "node": ">=16" - } - }, - "node_modules/@dotenvx/dotenvx/node_modules/which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "license": "ISC", - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^16.13.0 || >=18.0.0" - } - }, "node_modules/@ecies/ciphers": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@ecies/ciphers/-/ciphers-0.2.3.tgz", @@ -270,912 +309,674 @@ "@noble/ciphers": "^1.0.0" } }, - "node_modules/@emnapi/runtime": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz", - "integrity": "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz", - "integrity": "sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz", + "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==", "cpu": [ - "ppc64" + "arm64" ], "license": "MIT", "optional": true, "os": [ - "aix" + "darwin" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.0.tgz", - "integrity": "sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" + "node_modules/@ianvs/prettier-plugin-sort-imports": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@ianvs/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.4.1.tgz", + "integrity": "sha512-F0/Hrcfpy8WuxlQyAWJTEren/uxKhYonOGY4OyWmwRdeTvkh9mMSCxowZLjNkhwi/2ipqCgtXwwOk7tW0mWXkA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@babel/generator": "^7.26.2", + "@babel/parser": "^7.26.2", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", + "semver": "^7.5.2" + }, + "peerDependencies": { + "@vue/compiler-sfc": "2.7.x || 3.x", + "prettier": "2 || 3" + }, + "peerDependenciesMeta": { + "@vue/compiler-sfc": { + "optional": true + } } }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.0.tgz", - "integrity": "sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==", + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", + "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", "cpu": [ "arm64" ], - "license": "MIT", + "license": "Apache-2.0", "optional": true, "os": [ - "android" + "darwin" ], "engines": { - "node": ">=18" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.4" } }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.0.tgz", - "integrity": "sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==", + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", + "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", "cpu": [ - "x64" + "arm64" ], - "license": "MIT", + "license": "LGPL-3.0-or-later", "optional": true, "os": [ - "android" + "darwin" ], - "engines": { - "node": ">=18" + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.0.tgz", - "integrity": "sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==", - "cpu": [ - "arm64" - ], + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, "engines": { - "node": ">=18" + "node": ">=6.0.0" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.0.tgz", - "integrity": "sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==", - "cpu": [ - "x64" - ], + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], "engines": { - "node": ">=18" + "node": ">=6.0.0" } }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.0.tgz", - "integrity": "sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==", - "cpu": [ - "arm64" - ], + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], "engines": { - "node": ">=18" + "node": ">=6.0.0" } }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.0.tgz", - "integrity": "sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==", - "cpu": [ - "x64" - ], + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.0.tgz", - "integrity": "sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==", - "cpu": [ - "arm" - ], + "node_modules/@noble/ciphers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.2.1.tgz", + "integrity": "sha512-rONPWMC7PeExE077uLE4oqWrZ1IvAfz3oH9LibVAcVCopJiA9R62uavnbEzdkVmJYI6M6Zgkbeb07+tWjlq2XA==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], "engines": { - "node": ">=18" + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.0.tgz", - "integrity": "sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==", - "cpu": [ - "arm64" - ], + "node_modules/@noble/curves": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.1.tgz", + "integrity": "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@noble/hashes": "1.7.1" + }, "engines": { - "node": ">=18" + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.0.tgz", - "integrity": "sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==", - "cpu": [ - "ia32" - ], + "node_modules/@noble/hashes": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz", + "integrity": "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], "engines": { - "node": ">=18" + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.0.tgz", - "integrity": "sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==", - "cpu": [ - "loong64" - ], + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, "engines": { - "node": ">=18" + "node": ">= 8" } }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.0.tgz", - "integrity": "sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==", - "cpu": [ - "mips64el" - ], + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], "engines": { - "node": ">=18" + "node": ">= 8" } }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.0.tgz", - "integrity": "sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==", - "cpu": [ - "ppc64" - ], + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, "engines": { - "node": ">=18" + "node": ">= 8" } }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.0.tgz", - "integrity": "sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "node_modules/@opentelemetry/api": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.4.1.tgz", + "integrity": "sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA==", + "license": "Apache-2.0", "engines": { - "node": ">=18" + "node": ">=8.0.0" } }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.0.tgz", - "integrity": "sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.0.tgz", - "integrity": "sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.0.tgz", - "integrity": "sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.0.tgz", - "integrity": "sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.0.tgz", - "integrity": "sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } + "node_modules/@oslojs/encoding": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz", + "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==", + "license": "MIT" }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.0.tgz", - "integrity": "sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], + "node_modules/@prisma/client": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.5.0.tgz", + "integrity": "sha512-M6w1Ql/BeiGoZmhMdAZUXHu5sz5HubyVcKukbLs3l0ELcQb8hTUJxtGEChhv4SVJ0QJlwtLnwOLgIRQhpsm9dw==", + "hasInstallScript": true, + "license": "Apache-2.0", "engines": { - "node": ">=18" + "node": ">=18.18" + }, + "peerDependencies": { + "prisma": "*", + "typescript": ">=5.1.0" + }, + "peerDependenciesMeta": { + "prisma": { + "optional": true + }, + "typescript": { + "optional": true + } } }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.0.tgz", - "integrity": "sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" + "node_modules/@prisma/config": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.5.0.tgz", + "integrity": "sha512-sOH/2Go9Zer67DNFLZk6pYOHj+rumSb0VILgltkoxOjYnlLqUpHPAN826vnx8HigqnOCxj9LRhT6U7uLiIIWgw==", + "license": "Apache-2.0", + "dependencies": { + "esbuild": ">=0.12 <1", + "esbuild-register": "3.6.0" } }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.0.tgz", - "integrity": "sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } + "node_modules/@prisma/debug": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.5.0.tgz", + "integrity": "sha512-fc/nusYBlJMzDmDepdUtH9aBsJrda2JNErP9AzuHbgUEQY0/9zQYZdNlXmKoIWENtio+qarPNe/+DQtrX5kMcQ==", + "license": "Apache-2.0" }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.0.tgz", - "integrity": "sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" + "node_modules/@prisma/engines": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.5.0.tgz", + "integrity": "sha512-FVPQYHgOllJklN9DUyujXvh3hFJCY0NX86sDmBErLvoZjy2OXGiZ5FNf3J/C4/RZZmCypZBYpBKEhx7b7rEsdw==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "6.5.0", + "@prisma/engines-version": "6.5.0-73.173f8d54f8d52e692c7e27e72a88314ec7aeff60", + "@prisma/fetch-engine": "6.5.0", + "@prisma/get-platform": "6.5.0" } }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.0.tgz", - "integrity": "sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } + "node_modules/@prisma/engines-version": { + "version": "6.5.0-73.173f8d54f8d52e692c7e27e72a88314ec7aeff60", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.5.0-73.173f8d54f8d52e692c7e27e72a88314ec7aeff60.tgz", + "integrity": "sha512-iK3EmiVGFDCmXjSpdsKGNqy9hOdLnvYBrJB61far/oP03hlIxrb04OWmDjNTwtmZ3UZdA5MCvI+f+3k2jPTflQ==", + "license": "Apache-2.0" }, - "node_modules/@img/sharp-darwin-arm64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", - "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", - "cpu": [ - "arm64" - ], + "node_modules/@prisma/fetch-engine": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.5.0.tgz", + "integrity": "sha512-3LhYA+FXP6pqY8FLHCjewyE8pGXXJ7BxZw2rhPq+CZAhvflVzq4K8Qly3OrmOkn6wGlz79nyLQdknyCG2HBTuA==", "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.0.4" + "dependencies": { + "@prisma/debug": "6.5.0", + "@prisma/engines-version": "6.5.0-73.173f8d54f8d52e692c7e27e72a88314ec7aeff60", + "@prisma/get-platform": "6.5.0" } }, - "node_modules/@img/sharp-darwin-x64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", - "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", - "cpu": [ - "x64" - ], + "node_modules/@prisma/generator-helper": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@prisma/generator-helper/-/generator-helper-6.0.0.tgz", + "integrity": "sha512-5DkG7hspZo6U4OtqI2W0JcgtY37sr7HgT8Q0W/sjL4VoV4px6ivzK6Eif5bKM7q+S4yFUHtjUt/3s69ErfLn7A==", "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.0.4" - } - }, - "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", - "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" + "dependencies": { + "@prisma/debug": "6.0.0" } }, - "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", - "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } + "node_modules/@prisma/generator-helper/node_modules/@prisma/debug": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.0.0.tgz", + "integrity": "sha512-eUjoNThlDXdyJ1iQ2d7U6aTVwm59EwvODb5zFVNJEokNoSiQmiYWNzZIwZyDmZ+j51j42/0iTaHIJ4/aZPKFRg==", + "license": "Apache-2.0" }, - "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", - "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", - "cpu": [ - "arm" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" + "node_modules/@prisma/get-platform": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.5.0.tgz", + "integrity": "sha512-xYcvyJwNMg2eDptBYFqFLUCfgi+wZLcj6HDMsj0Qw0irvauG4IKmkbywnqwok0B+k+W+p+jThM2DKTSmoPCkzw==", + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "6.5.0" } }, - "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", - "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" + "node_modules/@prisma/internals": { + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/@prisma/internals/-/internals-4.16.2.tgz", + "integrity": "sha512-/3OiSADA3RRgsaeEE+MDsBgL6oAMwddSheXn6wtYGUnjERAV/BmF5bMMLnTykesQqwZ1s8HrISrJ0Vf6cjOxMg==", + "license": "Apache-2.0", + "dependencies": { + "@antfu/ni": "0.21.4", + "@opentelemetry/api": "1.4.1", + "@prisma/debug": "4.16.2", + "@prisma/engines": "4.16.2", + "@prisma/fetch-engine": "4.16.2", + "@prisma/generator-helper": "4.16.2", + "@prisma/get-platform": "4.16.2", + "@prisma/prisma-fmt-wasm": "4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81", + "archiver": "5.3.1", + "arg": "5.0.2", + "checkpoint-client": "1.1.24", + "cli-truncate": "2.1.0", + "dotenv": "16.0.3", + "escape-string-regexp": "4.0.0", + "execa": "5.1.1", + "find-up": "5.0.0", + "fp-ts": "2.16.0", + "fs-extra": "11.1.1", + "fs-jetpack": "5.1.0", + "global-dirs": "3.0.1", + "globby": "11.1.0", + "indent-string": "4.0.0", + "is-windows": "1.0.2", + "is-wsl": "2.2.0", + "kleur": "4.1.5", + "new-github-issue-url": "0.2.1", + "node-fetch": "2.6.11", + "npm-packlist": "5.1.3", + "open": "7.4.2", + "p-map": "4.0.0", + "prompts": "2.4.2", + "read-pkg-up": "7.0.1", + "replace-string": "3.1.0", + "resolve": "1.22.2", + "string-width": "4.2.3", + "strip-ansi": "6.0.1", + "strip-indent": "3.0.0", + "temp-dir": "2.0.0", + "temp-write": "4.0.0", + "tempy": "1.0.1", + "terminal-link": "2.1.1", + "tmp": "0.2.1", + "ts-pattern": "4.3.0" + } + }, + "node_modules/@prisma/internals/node_modules/@prisma/debug": { + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-4.16.2.tgz", + "integrity": "sha512-7L7WbG0qNNZYgLpsVB8rCHCXEyHFyIycRlRDNwkVfjQmACC2OW6AWCYCbfdjQhkF/t7+S3njj8wAWAocSs+Brw==", + "license": "Apache-2.0", + "dependencies": { + "@types/debug": "4.1.8", + "debug": "4.3.4", + "strip-ansi": "6.0.1" } }, - "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", - "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", - "cpu": [ - "s390x" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } + "node_modules/@prisma/internals/node_modules/@prisma/engines": { + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.16.2.tgz", + "integrity": "sha512-vx1nxVvN4QeT/cepQce68deh/Turxy5Mr+4L4zClFuK1GlxN3+ivxfuv+ej/gvidWn1cE1uAhW7ALLNlYbRUAw==", + "hasInstallScript": true, + "license": "Apache-2.0" }, - "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", - "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" + "node_modules/@prisma/internals/node_modules/@prisma/fetch-engine": { + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-4.16.2.tgz", + "integrity": "sha512-lnCnHcOaNn0kw8qTJbVcNhyfIf5Lus2GFXbj3qpkdKEIB9xLgqkkuTP+35q1xFaqwQ0vy4HFpdRUpFP7njE15g==", + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "4.16.2", + "@prisma/get-platform": "4.16.2", + "execa": "5.1.1", + "find-cache-dir": "3.3.2", + "fs-extra": "11.1.1", + "hasha": "5.2.2", + "http-proxy-agent": "7.0.0", + "https-proxy-agent": "7.0.0", + "kleur": "4.1.5", + "node-fetch": "2.6.11", + "p-filter": "2.1.0", + "p-map": "4.0.0", + "p-retry": "4.6.2", + "progress": "2.0.3", + "rimraf": "3.0.2", + "temp-dir": "2.0.0", + "tempy": "1.0.1" + } + }, + "node_modules/@prisma/internals/node_modules/@prisma/generator-helper": { + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/@prisma/generator-helper/-/generator-helper-4.16.2.tgz", + "integrity": "sha512-bMOH7y73Ui7gpQrioFeavMQA+Tf8ksaVf8Nhs9rQNzuSg8SSV6E9baczob0L5KGZTSgYoqnrRxuo03kVJYrnIg==", + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "4.16.2", + "@types/cross-spawn": "6.0.2", + "cross-spawn": "7.0.3", + "kleur": "4.1.5" } }, - "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", - "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" + "node_modules/@prisma/internals/node_modules/@prisma/get-platform": { + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-4.16.2.tgz", + "integrity": "sha512-fnDey1/iSefHJRMB+w243BhWENf+paRouPMdCqIVqu8dYkR1NqhldblsSUC4Zr2sKS7Ta2sK4OLdt9IH+PZTfw==", + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "4.16.2", + "escape-string-regexp": "4.0.0", + "execa": "5.1.1", + "fs-jetpack": "5.1.0", + "kleur": "4.1.5", + "replace-string": "3.1.0", + "strip-ansi": "6.0.1", + "tempy": "1.0.1", + "terminal-link": "2.1.1", + "ts-pattern": "4.3.0" } }, - "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", - "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" + "node_modules/@prisma/internals/node_modules/@types/debug": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz", + "integrity": "sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" } }, - "node_modules/@img/sharp-linux-arm": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", - "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", - "cpu": [ - "arm" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], + "node_modules/@prisma/internals/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.0.5" + "node": ">=8" } }, - "node_modules/@img/sharp-linux-arm64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", - "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" + "node_modules/@prisma/internals/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.0.4" - } - }, - "node_modules/@img/sharp-linux-s390x": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", - "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", - "cpu": [ - "s390x" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.0.4" + "node": ">= 8" } }, - "node_modules/@img/sharp-linux-x64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", - "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node_modules/@prisma/internals/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "license": "MIT", + "dependencies": { + "ms": "2.1.2" }, - "funding": { - "url": "https://opencollective.com/libvips" + "engines": { + "node": ">=6.0" }, - "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.0.4" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", - "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], + "node_modules/@prisma/internals/node_modules/dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "license": "BSD-2-Clause", "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" + "node": ">=12" } }, - "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", - "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], + "node_modules/@prisma/internals/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/@prisma/internals/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=10" }, "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.0.4" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@img/sharp-wasm32": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", - "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", - "cpu": [ - "wasm32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", - "optional": true, + "node_modules/@prisma/internals/node_modules/http-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", + "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "license": "MIT", "dependencies": { - "@emnapi/runtime": "^1.2.0" + "agent-base": "^7.1.0", + "debug": "^4.3.4" }, "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" + "node": ">= 14" } }, - "node_modules/@img/sharp-win32-ia32": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", - "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", - "cpu": [ - "ia32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node_modules/@prisma/internals/node_modules/https-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.0.tgz", + "integrity": "sha512-0euwPCRyAPSgGdzD1IVN9nJYHtBhJwb6XPfbpQcYbPCwrBidX6GzxmchnaF4sfF/jPb74Ojx5g4yTg3sixlyPw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-x64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", - "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" + "node": ">= 14" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "license": "MIT" - }, - "node_modules/@noble/ciphers": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.2.1.tgz", - "integrity": "sha512-rONPWMC7PeExE077uLE4oqWrZ1IvAfz3oH9LibVAcVCopJiA9R62uavnbEzdkVmJYI6M6Zgkbeb07+tWjlq2XA==", + "node_modules/@prisma/internals/node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "license": "MIT", "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" + "node": ">=8" } }, - "node_modules/@noble/curves": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.1.tgz", - "integrity": "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==", + "node_modules/@prisma/internals/node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "license": "MIT", - "dependencies": { - "@noble/hashes": "1.7.1" + "bin": { + "is-docker": "cli.js" }, "engines": { - "node": "^14.21.3 || >=16" + "node": ">=8" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@noble/hashes": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz", - "integrity": "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==", + "node_modules/@prisma/internals/node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" + "dependencies": { + "is-docker": "^2.0.0" }, - "funding": { - "url": "https://paulmillr.com/funding/" + "engines": { + "node": ">=8" } }, - "node_modules/@oslojs/encoding": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz", - "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==", + "node_modules/@prisma/internals/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/@prisma/internals/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "license": "MIT" }, - "node_modules/@prisma/client": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.4.1.tgz", - "integrity": "sha512-A7Mwx44+GVZVexT5e2GF/WcKkEkNNKbgr059xpr5mn+oUm2ZW1svhe+0TRNBwCdzhfIZ+q23jEgsNPvKD9u+6g==", - "hasInstallScript": true, - "license": "Apache-2.0", + "node_modules/@prisma/internals/node_modules/node-fetch": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, "engines": { - "node": ">=18.18" + "node": "4.x || >=6.0.0" }, "peerDependencies": { - "prisma": "*", - "typescript": ">=5.1.0" + "encoding": "^0.1.0" }, "peerDependenciesMeta": { - "prisma": { - "optional": true - }, - "typescript": { + "encoding": { "optional": true } } }, - "node_modules/@prisma/debug": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.4.1.tgz", - "integrity": "sha512-Q9xk6yjEGIThjSD8zZegxd5tBRNHYd13GOIG0nLsanbTXATiPXCLyvlYEfvbR2ft6dlRsziQXfQGxAgv7zcMUA==", - "license": "Apache-2.0" + "node_modules/@prisma/internals/node_modules/resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/@prisma/engines": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.4.1.tgz", - "integrity": "sha512-KldENzMHtKYwsOSLThghOIdXOBEsfDuGSrxAZjMnimBiDKd3AE4JQ+Kv+gBD/x77WoV9xIPf25GXMWffXZ17BA==", - "hasInstallScript": true, - "license": "Apache-2.0", + "node_modules/@prisma/internals/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", "dependencies": { - "@prisma/debug": "6.4.1", - "@prisma/engines-version": "6.4.0-29.a9055b89e58b4b5bfb59600785423b1db3d0e75d", - "@prisma/fetch-engine": "6.4.1", - "@prisma/get-platform": "6.4.1" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@prisma/engines-version": { - "version": "6.4.0-29.a9055b89e58b4b5bfb59600785423b1db3d0e75d", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.4.0-29.a9055b89e58b4b5bfb59600785423b1db3d0e75d.tgz", - "integrity": "sha512-Xq54qw55vaCGrGgIJqyDwOq0TtjZPJEWsbQAHugk99hpDf2jcEeQhUcF+yzEsSqegBaDNLA4IC8Nn34sXmkiTQ==", - "license": "Apache-2.0" - }, - "node_modules/@prisma/fetch-engine": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.4.1.tgz", - "integrity": "sha512-uZ5hVeTmDspx7KcaRCNoXmcReOD+84nwlO2oFvQPRQh9xiFYnnUKDz7l9bLxp8t4+25CsaNlgrgilXKSQwrIGQ==", - "license": "Apache-2.0", + "node_modules/@prisma/internals/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", "dependencies": { - "@prisma/debug": "6.4.1", - "@prisma/engines-version": "6.4.0-29.a9055b89e58b4b5bfb59600785423b1db3d0e75d", - "@prisma/get-platform": "6.4.1" + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@prisma/generator-helper": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@prisma/generator-helper/-/generator-helper-6.0.0.tgz", - "integrity": "sha512-5DkG7hspZo6U4OtqI2W0JcgtY37sr7HgT8Q0W/sjL4VoV4px6ivzK6Eif5bKM7q+S4yFUHtjUt/3s69ErfLn7A==", - "dev": true, - "license": "Apache-2.0", + "node_modules/@prisma/internals/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", "dependencies": { - "@prisma/debug": "6.0.0" + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/@prisma/generator-helper/node_modules/@prisma/debug": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.0.0.tgz", - "integrity": "sha512-eUjoNThlDXdyJ1iQ2d7U6aTVwm59EwvODb5zFVNJEokNoSiQmiYWNzZIwZyDmZ+j51j42/0iTaHIJ4/aZPKFRg==", - "dev": true, + "node_modules/@prisma/prisma-fmt-wasm": { + "version": "4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81", + "resolved": "https://registry.npmjs.org/@prisma/prisma-fmt-wasm/-/prisma-fmt-wasm-4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81.tgz", + "integrity": "sha512-g090+dEH7wrdCw359+8J9+TGH84qK28V/dxwINjhhNCtju9lej99z9w/AVsJP9UhhcCPS4psYz4iu8d53uxVpA==", "license": "Apache-2.0" }, - "node_modules/@prisma/get-platform": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.4.1.tgz", - "integrity": "sha512-gXqZaDI5scDkBF8oza7fOD3Q3QMD0e0rBynlzDDZdTWbWmzjuW58PRZtj+jkvKje2+ZigCWkH8SsWZAsH6q1Yw==", - "license": "Apache-2.0", - "dependencies": { - "@prisma/debug": "6.4.1" - } - }, "node_modules/@puppeteer/browsers": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.8.0.tgz", @@ -1225,32 +1026,6 @@ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "license": "MIT" }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.35.0.tgz", - "integrity": "sha512-uYQ2WfPaqz5QtVgMxfN6NpLD+no0MYHDBywl7itPYd3K5TjjSghNKmX8ic9S8NU8w81NVhJv/XojcHptRly7qQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.35.0.tgz", - "integrity": "sha512-FtKddj9XZudurLhdJnBl9fl6BwCJ3ky8riCXjEw3/UIbjmIY58ppWwPEvU3fNu+W7FUsAsB1CdH+7EQE6CXAPA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, "node_modules/@rollup/rollup-darwin-arm64": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.35.0.tgz", @@ -1264,214 +1039,6 @@ "darwin" ] }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.35.0.tgz", - "integrity": "sha512-3IrHjfAS6Vkp+5bISNQnPogRAW5GAV1n+bNCrDwXmfMHbPl5EhTmWtfmwlJxFRUCBZ+tZ/OxDyU08aF6NI/N5Q==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.35.0.tgz", - "integrity": "sha512-sxjoD/6F9cDLSELuLNnY0fOrM9WA0KrM0vWm57XhrIMf5FGiN8D0l7fn+bpUeBSU7dCgPV2oX4zHAsAXyHFGcQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.35.0.tgz", - "integrity": "sha512-2mpHCeRuD1u/2kruUiHSsnjWtHjqVbzhBkNVQ1aVD63CcexKVcQGwJ2g5VphOd84GvxfSvnnlEyBtQCE5hxVVw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.35.0.tgz", - "integrity": "sha512-mrA0v3QMy6ZSvEuLs0dMxcO2LnaCONs1Z73GUDBHWbY8tFFocM6yl7YyMu7rz4zS81NDSqhrUuolyZXGi8TEqg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.35.0.tgz", - "integrity": "sha512-DnYhhzcvTAKNexIql8pFajr0PiDGrIsBYPRvCKlA5ixSS3uwo/CWNZxB09jhIapEIg945KOzcYEAGGSmTSpk7A==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.35.0.tgz", - "integrity": "sha512-uagpnH2M2g2b5iLsCTZ35CL1FgyuzzJQ8L9VtlJ+FckBXroTwNOaD0z0/UF+k5K3aNQjbm8LIVpxykUOQt1m/A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.35.0.tgz", - "integrity": "sha512-XQxVOCd6VJeHQA/7YcqyV0/88N6ysSVzRjJ9I9UA/xXpEsjvAgDTgH3wQYz5bmr7SPtVK2TsP2fQ2N9L4ukoUg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.35.0.tgz", - "integrity": "sha512-5pMT5PzfgwcXEwOaSrqVsz/LvjDZt+vQ8RT/70yhPU06PTuq8WaHhfT1LW+cdD7mW6i/J5/XIkX/1tCAkh1W6g==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.35.0.tgz", - "integrity": "sha512-c+zkcvbhbXF98f4CtEIP1EBA/lCic5xB0lToneZYvMeKu5Kamq3O8gqrxiYYLzlZH6E3Aq+TSW86E4ay8iD8EA==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.35.0.tgz", - "integrity": "sha512-s91fuAHdOwH/Tad2tzTtPX7UZyytHIRR6V4+2IGlV0Cej5rkG0R61SX4l4y9sh0JBibMiploZx3oHKPnQBKe4g==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.35.0.tgz", - "integrity": "sha512-hQRkPQPLYJZYGP+Hj4fR9dDBMIM7zrzJDWFEMPdTnTy95Ljnv0/4w/ixFw3pTBMEuuEuoqtBINYND4M7ujcuQw==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.35.0.tgz", - "integrity": "sha512-Pim1T8rXOri+0HmV4CdKSGrqcBWX0d1HoPnQ0uw0bdp1aP5SdQVNBy8LjYncvnLgu3fnnCt17xjWGd4cqh8/hA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.35.0.tgz", - "integrity": "sha512-QysqXzYiDvQWfUiTm8XmJNO2zm9yC9P/2Gkrwg2dH9cxotQzunBHYr6jk4SujCTqnfGxduOmQcI7c2ryuW8XVg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.35.0.tgz", - "integrity": "sha512-OUOlGqPkVJCdJETKOCEf1mw848ZyJ5w50/rZ/3IBQVdLfR5jk/6Sr5m3iO2tdPgwo0x7VcncYuOvMhBWZq8ayg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.35.0.tgz", - "integrity": "sha512-2/lsgejMrtwQe44glq7AFFHLfJBPafpsTa6JvP2NGef/ifOa4KBoglVf7AKN7EV9o32evBPRqfg96fEHzWo5kw==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.35.0.tgz", - "integrity": "sha512-PIQeY5XDkrOysbQblSW7v3l1MDZzkTEzAfTPkj5VAu3FW8fS4ynyLg2sINp0fp3SjZ8xkRYpLqoKcYqAkhU1dw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@shikijs/core": { "version": "1.29.2", "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.29.2.tgz", @@ -1577,6 +1144,15 @@ "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", "license": "MIT" }, + "node_modules/@types/cross-spawn": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.2.tgz", + "integrity": "sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/debug": { "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", @@ -1627,6 +1203,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", + "license": "MIT" + }, "node_modules/@types/ms": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", @@ -1646,12 +1228,27 @@ "version": "22.13.10", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz", "integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==", - "devOptional": true, "license": "MIT", "dependencies": { "undici-types": "~6.20.0" } }, + "node_modules/@types/node-fetch": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.0" + } + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "license": "MIT" + }, "node_modules/@types/prop-types": { "version": "15.7.14", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", @@ -1680,6 +1277,12 @@ "@types/react": "^18.0.0" } }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "license": "MIT" + }, "node_modules/@types/unist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", @@ -1821,6 +1424,31 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/acorn": { "version": "8.14.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", @@ -1839,7 +1467,41 @@ "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", "license": "MIT", "engines": { - "node": ">= 14" + "node": ">= 14" + } + }, + "node_modules/agentkeepalive": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", + "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", + "license": "MIT", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/aggregate-error/node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "license": "MIT", + "engines": { + "node": ">=8" } }, "node_modules/ansi-align": { @@ -1892,6 +1554,33 @@ "node": ">=8" } }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", @@ -1941,6 +1630,103 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/archiver": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.1.tgz", + "integrity": "sha512-8KyabkmbYrH+9ibcTScQ1xCJC/CGcugdVIwB+53f5sZziXgwUh3iXlAlANMxcZyDEfTHMe6+Z5FofV8nopXP7w==", + "license": "MIT", + "dependencies": { + "archiver-utils": "^2.1.0", + "async": "^3.2.3", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.0.0", + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "license": "MIT", + "dependencies": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/archiver-utils/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/archiver-utils/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/archiver-utils/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/archiver/node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" + }, + "node_modules/archiver/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT" + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1956,6 +1742,12 @@ "node": ">= 0.4" } }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" + }, "node_modules/array-iterate": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-2.0.1.tgz", @@ -1966,6 +1758,24 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", @@ -1988,15 +1798,24 @@ "node": ">=4" } }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/astro": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/astro/-/astro-5.4.2.tgz", - "integrity": "sha512-9Z3fAniIRJaK/o43OroZA1wHUIU+qHiOR9ovlVT/2XQaN25QRXScIsKWlFp0G/zrx5OuuoJ+QnaoHHW061u26A==", + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/astro/-/astro-5.4.3.tgz", + "integrity": "sha512-GKkOJQCHLx6CrPoghGhj7824WDSvIuuc+HTVjfjMPdB9axp238iJLByREJNDaSdzMeR/lC13xvBiUnKvcYyEIA==", "license": "MIT", "dependencies": { "@astrojs/compiler": "^2.10.4", - "@astrojs/internal-helpers": "0.6.0", - "@astrojs/markdown-remark": "6.2.0", + "@astrojs/internal-helpers": "0.6.1", + "@astrojs/markdown-remark": "6.2.1", "@astrojs/telemetry": "3.2.0", "@oslojs/encoding": "^1.1.0", "@rollup/pluginutils": "^5.1.4", @@ -2031,8 +1850,8 @@ "neotraverse": "^0.6.18", "p-limit": "^6.2.0", "p-queue": "^8.1.0", + "package-manager-detector": "^1.0.0", "picomatch": "^4.0.2", - "preferred-pm": "^4.1.1", "prompts": "^2.4.2", "rehype": "^13.0.2", "semver": "^7.7.1", @@ -2046,7 +1865,6 @@ "vfile": "^6.0.3", "vite": "^6.2.0", "vitefu": "^1.0.6", - "which-pm": "^3.0.1", "xxhash-wasm": "^1.1.0", "yargs-parser": "^21.1.1", "yocto-spinner": "^0.2.1", @@ -2173,6 +1991,12 @@ "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", "integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==" }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, "node_modules/axobject-query": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", @@ -2198,6 +2022,12 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, "node_modules/bare-events": { "version": "2.5.4", "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.4.tgz", @@ -2221,9 +2051,9 @@ } }, "node_modules/bare-os": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.5.1.tgz", - "integrity": "sha512-LvfVNDcWLw2AnIw5f2mWUgumW3I3N/WYGiWeimhQC1Ybt71n2FjlS9GJKeCnFeg1MKZHxzIFmpFnBXDI+sBeFg==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.0.tgz", + "integrity": "sha512-BUrFS5TqSBdA0LwHop4OjPJwisqxGy6JsWVqV6qaFoe965qqtaKfDzHY5T2YA1gUL0ZeeQeA+4BBc1FJTcHiPw==", "license": "Apache-2.0", "optional": true, "engines": { @@ -2268,6 +2098,26 @@ "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==", "license": "MIT" }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/basic-ftp": { "version": "5.0.5", "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", @@ -2277,6 +2127,56 @@ "node": ">=10.0.0" } }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, "node_modules/boxen": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/boxen/-/boxen-8.0.1.tgz", @@ -2299,6 +2199,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", @@ -2311,6 +2220,30 @@ "node": ">=8" } }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", @@ -2320,6 +2253,15 @@ "node": "*" } }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -2330,6 +2272,35 @@ "node": ">=8" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -2351,6 +2322,32 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "license": "MIT", + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-keys/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/ccount": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", @@ -2430,6 +2427,56 @@ "node": ">= 16" } }, + "node_modules/checkpoint-client": { + "version": "1.1.24", + "resolved": "https://registry.npmjs.org/checkpoint-client/-/checkpoint-client-1.1.24.tgz", + "integrity": "sha512-nIOlLhDS7MKs4tUzS3LCm+sE1NgTCVnVrXlD0RRxaoEkkLu8LIWSUNiNWai6a+LK5unLzTyZeTCYX1Smqy0YoA==", + "license": "MIT", + "dependencies": { + "ci-info": "3.8.0", + "env-paths": "2.2.1", + "fast-write-atomic": "0.2.1", + "make-dir": "3.1.0", + "ms": "2.1.3", + "node-fetch": "2.6.11", + "uuid": "9.0.0" + } + }, + "node_modules/checkpoint-client/node_modules/ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/checkpoint-client/node_modules/node-fetch": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/chokidar": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", @@ -2454,35 +2501,101 @@ "mitt": "^3.0.1", "zod": "^3.24.1" }, - "peerDependencies": { - "devtools-protocol": "*" + "peerDependencies": { + "devtools-protocol": "*" + } + }, + "node_modules/ci-info": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.2.0.tgz", + "integrity": "sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "license": "MIT", + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ci-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.1.0.tgz", - "integrity": "sha512-HutrvTNsF48wnxkzERIXOe5/mlcfFcbfCmwcg6CJnizbSue78AbDt+1cgl26zwn61WFxhcPykPfZrbqjGmBb4A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/cli-boxes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", - "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, "engines": { - "node": ">=10" + "node": ">=8" + } + }, + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=8" } }, "node_modules/cliui": { @@ -2630,6 +2743,18 @@ "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", "license": "MIT" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/comma-separated-tokens": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", @@ -2641,12 +2766,12 @@ } }, "node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", "license": "MIT", "engines": { - "node": ">=14" + "node": ">=16" } }, "node_modules/common-ancestor-path": { @@ -2655,6 +2780,54 @@ "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==", "license": "ISC" }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "license": "MIT" + }, + "node_modules/compress-commons": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz", + "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==", + "license": "MIT", + "dependencies": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^4.0.2", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/cookie": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", @@ -2670,6 +2843,18 @@ "integrity": "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==", "license": "MIT" }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "license": "MIT" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, "node_modules/cosmiconfig": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", @@ -2696,6 +2881,31 @@ } } }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/crc32-stream": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz", + "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==", + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -2710,6 +2920,12 @@ "node": ">= 8" } }, + "node_modules/cross-spawn/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, "node_modules/cross-spawn/node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -2734,6 +2950,15 @@ "uncrypto": "^0.1.3" } }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -2795,6 +3020,40 @@ } } }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "license": "MIT", + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/decode-named-character-reference": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.1.0.tgz", @@ -2838,6 +3097,37 @@ "node": ">= 14" } }, + "node_modules/del": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", + "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", + "license": "MIT", + "dependencies": { + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.2", + "p-map": "^4.0.0", + "rimraf": "^3.0.2", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -2928,6 +3218,18 @@ "node": ">=0.3.1" } }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", @@ -2955,6 +3257,20 @@ "node": ">=4" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/eciesjs": { "version": "0.4.14", "resolved": "https://registry.npmjs.org/eciesjs/-/eciesjs-0.4.14.tgz", @@ -3000,9 +3316,9 @@ } }, "node_modules/encore.dev": { - "version": "1.46.6", - "resolved": "https://registry.npmjs.org/encore.dev/-/encore.dev-1.46.6.tgz", - "integrity": "sha512-LX2eZXCdiF1qV9vvchZlx5RXU4I8c1AtFPVStAT0bo4YBT1mTGB+JJkl1q7NMr4yzFW+gJtFJONyb3hDyZcE7w==", + "version": "1.46.10", + "resolved": "https://registry.npmjs.org/encore.dev/-/encore.dev-1.46.10.tgz", + "integrity": "sha512-eUY7oYozfpgHR03V8yAn78Fum4bh8F/NgF8B6cMyVT6eJfiqMSLlaYLUfd2TcBv+febbhgyz+tyLj3p91UVv6Q==", "license": "MPL-2.0", "engines": { "node": ">=18.0.0" @@ -3047,16 +3363,61 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-module-lexer": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", "license": "MIT" }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/esbuild": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz", - "integrity": "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz", + "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==", "hasInstallScript": true, "license": "MIT", "bin": { @@ -3066,31 +3427,31 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.0", - "@esbuild/android-arm": "0.25.0", - "@esbuild/android-arm64": "0.25.0", - "@esbuild/android-x64": "0.25.0", - "@esbuild/darwin-arm64": "0.25.0", - "@esbuild/darwin-x64": "0.25.0", - "@esbuild/freebsd-arm64": "0.25.0", - "@esbuild/freebsd-x64": "0.25.0", - "@esbuild/linux-arm": "0.25.0", - "@esbuild/linux-arm64": "0.25.0", - "@esbuild/linux-ia32": "0.25.0", - "@esbuild/linux-loong64": "0.25.0", - "@esbuild/linux-mips64el": "0.25.0", - "@esbuild/linux-ppc64": "0.25.0", - "@esbuild/linux-riscv64": "0.25.0", - "@esbuild/linux-s390x": "0.25.0", - "@esbuild/linux-x64": "0.25.0", - "@esbuild/netbsd-arm64": "0.25.0", - "@esbuild/netbsd-x64": "0.25.0", - "@esbuild/openbsd-arm64": "0.25.0", - "@esbuild/openbsd-x64": "0.25.0", - "@esbuild/sunos-x64": "0.25.0", - "@esbuild/win32-arm64": "0.25.0", - "@esbuild/win32-ia32": "0.25.0", - "@esbuild/win32-x64": "0.25.0" + "@esbuild/aix-ppc64": "0.25.1", + "@esbuild/android-arm": "0.25.1", + "@esbuild/android-arm64": "0.25.1", + "@esbuild/android-x64": "0.25.1", + "@esbuild/darwin-arm64": "0.25.1", + "@esbuild/darwin-x64": "0.25.1", + "@esbuild/freebsd-arm64": "0.25.1", + "@esbuild/freebsd-x64": "0.25.1", + "@esbuild/linux-arm": "0.25.1", + "@esbuild/linux-arm64": "0.25.1", + "@esbuild/linux-ia32": "0.25.1", + "@esbuild/linux-loong64": "0.25.1", + "@esbuild/linux-mips64el": "0.25.1", + "@esbuild/linux-ppc64": "0.25.1", + "@esbuild/linux-riscv64": "0.25.1", + "@esbuild/linux-s390x": "0.25.1", + "@esbuild/linux-x64": "0.25.1", + "@esbuild/netbsd-arm64": "0.25.1", + "@esbuild/netbsd-x64": "0.25.1", + "@esbuild/openbsd-arm64": "0.25.1", + "@esbuild/openbsd-x64": "0.25.1", + "@esbuild/sunos-x64": "0.25.1", + "@esbuild/win32-arm64": "0.25.1", + "@esbuild/win32-ia32": "0.25.1", + "@esbuild/win32-x64": "0.25.1" } }, "node_modules/esbuild-register": { @@ -3211,6 +3572,15 @@ "node": ">= 0.6" } }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", @@ -3240,18 +3610,6 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/execa/node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/expect-type": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.0.tgz", @@ -3259,7 +3617,110 @@ "dev": true, "license": "Apache-2.0", "engines": { - "node": ">=12.0.0" + "node": ">=12.0.0" + } + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/express/node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/express/node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" } }, "node_modules/extend": { @@ -3288,12 +3749,58 @@ "@types/yauzl": "^2.9.1" } }, + "node_modules/extract-zip/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/fast-fifo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", "license": "MIT" }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-write-atomic": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fast-write-atomic/-/fast-write-atomic-0.2.1.tgz", + "integrity": "sha512-WvJe06IfNYlr+6cO3uQkdKdy3Cb1LlCJSF8zRs2eT8yuhdbSlR9nIt+TgQ92RUxiRrQm+/S7RARnMfCs5iuAjw==", + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", @@ -3361,39 +3868,70 @@ "node": ">=8" } }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "license": "MIT", "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" }, "engines": { - "node": ">=8" + "node": ">= 0.8" } }, - "node_modules/find-up-simple": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", - "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "license": "MIT", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, "engines": { - "node": ">=18" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, - "node_modules/find-yarn-workspace-root2": { - "version": "1.2.16", - "resolved": "https://registry.npmjs.org/find-yarn-workspace-root2/-/find-yarn-workspace-root2-1.2.16.tgz", - "integrity": "sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==", - "license": "Apache-2.0", + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "license": "MIT", "dependencies": { - "micromatch": "^4.0.2", - "pkg-dir": "^4.2.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/flattie": { @@ -3418,6 +3956,73 @@ "node": ">=18" } }, + "node_modules/fluent-ffmpeg/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/fluent-ffmpeg/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/form-data": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/form-data-encoder": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", + "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==", + "license": "MIT" + }, + "node_modules/formdata-node": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", + "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", + "license": "MIT", + "dependencies": { + "node-domexception": "1.0.0", + "web-streams-polyfill": "4.0.0-beta.3" + }, + "engines": { + "node": ">= 12.20" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fp-ts": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-2.16.0.tgz", + "integrity": "sha512-bLq+KgbiXdTEoT1zcARrWEpa5z6A/8b7PcDW7Gef3NSisQ+VS7ll2Xbf1E+xsgik0rWub/8u0qP/iTTjj+PhxQ==", + "license": "MIT" + }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -3427,6 +4032,41 @@ "node": ">= 0.6" } }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "license": "MIT" + }, + "node_modules/fs-extra": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", + "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs-jetpack": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/fs-jetpack/-/fs-jetpack-5.1.0.tgz", + "integrity": "sha512-Xn4fDhLydXkuzepZVsr02jakLlmoARPy+YWIclo4kh0GyNGUHnTqeH/w/qIsVn50dFxtp8otPL2t/HcPJBbxUA==", + "license": "MIT", + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "license": "ISC" + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -3471,6 +4111,30 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -3480,16 +4144,26 @@ "node": ">=8.0.0" } }, - "node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "license": "MIT", "dependencies": { - "pump": "^3.0.0" + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", + "engines": { + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -3521,6 +4195,118 @@ "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", "license": "ISC" }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/global-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "license": "MIT", + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -3544,6 +4330,76 @@ "uncrypto": "^0.1.3" } }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "license": "MIT", + "dependencies": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasha/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -3743,6 +4599,30 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/html-escaper": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", @@ -3816,6 +4696,27 @@ "node": ">=10.17.0" } }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -3845,6 +4746,18 @@ "node": ">= 4" } }, + "node_modules/ignore-walk": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-5.0.1.tgz", + "integrity": "sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw==", + "license": "ISC", + "dependencies": { + "minimatch": "^5.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", @@ -3880,12 +4793,44 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, + "node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, "node_modules/interpret": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", @@ -3908,6 +4853,15 @@ "node": ">= 12" } }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/iron-webcrypto": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz", @@ -3953,6 +4907,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -3962,6 +4925,18 @@ "node": ">=8" } }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-inside-container": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", @@ -3989,6 +4964,24 @@ "node": ">=0.12.0" } }, + "node_modules/is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", @@ -4013,6 +5006,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-wsl": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", @@ -4028,11 +5030,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "license": "ISC", + "engines": { + "node": ">=16" + } }, "node_modules/js-tokens": { "version": "4.0.0", @@ -4058,12 +5069,46 @@ "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", "license": "MIT" }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "license": "MIT" }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/kleur": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", @@ -4124,6 +5169,15 @@ } } }, + "node_modules/knex/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/knex/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -4147,65 +5201,67 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "license": "MIT" }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "license": "MIT" - }, - "node_modules/load-yaml-file": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/load-yaml-file/-/load-yaml-file-0.2.0.tgz", - "integrity": "sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==", + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", "license": "MIT", "dependencies": { - "graceful-fs": "^4.1.5", - "js-yaml": "^3.13.0", - "pify": "^4.0.1", - "strip-bom": "^3.0.0" + "readable-stream": "^2.0.5" }, "engines": { - "node": ">=6" + "node": ">= 0.6.3" } }, - "node_modules/load-yaml-file/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "license": "MIT", "dependencies": { - "sprintf-js": "~1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "node_modules/load-yaml-file/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "node_modules/lazystream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "license": "MIT", "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "safe-buffer": "~5.1.0" } }, - "node_modules/load-yaml-file/node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "license": "BSD-3-Clause" + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" }, "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "license": "MIT", "dependencies": { - "p-locate": "^4.1.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lodash": { @@ -4214,6 +5270,36 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "license": "MIT" }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", + "license": "MIT" + }, + "node_modules/lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==", + "license": "MIT" + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==", + "license": "MIT" + }, "node_modules/longest-streak": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", @@ -4272,6 +5358,42 @@ "source-map-js": "^1.2.0" } }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/markdown-table": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", @@ -4282,6 +5404,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/mdast-util-definitions": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz", @@ -4490,21 +5621,86 @@ "zwitch": "^2.0.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "license": "MIT", + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "node_modules/meow/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0" - }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/merge-stream": { @@ -4513,6 +5709,24 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "license": "MIT" }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/micromark": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", @@ -5101,6 +6315,18 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -5131,6 +6357,50 @@ "node": ">=6" } }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "license": "MIT", + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/minimist-options/node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/mitt": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", @@ -5170,6 +6440,15 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/neotraverse": { "version": "0.6.18", "resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-0.6.18.tgz", @@ -5188,6 +6467,15 @@ "node": ">= 0.4.0" } }, + "node_modules/new-github-issue-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/new-github-issue-url/-/new-github-issue-url-0.2.1.tgz", + "integrity": "sha512-md4cGoxuT4T4d/HDOXbrUHkTKrp/vp+m3aOA7XXVYwNsUNMK49g3SQicTSeV5GIz/5QVGAeYRAOlyp9OvlgsYA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/nlcst-to-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-4.0.0.tgz", @@ -5201,6 +6489,45 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/node-fetch-native": { "version": "1.6.6", "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.6.tgz", @@ -5213,6 +6540,21 @@ "integrity": "sha512-0uGYQ1WQL1M5kKvGRXWQ3uZCHtLTO8hln3oBjIusM75WoesZ909uQJs/Hb946i2SS+Gsrhkaa6iAO17jRIv6DQ==", "license": "MIT" }, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -5222,6 +6564,65 @@ "node": ">=0.10.0" } }, + "node_modules/npm-bundled": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-2.0.1.tgz", + "integrity": "sha512-gZLxXdjEzE/+mOstGDqR6b0EkhJ+kM6fxM6vUuckuctuVPh80Q6pw/rSZj9s4Gex9GxWtIicO1pc8DB9KZWudw==", + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz", + "integrity": "sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ==", + "license": "ISC", + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/npm-packlist": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-5.1.3.tgz", + "integrity": "sha512-263/0NGrn32YFYi4J533qzrQ/krmmrWwhKkzwTuM4f/07ug51odoaNjUexxO4vxlzURHcmYMH1QjvHjsNDKLVg==", + "license": "ISC", + "dependencies": { + "glob": "^8.0.1", + "ignore-walk": "^5.0.1", + "npm-bundled": "^2.0.0", + "npm-normalize-package-bin": "^2.0.0" + }, + "bin": { + "npm-packlist": "bin/index.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/npm-packlist/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -5234,6 +6635,18 @@ "node": ">=8" } }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/object-treeify": { "version": "1.1.33", "resolved": "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.33.tgz", @@ -5301,6 +6714,115 @@ "regex-recursion": "^5.1.1" } }, + "node_modules/open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open/node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open/node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/openai": { + "version": "4.87.3", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.87.3.tgz", + "integrity": "sha512-d2D54fzMuBYTxMW8wcNmhT1rYKcTfMJ8t+4KjH2KtvYenygITiGBgHoIrzHwnDQWW+C5oCA+ikIR2jgPCFqcKQ==", + "license": "Apache-2.0", + "dependencies": { + "@types/node": "^18.11.18", + "@types/node-fetch": "^2.6.4", + "abort-controller": "^3.0.0", + "agentkeepalive": "^4.2.1", + "form-data-encoder": "1.7.2", + "formdata-node": "^4.3.2", + "node-fetch": "^2.6.7" + }, + "bin": { + "openai": "bin/cli" + }, + "peerDependencies": { + "ws": "^8.18.0", + "zod": "^3.23.8" + }, + "peerDependenciesMeta": { + "ws": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/openai/node_modules/@types/node": { + "version": "18.19.80", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.80.tgz", + "integrity": "sha512-kEWeMwMeIvxYkeg1gTc01awpwLbfMRZXdIhwRcakd/KlK53jmRC26LqcbIt7fnAQTu5GzlnWmzA3H6+l1u6xxQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/openai/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "license": "MIT" + }, + "node_modules/p-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", + "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", + "license": "MIT", + "dependencies": { + "p-map": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-filter/node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/p-limit": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-6.2.0.tgz", @@ -5317,27 +6839,57 @@ } }, "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "license": "MIT", "dependencies": { - "p-limit": "^2.2.0" + "p-limit": "^3.0.2" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "license": "MIT", "dependencies": { - "p-try": "^2.0.0" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5359,6 +6911,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/p-timeout": { "version": "6.1.4", "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz", @@ -5412,6 +6977,12 @@ "node": ">= 14" } }, + "node_modules/package-manager-detector": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.0.0.tgz", + "integrity": "sha512-7elnH+9zMsRo7aS72w6MeRugTpdRvInmEB4Kmm9BVvPw/SLG8gXUGQ+4wF0Mys0RSWPz0B9nuBbDe8vFeA2sfg==", + "license": "MIT" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -5472,6 +7043,15 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -5481,6 +7061,15 @@ "node": ">=8" } }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -5496,6 +7085,21 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "license": "MIT" }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", @@ -5533,14 +7137,14 @@ "license": "MIT" }, "node_modules/pg": { - "version": "8.13.3", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.13.3.tgz", - "integrity": "sha512-P6tPt9jXbL9HVu/SSRERNYaYG++MjnscnegFh9pPHihfoBSujsrka0hyuymMzeJKFWrcG8wvCKy8rCe8e5nDUQ==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.14.0.tgz", + "integrity": "sha512-nXbVpyoaXVmdqlKEzToFf37qzyeeh7mbiXsnoWvstSqohj88yaa/I/Rq/HEVn2QPSZEuLIJa/jSpRDyzjEx4FQ==", "license": "MIT", "dependencies": { "pg-connection-string": "^2.7.0", - "pg-pool": "^3.7.1", - "pg-protocol": "^1.7.1", + "pg-pool": "^3.8.0", + "pg-protocol": "^1.8.0", "pg-types": "^2.1.0", "pgpass": "1.x" }, @@ -5582,18 +7186,18 @@ } }, "node_modules/pg-pool": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.7.1.tgz", - "integrity": "sha512-xIOsFoh7Vdhojas6q3596mXFsR8nwBQBXX5JiV7p9buEVAGqYL4yFzclON5P9vFrpu1u7Zwl2oriyDa89n0wbw==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.8.0.tgz", + "integrity": "sha512-VBw3jiVm6ZOdLBTIcXLNdSotb6Iy3uOCwDGFAksZCXmi10nyRvnP2v3jl4d+IsLYRyXf6o9hIm/ZtUzlByNUdw==", "license": "MIT", "peerDependencies": { "pg": ">=8.0" } }, "node_modules/pg-protocol": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.7.1.tgz", - "integrity": "sha512-gjTHWGYWsEgy9MsY0Gp6ZJxV24IjDqdpTW7Eh0x+WfJLFsm/TJx1MzL6T0D88mBvkpxotCQ6TwW6N+Kko7lhgQ==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.8.0.tgz", + "integrity": "sha512-jvuYlEkL03NRvOoyoRktBK7+qU5kOvlAwvmrH8sr3wbLrOdVWsRxQfz8mMy9sZFsqJ1hEWNfdWKI4SAmoL+j7g==", "license": "MIT" }, "node_modules/pg-types": { @@ -5645,15 +7249,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -5666,6 +7261,67 @@ "node": ">=8" } }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/postcss": { "version": "8.5.3", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", @@ -5733,30 +7389,31 @@ "node": ">=0.10.0" } }, - "node_modules/preferred-pm": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/preferred-pm/-/preferred-pm-4.1.1.tgz", - "integrity": "sha512-rU+ZAv1Ur9jAUZtGPebQVQPzdGhNzaEiQ7VL9+cjsAWPHFYOccNXPNiev1CCDSOg/2j7UujM7ojNhpkuILEVNQ==", + "node_modules/prettier": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", + "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", + "dev": true, "license": "MIT", - "dependencies": { - "find-up-simple": "^1.0.0", - "find-yarn-workspace-root2": "1.2.16", - "which-pm": "^3.0.1" + "bin": { + "prettier": "bin/prettier.cjs" }, "engines": { - "node": ">=18.12" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, "node_modules/prisma": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-6.4.1.tgz", - "integrity": "sha512-q2uJkgXnua/jj66mk6P9bX/zgYJFI/jn4Yp0aS6SPRrjH/n6VyOV7RDe1vHD0DX8Aanx4MvgmUPPoYnR6MJnPg==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-6.5.0.tgz", + "integrity": "sha512-yUGXmWqv5F4PByMSNbYFxke/WbnyTLjnJ5bKr8fLkcnY7U5rU9rUTh/+Fja+gOrRxEgtCbCtca94IeITj4j/pg==", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@prisma/engines": "6.4.1", - "esbuild": ">=0.12 <1", - "esbuild-register": "3.6.0" + "@prisma/config": "6.5.0", + "@prisma/engines": "6.5.0" }, "bin": { "prisma": "build/index.js" @@ -5776,11 +7433,154 @@ } } }, + "node_modules/prisma-docs-generator": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/prisma-docs-generator/-/prisma-docs-generator-0.8.0.tgz", + "integrity": "sha512-w+lwFsslDtsCilWauQlKyEIPTtT4wXbG1sRnSb1NldEVF572DtcHTbcp54UGz7i1WaOuLK2M1YCp1UFRf62Nxw==", + "license": "MIT", + "dependencies": { + "@prisma/generator-helper": "^4.14.0", + "@prisma/internals": "^4.14.0", + "express": "^4.18.2", + "indent-string": "^5.0.0", + "kleur": "^4.1.5", + "meow": "9", + "pluralize": "^8.0.0", + "prismjs": "^1.29.0", + "ts-toolbelt": "^9.6.0" + }, + "bin": { + "prisma-docs-generator": "dist/cli.js" + } + }, + "node_modules/prisma-docs-generator/node_modules/@prisma/debug": { + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-4.16.2.tgz", + "integrity": "sha512-7L7WbG0qNNZYgLpsVB8rCHCXEyHFyIycRlRDNwkVfjQmACC2OW6AWCYCbfdjQhkF/t7+S3njj8wAWAocSs+Brw==", + "license": "Apache-2.0", + "dependencies": { + "@types/debug": "4.1.8", + "debug": "4.3.4", + "strip-ansi": "6.0.1" + } + }, + "node_modules/prisma-docs-generator/node_modules/@prisma/generator-helper": { + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/@prisma/generator-helper/-/generator-helper-4.16.2.tgz", + "integrity": "sha512-bMOH7y73Ui7gpQrioFeavMQA+Tf8ksaVf8Nhs9rQNzuSg8SSV6E9baczob0L5KGZTSgYoqnrRxuo03kVJYrnIg==", + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "4.16.2", + "@types/cross-spawn": "6.0.2", + "cross-spawn": "7.0.3", + "kleur": "4.1.5" + } + }, + "node_modules/prisma-docs-generator/node_modules/@types/debug": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz", + "integrity": "sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/prisma-docs-generator/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/prisma-docs-generator/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/prisma-docs-generator/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/prisma-docs-generator/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/prisma-docs-generator/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "license": "MIT" + }, + "node_modules/prisma-docs-generator/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/prisma-docs-generator/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/prisma-generator-typescript-interfaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/prisma-generator-typescript-interfaces/-/prisma-generator-typescript-interfaces-2.0.1.tgz", + "integrity": "sha512-taA9N8Q1QqU0HujDw4GoQ8wPtpAVNd1VQeelMvoMKRp/dP7WxI/yJ6ZqAbLo/LSjRi0VHp5Z9csbXE7YQJZzdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@prisma/generator-helper": "^5 || ^6" + }, + "bin": { + "prisma-generator-typescript-interfaces": "generator.js" + } + }, "node_modules/prisma-json-types-generator": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/prisma-json-types-generator/-/prisma-json-types-generator-3.2.2.tgz", "integrity": "sha512-kvEbJPIP5gxk65KmLs0nAvY+CxpqVMWb4OsEvXlyXZmp2IGfi5f52BUV7ezTYQNjRPZyR4QlayWJXffoqVVAfA==", - "dev": true, "license": "MIT", "dependencies": { "@prisma/generator-helper": "6.0.0", @@ -5800,15 +7600,52 @@ "typescript": "^5.6.2" } }, + "node_modules/prisma-markdown": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/prisma-markdown/-/prisma-markdown-1.0.9.tgz", + "integrity": "sha512-Y/aWUgDnzYt7JFjhUOmLzNs+09eoITq8ZK9CmG3L6TTKc/prYr+2EClD4jRcfEgyElfJlvH2/4QeZponu9D92Q==", + "license": "MIT", + "dependencies": { + "@prisma/generator-helper": "^5.0.0" + }, + "bin": { + "prisma-markdown": "lib/executable/markdown.js" + }, + "peerDependencies": { + "@prisma/client": ">= 5.0.0", + "prisma": ">= 5.0.0" + } + }, + "node_modules/prisma-markdown/node_modules/@prisma/debug": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.22.0.tgz", + "integrity": "sha512-AUt44v3YJeggO2ZU5BkXI7M4hu9BF2zzH2iF2V5pyXT/lRTyWiElZ7It+bRH1EshoMRxHgpYg4VB6rCM+mG5jQ==", + "license": "Apache-2.0" + }, + "node_modules/prisma-markdown/node_modules/@prisma/generator-helper": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/generator-helper/-/generator-helper-5.22.0.tgz", + "integrity": "sha512-LwqcBQ5/QsuAaLNQZAIVIAJDJBMjHwMwn16e06IYx/3Okj/xEEfw9IvrqB2cJCl3b2mCBlh3eVH0w9WGmi4aHg==", + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "5.22.0" + } + }, "node_modules/prismjs": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", - "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", "license": "MIT", "engines": { "node": ">=6" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -5850,6 +7687,19 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/proxy-agent": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", @@ -5920,7 +7770,51 @@ "ws": "^8.18.1" }, "engines": { - "node": ">=18" + "node": ">=18" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "license": "MIT", + "engines": { + "node": ">=8" } }, "node_modules/radix3": { @@ -5938,6 +7832,21 @@ "node": ">= 0.6" } }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", @@ -5963,6 +7872,158 @@ "react": "^18.3.1" } }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "license": "MIT", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "license": "ISC" + }, + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdir-glob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.1.0" + } + }, "node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -5988,6 +8049,28 @@ "node": ">= 10.13.0" } }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/redent/node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/regex": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/regex/-/regex-5.1.1.tgz", @@ -6155,6 +8238,18 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/replace-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/replace-string/-/replace-string-3.1.0.tgz", + "integrity": "sha512-yPpxc4ZR2makceA9hy/jHNqc7QVkd4Je/N0WRHm6bs3PtivPuPynxE5ejU/mp5EhnCv8+uZL7vhz8rkluSlx+Q==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -6254,6 +8349,41 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/rollup": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.35.0.tgz", @@ -6292,6 +8422,55 @@ "fsevents": "~2.3.2" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, "node_modules/scheduler": { "version": "0.23.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", @@ -6336,6 +8515,69 @@ "node": ">= 18" } }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-static/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-static/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/serve-static/node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-static/node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/server-destroy": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", @@ -6425,6 +8667,78 @@ "@types/hast": "^3.0.4" } }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", @@ -6461,6 +8775,44 @@ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "license": "MIT" }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", @@ -6540,6 +8892,38 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", + "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", + "license": "CC0-1.0" + }, "node_modules/split2": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", @@ -6591,6 +8975,15 @@ "bare-events": "^2.2.0" } }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-width": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", @@ -6637,15 +9030,6 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -6655,6 +9039,18 @@ "node": ">=6" } }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strtok3": { "version": "10.2.2", "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.2.2.tgz", @@ -6672,6 +9068,31 @@ "url": "https://github.com/sponsors/Borewit" } }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -6718,6 +9139,97 @@ "node": ">=8.0.0" } }, + "node_modules/temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/temp-write": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/temp-write/-/temp-write-4.0.0.tgz", + "integrity": "sha512-HIeWmj77uOOHb0QX7siN3OtwV3CTntquin6TNVg6SHOqCP3hYKmox90eeFOGaY1MqJ9WYDDjkyZrW6qS5AWpbw==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.15", + "is-stream": "^2.0.0", + "make-dir": "^3.0.0", + "temp-dir": "^1.0.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/temp-write/node_modules/temp-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", + "integrity": "sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/temp-write/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/tempy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-1.0.1.tgz", + "integrity": "sha512-biM9brNqxSc04Ee71hzFbryD11nX7VPhQQY32AdDmjFvodsRFz/3ufeoTZ6uYkRFfGo188tENcASNs3vTdsM0w==", + "license": "MIT", + "dependencies": { + "del": "^6.0.0", + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tempy/node_modules/type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/text-decoder": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", @@ -6795,6 +9307,18 @@ "node": ">=14.0.0" } }, + "node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "license": "MIT", + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -6833,6 +9357,12 @@ "url": "https://github.com/sponsors/Borewit" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, "node_modules/trim-lines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", @@ -6843,6 +9373,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/trough": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", @@ -6853,6 +9392,18 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/ts-pattern": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ts-pattern/-/ts-pattern-4.3.0.tgz", + "integrity": "sha512-pefrkcd4lmIVR0LA49Imjf9DYLK8vtWhqBPA3Ya1ir8xCW0O2yjL9dsCVvI7pCodLC5q7smNpEtDR2yVulQxOg==", + "license": "MIT" + }, + "node_modules/ts-toolbelt": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz", + "integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==", + "license": "Apache-2.0" + }, "node_modules/tsconfck": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.5.tgz", @@ -6891,6 +9442,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/typed-query-selector": { "version": "2.12.0", "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz", @@ -6944,7 +9508,6 @@ "version": "6.20.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", - "devOptional": true, "license": "MIT" }, "node_modules/unified": { @@ -6966,6 +9529,18 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "license": "MIT", + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/unist-util-find-after": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", @@ -7089,10 +9664,52 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/valibot": { - "version": "1.0.0-rc.3", - "resolved": "https://registry.npmjs.org/valibot/-/valibot-1.0.0-rc.3.tgz", - "integrity": "sha512-LT0REa7Iqx4QGcaHLiTiTkcmJqJ9QdpOy89HALFFBJgejTS64GQFRIbDF7e4f6pauQbo/myfKGmWXCLhMeM6+g==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/valibot/-/valibot-1.0.0.tgz", + "integrity": "sha512-1Hc0ihzWxBar6NGeZv7fPLY0QuxFMyxwYR2sF1Blu7Wq7EnremwY2W02tit2ij2VJT8HcSkHAQqmFfl77f73Yw==", "license": "MIT", "peerDependencies": { "typescript": ">=5" @@ -7103,6 +9720,25 @@ } } }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/vfile": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", @@ -7337,6 +9973,31 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/when": { "version": "3.7.8", "resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz", @@ -7344,27 +10005,18 @@ "license": "MIT" }, "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", "license": "ISC", "dependencies": { - "isexe": "^2.0.0" + "isexe": "^3.1.1" }, "bin": { - "which": "bin/which" - } - }, - "node_modules/which-pm": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/which-pm/-/which-pm-3.0.1.tgz", - "integrity": "sha512-v2JrMq0waAI4ju1xU5x3blsxBBMgdgZve580iYMN5frDaLGjbA24fok7wKCsya8KLVO19Ju4XDc5+zTZCJkQfg==", - "license": "MIT", - "dependencies": { - "load-yaml-file": "^0.2.0" + "node-which": "bin/which.js" }, "engines": { - "node": ">=18.12" + "node": "^16.13.0 || >=18.0.0" } }, "node_modules/which-pm-runs": { @@ -7476,6 +10128,12 @@ "node": ">=10" } }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", @@ -7593,6 +10251,41 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zip-stream": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz", + "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==", + "license": "MIT", + "dependencies": { + "archiver-utils": "^3.0.4", + "compress-commons": "^4.1.2", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/zip-stream/node_modules/archiver-utils": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz", + "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==", + "license": "MIT", + "dependencies": { + "glob": "^7.2.3", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/zod": { "version": "3.24.2", "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz", diff --git a/package.json b/package.json index 02dca18..394bc35 100644 --- a/package.json +++ b/package.json @@ -9,22 +9,28 @@ "test": "vitest", "gen": "encore gen client --output=./frontend/app/lib/client.ts --env=local", "build": "cd frontend && npx astro build", - "db:gen": "npx concurrently node:db:gen:*", - "db:gen:archives": "npx prisma generate --schema ./archives/data/schema.prisma", - "db:gen:media": "npx prisma generate --schema ./media/data/schema.prisma", - "db:gen:documents": "npx prisma generate --schema ./documents/data/schema.prisma", - "db:gen:tgov": "npx prisma generate --schema ./tgov/data/schema.prisma", "db:migrate:media": "npx prisma migrate dev --schema ./media/data/schema.prisma", - "db:migrate:documents": "npx prisma migrate dev --schema ./documents/data/schema.prisma", - "db:migrate:tgov": "npx prisma migrate dev --schema ./tgov/data/schema.prisma", - "db:migrate:archives": "npx prisma migrate dev --schema ./archives/data/schema.prisma" + "db:gen": "npx concurrently npm:db:gen:*", + "db:gen:tgov": "npx prisma generate --schema ./tgov/db/schema.prisma", + "db:gen:media": "npx prisma generate --schema ./media/db/schema.prisma", + "db:gen:documents": "npx prisma generate --schema ./documents/db/schema.prisma", + "db:gen:transcription": "npx prisma generate --schema ./transcription/db/schema.prisma", + "db:gen:batch": "npx prisma generate --schema ./batch/db/schema.prisma", + "db:migrate:tgov": "npx prisma migrate dev --schema ./tgov/db/schema.prisma", + "db:migrate:media": "npx prisma migrate dev --schema ./media/db/schema.prisma", + "db:migrate:documents": "npx prisma migrate dev --schema ./documents/db/schema.prisma", + "db:migrate:transcription": "npx prisma migrate dev --schema ./transcription/db/schema.prisma", + "db:migrate:batch": "npx prisma migrate dev --schema ./batch/db/schema.prisma" }, "devDependencies": { + "@ianvs/prettier-plugin-sort-imports": "^4.4.1", "@types/fluent-ffmpeg": "^2.1.27", "@types/mime-types": "^2.1.4", "@types/node": "22.13.10", "@types/react": "^18", "@types/react-dom": "^18", - "prisma-json-types-generator": "^3.2.2", + "prettier": "^3.5.3", + "prisma": "^6.4.1", + "prisma-generator-typescript-interfaces": "^2.0.1", "typescript": "^5.2.2", "vitest": "3.0.8" }, @@ -38,18 +44,21 @@ "astro": "^5.4.2", "csv-parse": "^5.6.0", "date-fns": "^4.1.0", - "encore.dev": "^1.46.6", + "encore.dev": "^1.46.10", "ffmpeg": "^0.0.4", "file-type": "^20.4.0", "fluent-ffmpeg": "2.1.3", "knex": "^3.1.0", "mime-types": "^2.1.35", + "openai": "^4.87.3", "pg": "^8.11.3", - "prisma": "^6.4.1", + "prisma-docs-generator": "^0.8.0", + "prisma-json-types-generator": "^3.2.2", + "prisma-markdown": "^1.0.9", "puppeteer": "^24.4.0", "react": "^18", "react-dom": "^18", - "valibot": "^1.0.0-rc.3" + "valibot": "^1.0.0" }, "packageManager": "npm@11.2.0+sha512.3dc9c50ba813a3d54393155a435fe66404b72685ab0e3008f9ae9ed8d81f6104860f07ed2656dd5748c1322d95f3140fa9b19c59a6bba7750fd12285f81866da" } diff --git a/prettier.config.js b/prettier.config.js new file mode 100644 index 0000000..b467e6c --- /dev/null +++ b/prettier.config.js @@ -0,0 +1,71 @@ +/** @typedef {import("@ianvs/prettier-plugin-sort-imports").PluginConfig} SortImportsConfig */ +/** @typedef {import("prettier").Config} PrettierConfig */ + +const assets = [ + "css", + "sass", + "scss", + "less", + "styl", + "svg", + "png", + "jpg", + "jpeg", + "gif", + "webp", + "eot", + "otf", + "ttf", + "woff", + "woff2", + "mp4", + "webm", + "wav", + "mp3", + "m4a", + "aac", + "oga", + ]; + + const frameworks = [ + "encore", + "prisma", + "~encore" + ]; + + + const importOrder = /** @satisfies {SortImportsConfig["importOrder"]} */(/** @type {const} */([ + "^(?!@welldone-software).*?(wdyr|why-did-you-render|whyDidYouRender).*?$", // why-did-you-render is always first + `^.*\\.+(${assets.join("|")})$`, // assets should always be top-most (why-did-you-render excepted), as they may have side effects + " ", + "", // node builtins + " ", + "^\\.", // relative imports + "^#", // aliased packages (e.g. workspaces) + " ", + `^@?(${frameworks.join("|")})(/.+)?$`, + " ", + `^(${frameworks.join("|")})[^/]+.*?$`, // framework ecosystem packages + " ", + "^@\\w", // other scoped packages + "", // other third party modules + // everything should be sorted by now, but just in case... + ".*?", + ])); + + export default /** @satisfies {PrettierConfig & SortImportsConfig} */({ + experimentalTernaries: true, + plugins: ["@ianvs/prettier-plugin-sort-imports"], + importOrderParserPlugins: ["typescript", "jsx", "importAssertions"], + importOrder, + overrides: [ + { + files: ["*.json", "*.jsonc", "*.json5", "encore.app"], + options: { + parser: "json", + trailingComma: "none", + }, + }, + ], + }); + \ No newline at end of file diff --git a/services/enums.ts b/services/enums.ts new file mode 100644 index 0000000..ebdc737 --- /dev/null +++ b/services/enums.ts @@ -0,0 +1,41 @@ +export const JobStatus = { + QUEUED: "QUEUED", + PROCESSING: "PROCESSING", + COMPLETED: "COMPLETED", + COMPLETED_WITH_ERRORS: "COMPLETED_WITH_ERRORS", + FAILED: "FAILED", +} as const; + +export type JobStatus = keyof typeof JobStatus; + +export const BatchType = { + MEDIA: "MEDIA", + DOCUMENT: "DOCUMENT", + TRANSCRIPTION: "TRANSCRIPTION", +} as const; + +export type BatchType = keyof typeof BatchType; + +export const TaskType = { + DOCUMENT_DOWNLOAD: "DOCUMENT_DOWNLOAD", + DOCUMENT_CONVERT: "DOCUMENT_CONVERT", + DOCUMENT_EXTRACT: "DOCUMENT_EXTRACT", + DOCUMENT_PARSE: "DOCUMENT_PARSE", + AGENDA_DOWNLOAD: "AGENDA_DOWNLOAD", + VIDEO_DOWNLOAD: "VIDEO_DOWNLOAD", + VIDEO_PROCESS: "VIDEO_PROCESS", + AUDIO_EXTRACT: "AUDIO_EXTRACT", + AUDIO_TRANSCRIBE: "AUDIO_TRANSCRIBE", + SPEAKER_DIARIZE: "SPEAKER_DIARIZE", + TRANSCRIPT_FORMAT: "TRANSCRIPT_FORMAT", +} as const; + +export type $TaskType = keyof typeof TaskType; + +export const EventType = { + BATCH_CREATED: "BATCH_CREATED", + TASK_COMPLETED: "TASK_COMPLETED", + BATCH_STATUS_CHANGED: "BATCH_STATUS_CHANGED", +} as const; + +export type EventType = keyof typeof EventType; diff --git a/media/batch.ts b/services/media/batch.ts similarity index 51% rename from media/batch.ts rename to services/media/batch.ts index 50ec04f..574f19a 100644 --- a/media/batch.ts +++ b/services/media/batch.ts @@ -4,13 +4,17 @@ * Provides batch processing endpoints for video acquisition and processing, * designed for handling multiple videos concurrently or in the background. */ -import { api } from "encore.dev/api"; +import { JobStatus } from "../enums"; +import { db } from "./db"; +import { processMedia } from "./processor"; + +import { scrapers, tgov, transcription } from "~encore/clients"; + +import { api, APIError } from "encore.dev/api"; import { CronJob } from "encore.dev/cron"; import logger from "encore.dev/log"; -import { db } from "./data"; -import { processMedia } from "./processor"; -import { tgov } from "~encore/clients"; +import { subDays } from "date-fns"; // Interface for batch processing request interface BatchProcessRequest { @@ -28,6 +32,7 @@ interface BatchProcessResponse { /** * Queue a batch of videos for processing + * // TODO: TEST THIS * * This endpoint accepts an array of viewer URLs and queues them for processing. * It returns a batch ID that can be used to check the status of the batch. @@ -44,34 +49,42 @@ export const queueVideoBatch = api( } // Create a batch record in the database - const batch = await db.$transaction(async (tx) => { - // First, create entries for each URL to be processed - const videoTasks = await Promise.all( - req.viewerUrls!.map(async (url, index) => { - return tx.videoProcessingTask.create({ - data: { - viewerUrl: url, - meetingRecordId: req.meetingRecordIds?.[index], - status: "queued", - extractAudio: req.extractAudio ?? true, + const batch = await db.$transaction( + async (tx) => { + // First, create entries for each URL to be processed + const videoTasks = await Promise.all( + (req.viewerUrls ?? []).map(async (url, index) => { + const { videoUrl } = await scrapers.scrapeVideoDownloadUrl({ + hint: { url }, + }); + + return tx.videoProcessingTask.create({ + data: { + viewerUrl: url, + meetingRecordId: req.meetingRecordIds?.[index], + status: "queued", + extractAudio: req.extractAudio ?? true, + downloadUrl: videoUrl, + }, + }); + }), + ); + + // Then create the batch that references these tasks + return tx.videoProcessingBatch.create({ + data: { + status: "queued", + totalTasks: videoTasks.length, + completedTasks: 0, + failedTasks: 0, + tasks: { + connect: videoTasks.map((task) => ({ id: task.id })), }, - }); - }) - ); - - // Then create the batch that references these tasks - return tx.videoProcessingBatch.create({ - data: { - status: "queued", - totalTasks: videoTasks.length, - completedTasks: 0, - failedTasks: 0, - tasks: { - connect: videoTasks.map((task) => ({ id: task.id })), }, - }, - }); - }); + }); + }, + { timeout: 10000 }, + ); logger.info(`Queued batch ${batch.id} with ${batch.totalTasks} videos`); @@ -80,11 +93,12 @@ export const queueVideoBatch = api( totalVideos: batch.totalTasks, status: batch.status as BatchProcessResponse["status"], }; - } + }, ); /** * Get the status of a batch + * // TODO: TEST THIS */ export const getBatchStatus = api( { @@ -117,6 +131,7 @@ export const getBatchStatus = api( tasks: batch.tasks.map((task) => ({ id: task.id, viewerUrl: task.viewerUrl, + meetingRecordId: task.meetingRecordId, downloadUrl: task.downloadUrl, status: task.status, videoId: task.videoId, @@ -126,11 +141,12 @@ export const getBatchStatus = api( updatedAt: task.updatedAt, })), }; - } + }, ); /** * List all batches + * // TODO: TEST THIS */ export const listBatches = api( { @@ -160,7 +176,7 @@ export const listBatches = api( updatedAt: batch.updatedAt, taskCount: batch._count.tasks, })); - } + }, ); /** @@ -172,7 +188,11 @@ export const processNextBatch = api( path: "/api/videos/batch/process", expose: true, }, - async ({ batchSize = 5 }: { batchSize?: number }): Promise<{ processed: number }> => { + async ({ + batchSize = 5, + }: { + batchSize?: number; + }): Promise<{ processed: number }> => { // Find the oldest queued batch const queuedBatch = await db.videoProcessingBatch.findFirst({ where: { status: "queued" }, @@ -197,7 +217,7 @@ export const processNextBatch = api( }); logger.info( - `Processing batch ${queuedBatch.id} with ${queuedBatch.tasks.length} videos` + `Processing batch ${queuedBatch.id} with ${queuedBatch.tasks.length} videos`, ); let processed = 0; @@ -208,7 +228,7 @@ export const processNextBatch = api( // Step 1: Update task status to processing await db.videoProcessingTask.update({ where: { id: task.id }, - data: { status: "processing" }, + data: { status: JobStatus.PROCESSING }, }); // Step 2: Extract the download URL @@ -216,11 +236,11 @@ export const processNextBatch = api( if (!downloadUrl && task.viewerUrl) { // Scrape the download URL from the TGov service - const extractResult = await tgov.extractVideoUrl({ - viewerUrl: task.viewerUrl, + const { videoUrl } = await scrapers.scrapeVideoDownloadUrl({ + hint: { url: task.viewerUrl }, }); - downloadUrl = extractResult.videoUrl; + downloadUrl = videoUrl; // Update the task with the download URL await db.videoProcessingTask.update({ @@ -229,9 +249,7 @@ export const processNextBatch = api( }); } - if (!downloadUrl) { - throw new Error("No download URL available"); - } + if (!downloadUrl) throw new Error("No download URL available"); // Step 3: Process the video const result = await processMedia(downloadUrl, { @@ -298,28 +316,176 @@ export const processNextBatch = api( } return { processed }; - } + }, +); + +/** + * Auto-queue unprocessed meeting videos for processing + * + * This endpoint fetches recent meetings with video URLs that haven't been processed yet, + * queues them for video processing, and optionally initiates transcription jobs. + */ +export const autoQueueNewMeetings = api( + { + method: "POST", + path: "/api/videos/auto-queue", + expose: true, + }, + async ({ + daysBack = 30, + limit = 10, + autoTranscribe = true, + }: { + daysBack?: number; + limit?: number; + autoTranscribe?: boolean; + }): Promise<{ + batchId?: string; + queuedMeetings: number; + transcriptionJobs: number; + }> => { + logger.info( + `Searching for unprocessed meetings from past ${daysBack} days`, + ); + + // Get recent meetings from TGov service + const { meetings } = await tgov.listMeetings({ + afterDate: subDays(new Date(), daysBack), + next: limit, + }); + + // Filter for meetings with video URLs but no videoId (unprocessed) + const unprocessedMeetings = meetings.filter( + (meeting) => meeting.videoViewUrl && !meeting.videoId, + ); + + if (unprocessedMeetings.length === 0) { + logger.info("No unprocessed meetings found"); + return { queuedMeetings: 0, transcriptionJobs: 0 }; + } + + // Limit the number of meetings to process + const meetingsToProcess = unprocessedMeetings.slice(0, limit); + + logger.info( + `Queueing ${meetingsToProcess.length} unprocessed meetings for video processing`, + ); + + try { + // Queue the videos for processing + const response = await queueVideoBatch({ + viewerUrls: meetingsToProcess.map((m) => m.videoViewUrl!), + meetingRecordIds: meetingsToProcess.map((m) => m.id), + extractAudio: true, + }); + + logger.info( + `Successfully queued batch ${response.batchId} with ${response.totalVideos} videos`, + ); + + // Immediately process this batch + await processNextBatch({ batchSize: meetingsToProcess.length }); + + // If autoTranscribe is enabled, wait for video processing and then queue transcriptions + let transcriptionJobsCreated = 0; + + if (autoTranscribe) { + // Give some time for video processing to complete + // In a production system, you might want a more sophisticated approach with callbacks + logger.info("Scheduling transcription jobs for processed videos"); + + // Get the batch status after processing + const batchStatus = await getBatchStatus({ batchId: response.batchId }); + + // Queue transcription for successfully processed videos + const completedTasks = batchStatus.tasks.filter( + (task) => task.status === "completed" && task.audioId, + ); + + for (const task of completedTasks) { + try { + if (task.audioId) { + await transcription.transcribe({ + audioFileId: task.audioId, + meetingRecordId: task.meetingRecordId ?? undefined, + }); + transcriptionJobsCreated++; + } + } catch (error) { + logger.error( + `Failed to create transcription job for task ${task.id}`, + { error: error instanceof Error ? error.message : String(error) }, + ); + } + } + + logger.info(`Created ${transcriptionJobsCreated} transcription jobs`); + } + + return { + batchId: response.batchId, + queuedMeetings: meetingsToProcess.length, + transcriptionJobs: transcriptionJobsCreated, + }; + } catch (error) { + logger.error("Failed to auto-queue meetings", { + error: error instanceof Error ? error.message : String(error), + }); + throw APIError.internal("Failed to auto-queue meetings for processing"); + } + }, ); /** * Automatic batch processing endpoint for cron job + * // TODO: TEST THIS */ -export const autoProcessNextBatch = api( +export const processNextBatchCronTarget = api( { method: "POST", path: "/api/videos/batch/auto-process", expose: true, }, async () => { - return processNextBatch({}); - } + return processNextBatch({ batchSize: 5 }); + }, +); + +/** + * Auto-queue new meetings without parameters - wrapper for cron job + * // TODO: TEST THIS + */ +export const autoQueueNewMeetingsCronTarget = api( + { + method: "POST", + path: "/api/videos/auto-queue/cron", + expose: false, + }, + async () => { + // Call with default parameters + return autoQueueNewMeetings({ + daysBack: 30, + limit: 10, + autoTranscribe: true, + }); + }, ); /** * Cron job to process video batches */ -export const processBatchesCron = new CronJob("process-video-batches", { +export const autoProcessNextBatchCron = new CronJob("process-video-batches", { title: "Process Video Batches", schedule: "*/5 * * * *", // Every 5 minutes - endpoint: autoProcessNextBatch, + endpoint: processNextBatchCronTarget, +}); + +/** + * Cron job to auto-queue new meetings for processing + * Runs daily at 3:00 AM to check for new unprocessed meetings + */ +export const autoQueueNewMeetingsCron = new CronJob("auto-queue-meetings", { + title: "Auto-Queue New Meeting Videos", + schedule: "0 3 * * *", // Daily at 3:00 AM + endpoint: autoQueueNewMeetingsCronTarget, }); diff --git a/services/media/db/docs/README.md b/services/media/db/docs/README.md new file mode 100644 index 0000000..b359ef6 --- /dev/null +++ b/services/media/db/docs/README.md @@ -0,0 +1,92 @@ +# Media Service Database Schema +> Generated by [`prisma-markdown`](https://github.com/samchon/prisma-markdown) + +- [default](#default) + +## default +```mermaid +erDiagram +"MediaFile" { + String id PK + String bucket + String key + String mimetype + String url "nullable" + String srcUrl "nullable" + DateTime createdAt + DateTime updatedAt + String meetingRecordId "nullable" + String title "nullable" + String description "nullable" + Int fileSize "nullable" +} +"VideoProcessingBatch" { + String id PK + String status + Int totalTasks + Int completedTasks + Int failedTasks + DateTime createdAt + DateTime updatedAt +} +"VideoProcessingTask" { + String id PK + String viewerUrl "nullable" + String downloadUrl "nullable" + String status + Boolean extractAudio + String error "nullable" + DateTime createdAt + DateTime updatedAt + String batchId FK "nullable" + String meetingRecordId "nullable" + String videoId FK "nullable" + String audioId FK "nullable" +} +"VideoProcessingTask" }o--o| "VideoProcessingBatch" : batch +"VideoProcessingTask" }o--o| "MediaFile" : video +"VideoProcessingTask" }o--o| "MediaFile" : audio +``` + +### `MediaFile` + +**Properties** + - `id`: + - `bucket`: + - `key`: + - `mimetype`: + - `url`: + - `srcUrl`: + - `createdAt`: + - `updatedAt`: + - `meetingRecordId`: + - `title`: + - `description`: + - `fileSize`: + +### `VideoProcessingBatch` + +**Properties** + - `id`: + - `status`: + - `totalTasks`: + - `completedTasks`: + - `failedTasks`: + - `createdAt`: + - `updatedAt`: + +### `VideoProcessingTask` + +**Properties** + - `id`: + - `viewerUrl`: + - `downloadUrl`: + - `status`: + - `extractAudio`: + - `error`: + - `createdAt`: + - `updatedAt`: + - `batchId`: + - `meetingRecordId`: + - `videoId`: + - `audioId`: \ No newline at end of file diff --git a/services/media/db/docs/index.html b/services/media/db/docs/index.html new file mode 100644 index 0000000..4635ad3 --- /dev/null +++ b/services/media/db/docs/index.html @@ -0,0 +1,25226 @@ + + + + + + + + Prisma Generated Docs + + + + +
+
+
+ + + + + + + + +
+ +
+
Models
+ +
Types
+ +
+ +
+
+ +
+

Models

+ +
+

MediaFile

+ + +
+

Fields

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesRequiredComment
+ id + + String + +
    +
  • @id
  • @default(ulid())
  • +
+
+ Yes + + - +
+ bucket + + String + +
    +
  • -
  • +
+
+ Yes + + - +
+ key + + String + +
    +
  • -
  • +
+
+ Yes + + - +
+ mimetype + + String + +
    +
  • -
  • +
+
+ Yes + + - +
+ url + + String? + +
    +
  • -
  • +
+
+ No + + - +
+ srcUrl + + String? + +
    +
  • -
  • +
+
+ No + + - +
+ createdAt + + DateTime + +
    +
  • @default(now())
  • +
+
+ Yes + + - +
+ updatedAt + + DateTime + +
    +
  • @updatedAt
  • +
+
+ Yes + + - +
+ meetingRecordId + + String? + +
    +
  • -
  • +
+
+ No + + - +
+ title + + String? + +
    +
  • -
  • +
+
+ No + + - +
+ description + + String? + +
    +
  • -
  • +
+
+ No + + - +
+ fileSize + + Int? + +
    +
  • -
  • +
+
+ No + + - +
+ videoProcessingTaskVideos + + VideoProcessingTask[] + +
    +
  • -
  • +
+
+ Yes + + - +
+ videoProcessingTaskAudios + + VideoProcessingTask[] + +
    +
  • -
  • +
+
+ Yes + + - +
+
+
+
+
+

Operations

+
+ +
+

findUnique

+

Find zero or one MediaFile

+
+
// Get one MediaFile
+const mediaFile = await prisma.mediaFile.findUnique({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + MediaFileWhereUniqueInput + + Yes +
+

Output

+
Type: MediaFile
+
Required: + No
+
List: + No
+
+
+
+

findFirst

+

Find first MediaFile

+
+
// Get one MediaFile
+const mediaFile = await prisma.mediaFile.findFirst({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + MediaFileWhereInput + + No +
+ orderBy + + MediaFileOrderByWithRelationInput[] | MediaFileOrderByWithRelationInput + + No +
+ cursor + + MediaFileWhereUniqueInput + + No +
+ take + + Int + + No +
+ skip + + Int + + No +
+ distinct + + MediaFileScalarFieldEnum | MediaFileScalarFieldEnum[] + + No +
+

Output

+
Type: MediaFile
+
Required: + No
+
List: + No
+
+
+
+

findMany

+

Find zero or more MediaFile

+
+
// Get all MediaFile
+const MediaFile = await prisma.mediaFile.findMany()
+// Get first 10 MediaFile
+const MediaFile = await prisma.mediaFile.findMany({ take: 10 })
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + MediaFileWhereInput + + No +
+ orderBy + + MediaFileOrderByWithRelationInput[] | MediaFileOrderByWithRelationInput + + No +
+ cursor + + MediaFileWhereUniqueInput + + No +
+ take + + Int + + No +
+ skip + + Int + + No +
+ distinct + + MediaFileScalarFieldEnum | MediaFileScalarFieldEnum[] + + No +
+

Output

+
Type: MediaFile
+
Required: + Yes
+
List: + Yes
+
+
+
+

create

+

Create one MediaFile

+
+
// Create one MediaFile
+const MediaFile = await prisma.mediaFile.create({
+  data: {
+    // ... data to create a MediaFile
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + MediaFileCreateInput | MediaFileUncheckedCreateInput + + Yes +
+

Output

+
Type: MediaFile
+
Required: + Yes
+
List: + No
+
+
+
+

delete

+

Delete one MediaFile

+
+
// Delete one MediaFile
+const MediaFile = await prisma.mediaFile.delete({
+  where: {
+    // ... filter to delete one MediaFile
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + MediaFileWhereUniqueInput + + Yes +
+

Output

+
Type: MediaFile
+
Required: + No
+
List: + No
+
+
+
+

update

+

Update one MediaFile

+
+
// Update one MediaFile
+const mediaFile = await prisma.mediaFile.update({
+  where: {
+    // ... provide filter here
+  },
+  data: {
+    // ... provide data here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + MediaFileUpdateInput | MediaFileUncheckedUpdateInput + + Yes +
+ where + + MediaFileWhereUniqueInput + + Yes +
+

Output

+
Type: MediaFile
+
Required: + No
+
List: + No
+
+
+
+

deleteMany

+

Delete zero or more MediaFile

+
+
// Delete a few MediaFile
+const { count } = await prisma.mediaFile.deleteMany({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + MediaFileWhereInput + + No +
+ limit + + Int + + No +
+

Output

+ +
Required: + Yes
+
List: + No
+
+
+
+

updateMany

+

Update zero or one MediaFile

+
+
const { count } = await prisma.mediaFile.updateMany({
+  where: {
+    // ... provide filter here
+  },
+  data: {
+    // ... provide data here
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + MediaFileUpdateManyMutationInput | MediaFileUncheckedUpdateManyInput + + Yes +
+ where + + MediaFileWhereInput + + No +
+ limit + + Int + + No +
+

Output

+ +
Required: + Yes
+
List: + No
+
+
+
+

upsert

+

Create or update one MediaFile

+
+
// Update or create a MediaFile
+const mediaFile = await prisma.mediaFile.upsert({
+  create: {
+    // ... data to create a MediaFile
+  },
+  update: {
+    // ... in case it already exists, update
+  },
+  where: {
+    // ... the filter for the MediaFile we want to update
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + MediaFileWhereUniqueInput + + Yes +
+ create + + MediaFileCreateInput | MediaFileUncheckedCreateInput + + Yes +
+ update + + MediaFileUpdateInput | MediaFileUncheckedUpdateInput + + Yes +
+

Output

+
Type: MediaFile
+
Required: + Yes
+
List: + No
+
+ +
+
+
+
+
+

VideoProcessingBatch

+ + +
+

Fields

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesRequiredComment
+ id + + String + +
    +
  • @id
  • @default(ulid())
  • +
+
+ Yes + + - +
+ status + + String + +
    +
  • -
  • +
+
+ Yes + + - +
+ totalTasks + + Int + +
    +
  • -
  • +
+
+ Yes + + - +
+ completedTasks + + Int + +
    +
  • @default(0)
  • +
+
+ Yes + + - +
+ failedTasks + + Int + +
    +
  • @default(0)
  • +
+
+ Yes + + - +
+ createdAt + + DateTime + +
    +
  • @default(now())
  • +
+
+ Yes + + - +
+ updatedAt + + DateTime + +
    +
  • @updatedAt
  • +
+
+ Yes + + - +
+ tasks + + VideoProcessingTask[] + +
    +
  • -
  • +
+
+ Yes + + - +
+
+
+
+
+

Operations

+
+ +
+

findUnique

+

Find zero or one VideoProcessingBatch

+
+
// Get one VideoProcessingBatch
+const videoProcessingBatch = await prisma.videoProcessingBatch.findUnique({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + VideoProcessingBatchWhereUniqueInput + + Yes +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

findFirst

+

Find first VideoProcessingBatch

+
+
// Get one VideoProcessingBatch
+const videoProcessingBatch = await prisma.videoProcessingBatch.findFirst({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + VideoProcessingBatchWhereInput + + No +
+ orderBy + + VideoProcessingBatchOrderByWithRelationInput[] | VideoProcessingBatchOrderByWithRelationInput + + No +
+ cursor + + VideoProcessingBatchWhereUniqueInput + + No +
+ take + + Int + + No +
+ skip + + Int + + No +
+ distinct + + VideoProcessingBatchScalarFieldEnum | VideoProcessingBatchScalarFieldEnum[] + + No +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

findMany

+

Find zero or more VideoProcessingBatch

+
+
// Get all VideoProcessingBatch
+const VideoProcessingBatch = await prisma.videoProcessingBatch.findMany()
+// Get first 10 VideoProcessingBatch
+const VideoProcessingBatch = await prisma.videoProcessingBatch.findMany({ take: 10 })
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + VideoProcessingBatchWhereInput + + No +
+ orderBy + + VideoProcessingBatchOrderByWithRelationInput[] | VideoProcessingBatchOrderByWithRelationInput + + No +
+ cursor + + VideoProcessingBatchWhereUniqueInput + + No +
+ take + + Int + + No +
+ skip + + Int + + No +
+ distinct + + VideoProcessingBatchScalarFieldEnum | VideoProcessingBatchScalarFieldEnum[] + + No +
+

Output

+ +
Required: + Yes
+
List: + Yes
+
+
+
+

create

+

Create one VideoProcessingBatch

+
+
// Create one VideoProcessingBatch
+const VideoProcessingBatch = await prisma.videoProcessingBatch.create({
+  data: {
+    // ... data to create a VideoProcessingBatch
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + VideoProcessingBatchCreateInput | VideoProcessingBatchUncheckedCreateInput + + Yes +
+

Output

+ +
Required: + Yes
+
List: + No
+
+
+
+

delete

+

Delete one VideoProcessingBatch

+
+
// Delete one VideoProcessingBatch
+const VideoProcessingBatch = await prisma.videoProcessingBatch.delete({
+  where: {
+    // ... filter to delete one VideoProcessingBatch
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + VideoProcessingBatchWhereUniqueInput + + Yes +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

update

+

Update one VideoProcessingBatch

+
+
// Update one VideoProcessingBatch
+const videoProcessingBatch = await prisma.videoProcessingBatch.update({
+  where: {
+    // ... provide filter here
+  },
+  data: {
+    // ... provide data here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + VideoProcessingBatchUpdateInput | VideoProcessingBatchUncheckedUpdateInput + + Yes +
+ where + + VideoProcessingBatchWhereUniqueInput + + Yes +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

deleteMany

+

Delete zero or more VideoProcessingBatch

+
+
// Delete a few VideoProcessingBatch
+const { count } = await prisma.videoProcessingBatch.deleteMany({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + VideoProcessingBatchWhereInput + + No +
+ limit + + Int + + No +
+

Output

+ +
Required: + Yes
+
List: + No
+
+
+
+

updateMany

+

Update zero or one VideoProcessingBatch

+
+
const { count } = await prisma.videoProcessingBatch.updateMany({
+  where: {
+    // ... provide filter here
+  },
+  data: {
+    // ... provide data here
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + VideoProcessingBatchUpdateManyMutationInput | VideoProcessingBatchUncheckedUpdateManyInput + + Yes +
+ where + + VideoProcessingBatchWhereInput + + No +
+ limit + + Int + + No +
+

Output

+ +
Required: + Yes
+
List: + No
+
+
+
+

upsert

+

Create or update one VideoProcessingBatch

+
+
// Update or create a VideoProcessingBatch
+const videoProcessingBatch = await prisma.videoProcessingBatch.upsert({
+  create: {
+    // ... data to create a VideoProcessingBatch
+  },
+  update: {
+    // ... in case it already exists, update
+  },
+  where: {
+    // ... the filter for the VideoProcessingBatch we want to update
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + VideoProcessingBatchWhereUniqueInput + + Yes +
+ create + + VideoProcessingBatchCreateInput | VideoProcessingBatchUncheckedCreateInput + + Yes +
+ update + + VideoProcessingBatchUpdateInput | VideoProcessingBatchUncheckedUpdateInput + + Yes +
+

Output

+ +
Required: + Yes
+
List: + No
+
+ +
+
+
+
+
+

VideoProcessingTask

+ + +
+

Fields

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesRequiredComment
+ id + + String + +
    +
  • @id
  • @default(ulid())
  • +
+
+ Yes + + - +
+ viewerUrl + + String? + +
    +
  • -
  • +
+
+ No + + - +
+ downloadUrl + + String? + +
    +
  • -
  • +
+
+ No + + - +
+ status + + String + +
    +
  • -
  • +
+
+ Yes + + - +
+ extractAudio + + Boolean + +
    +
  • @default(true)
  • +
+
+ Yes + + - +
+ error + + String? + +
    +
  • -
  • +
+
+ No + + - +
+ createdAt + + DateTime + +
    +
  • @default(now())
  • +
+
+ Yes + + - +
+ updatedAt + + DateTime + +
    +
  • @updatedAt
  • +
+
+ Yes + + - +
+ batchId + + String? + +
    +
  • -
  • +
+
+ No + + - +
+ meetingRecordId + + String? + +
    +
  • -
  • +
+
+ No + + - +
+ videoId + + String? + +
    +
  • -
  • +
+
+ No + + - +
+ audioId + + String? + +
    +
  • -
  • +
+
+ No + + - +
+ batch + + VideoProcessingBatch? + +
    +
  • -
  • +
+
+ No + + - +
+ video + + MediaFile? + +
    +
  • -
  • +
+
+ No + + - +
+ audio + + MediaFile? + +
    +
  • -
  • +
+
+ No + + - +
+
+
+
+
+

Operations

+
+ +
+

findUnique

+

Find zero or one VideoProcessingTask

+
+
// Get one VideoProcessingTask
+const videoProcessingTask = await prisma.videoProcessingTask.findUnique({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + VideoProcessingTaskWhereUniqueInput + + Yes +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

findFirst

+

Find first VideoProcessingTask

+
+
// Get one VideoProcessingTask
+const videoProcessingTask = await prisma.videoProcessingTask.findFirst({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + VideoProcessingTaskWhereInput + + No +
+ orderBy + + VideoProcessingTaskOrderByWithRelationInput[] | VideoProcessingTaskOrderByWithRelationInput + + No +
+ cursor + + VideoProcessingTaskWhereUniqueInput + + No +
+ take + + Int + + No +
+ skip + + Int + + No +
+ distinct + + VideoProcessingTaskScalarFieldEnum | VideoProcessingTaskScalarFieldEnum[] + + No +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

findMany

+

Find zero or more VideoProcessingTask

+
+
// Get all VideoProcessingTask
+const VideoProcessingTask = await prisma.videoProcessingTask.findMany()
+// Get first 10 VideoProcessingTask
+const VideoProcessingTask = await prisma.videoProcessingTask.findMany({ take: 10 })
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + VideoProcessingTaskWhereInput + + No +
+ orderBy + + VideoProcessingTaskOrderByWithRelationInput[] | VideoProcessingTaskOrderByWithRelationInput + + No +
+ cursor + + VideoProcessingTaskWhereUniqueInput + + No +
+ take + + Int + + No +
+ skip + + Int + + No +
+ distinct + + VideoProcessingTaskScalarFieldEnum | VideoProcessingTaskScalarFieldEnum[] + + No +
+

Output

+ +
Required: + Yes
+
List: + Yes
+
+
+
+

create

+

Create one VideoProcessingTask

+
+
// Create one VideoProcessingTask
+const VideoProcessingTask = await prisma.videoProcessingTask.create({
+  data: {
+    // ... data to create a VideoProcessingTask
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + VideoProcessingTaskCreateInput | VideoProcessingTaskUncheckedCreateInput + + Yes +
+

Output

+ +
Required: + Yes
+
List: + No
+
+
+
+

delete

+

Delete one VideoProcessingTask

+
+
// Delete one VideoProcessingTask
+const VideoProcessingTask = await prisma.videoProcessingTask.delete({
+  where: {
+    // ... filter to delete one VideoProcessingTask
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + VideoProcessingTaskWhereUniqueInput + + Yes +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

update

+

Update one VideoProcessingTask

+
+
// Update one VideoProcessingTask
+const videoProcessingTask = await prisma.videoProcessingTask.update({
+  where: {
+    // ... provide filter here
+  },
+  data: {
+    // ... provide data here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + VideoProcessingTaskUpdateInput | VideoProcessingTaskUncheckedUpdateInput + + Yes +
+ where + + VideoProcessingTaskWhereUniqueInput + + Yes +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

deleteMany

+

Delete zero or more VideoProcessingTask

+
+
// Delete a few VideoProcessingTask
+const { count } = await prisma.videoProcessingTask.deleteMany({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + VideoProcessingTaskWhereInput + + No +
+ limit + + Int + + No +
+

Output

+ +
Required: + Yes
+
List: + No
+
+
+
+

updateMany

+

Update zero or one VideoProcessingTask

+
+
const { count } = await prisma.videoProcessingTask.updateMany({
+  where: {
+    // ... provide filter here
+  },
+  data: {
+    // ... provide data here
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + VideoProcessingTaskUpdateManyMutationInput | VideoProcessingTaskUncheckedUpdateManyInput + + Yes +
+ where + + VideoProcessingTaskWhereInput + + No +
+ limit + + Int + + No +
+

Output

+ +
Required: + Yes
+
List: + No
+
+
+
+

upsert

+

Create or update one VideoProcessingTask

+
+
// Update or create a VideoProcessingTask
+const videoProcessingTask = await prisma.videoProcessingTask.upsert({
+  create: {
+    // ... data to create a VideoProcessingTask
+  },
+  update: {
+    // ... in case it already exists, update
+  },
+  where: {
+    // ... the filter for the VideoProcessingTask we want to update
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + VideoProcessingTaskWhereUniqueInput + + Yes +
+ create + + VideoProcessingTaskCreateInput | VideoProcessingTaskUncheckedCreateInput + + Yes +
+ update + + VideoProcessingTaskUpdateInput | VideoProcessingTaskUncheckedUpdateInput + + Yes +
+

Output

+ +
Required: + Yes
+
List: + No
+
+ +
+
+
+ +
+ +
+

Types

+
+
+

Input Types

+
+ +
+

MediaFileWhereInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ AND + MediaFileWhereInput | MediaFileWhereInput[] + + No +
+ OR + MediaFileWhereInput[] + + No +
+ NOT + MediaFileWhereInput | MediaFileWhereInput[] + + No +
+ id + StringFilter | String + + No +
+ bucket + StringFilter | String + + No +
+ key + StringFilter | String + + No +
+ mimetype + StringFilter | String + + No +
+ url + StringNullableFilter | String | Null + + Yes +
+ srcUrl + StringNullableFilter | String | Null + + Yes +
+ createdAt + DateTimeFilter | DateTime + + No +
+ updatedAt + DateTimeFilter | DateTime + + No +
+ meetingRecordId + StringNullableFilter | String | Null + + Yes +
+ title + StringNullableFilter | String | Null + + Yes +
+ description + StringNullableFilter | String | Null + + Yes +
+ fileSize + IntNullableFilter | Int | Null + + Yes +
+ videoProcessingTaskVideos + VideoProcessingTaskListRelationFilter + + No +
+ videoProcessingTaskAudios + VideoProcessingTaskListRelationFilter + + No +
+
+
+
+

MediaFileOrderByWithRelationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ bucket + SortOrder + + No +
+ key + SortOrder + + No +
+ mimetype + SortOrder + + No +
+ url + SortOrder | SortOrderInput + + No +
+ srcUrl + SortOrder | SortOrderInput + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ meetingRecordId + SortOrder | SortOrderInput + + No +
+ title + SortOrder | SortOrderInput + + No +
+ description + SortOrder | SortOrderInput + + No +
+ fileSize + SortOrder | SortOrderInput + + No +
+ videoProcessingTaskVideos + VideoProcessingTaskOrderByRelationAggregateInput + + No +
+ videoProcessingTaskAudios + VideoProcessingTaskOrderByRelationAggregateInput + + No +
+
+
+
+

MediaFileWhereUniqueInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ AND + MediaFileWhereInput | MediaFileWhereInput[] + + No +
+ OR + MediaFileWhereInput[] + + No +
+ NOT + MediaFileWhereInput | MediaFileWhereInput[] + + No +
+ bucket + StringFilter | String + + No +
+ key + StringFilter | String + + No +
+ mimetype + StringFilter | String + + No +
+ url + StringNullableFilter | String | Null + + Yes +
+ srcUrl + StringNullableFilter | String | Null + + Yes +
+ createdAt + DateTimeFilter | DateTime + + No +
+ updatedAt + DateTimeFilter | DateTime + + No +
+ meetingRecordId + StringNullableFilter | String | Null + + Yes +
+ title + StringNullableFilter | String | Null + + Yes +
+ description + StringNullableFilter | String | Null + + Yes +
+ fileSize + IntNullableFilter | Int | Null + + Yes +
+ videoProcessingTaskVideos + VideoProcessingTaskListRelationFilter + + No +
+ videoProcessingTaskAudios + VideoProcessingTaskListRelationFilter + + No +
+
+
+
+

MediaFileOrderByWithAggregationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ bucket + SortOrder + + No +
+ key + SortOrder + + No +
+ mimetype + SortOrder + + No +
+ url + SortOrder | SortOrderInput + + No +
+ srcUrl + SortOrder | SortOrderInput + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ meetingRecordId + SortOrder | SortOrderInput + + No +
+ title + SortOrder | SortOrderInput + + No +
+ description + SortOrder | SortOrderInput + + No +
+ fileSize + SortOrder | SortOrderInput + + No +
+ _count + MediaFileCountOrderByAggregateInput + + No +
+ _avg + MediaFileAvgOrderByAggregateInput + + No +
+ _max + MediaFileMaxOrderByAggregateInput + + No +
+ _min + MediaFileMinOrderByAggregateInput + + No +
+ _sum + MediaFileSumOrderByAggregateInput + + No +
+
+
+
+

MediaFileScalarWhereWithAggregatesInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ AND + MediaFileScalarWhereWithAggregatesInput | MediaFileScalarWhereWithAggregatesInput[] + + No +
+ OR + MediaFileScalarWhereWithAggregatesInput[] + + No +
+ NOT + MediaFileScalarWhereWithAggregatesInput | MediaFileScalarWhereWithAggregatesInput[] + + No +
+ id + StringWithAggregatesFilter | String + + No +
+ bucket + StringWithAggregatesFilter | String + + No +
+ key + StringWithAggregatesFilter | String + + No +
+ mimetype + StringWithAggregatesFilter | String + + No +
+ url + StringNullableWithAggregatesFilter | String | Null + + Yes +
+ srcUrl + StringNullableWithAggregatesFilter | String | Null + + Yes +
+ createdAt + DateTimeWithAggregatesFilter | DateTime + + No +
+ updatedAt + DateTimeWithAggregatesFilter | DateTime + + No +
+ meetingRecordId + StringNullableWithAggregatesFilter | String | Null + + Yes +
+ title + StringNullableWithAggregatesFilter | String | Null + + Yes +
+ description + StringNullableWithAggregatesFilter | String | Null + + Yes +
+ fileSize + IntNullableWithAggregatesFilter | Int | Null + + Yes +
+
+
+
+

VideoProcessingBatchWhereInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ AND + VideoProcessingBatchWhereInput | VideoProcessingBatchWhereInput[] + + No +
+ OR + VideoProcessingBatchWhereInput[] + + No +
+ NOT + VideoProcessingBatchWhereInput | VideoProcessingBatchWhereInput[] + + No +
+ id + StringFilter | String + + No +
+ status + StringFilter | String + + No +
+ totalTasks + IntFilter | Int + + No +
+ completedTasks + IntFilter | Int + + No +
+ failedTasks + IntFilter | Int + + No +
+ createdAt + DateTimeFilter | DateTime + + No +
+ updatedAt + DateTimeFilter | DateTime + + No +
+ tasks + VideoProcessingTaskListRelationFilter + + No +
+
+
+
+

VideoProcessingBatchOrderByWithRelationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ status + SortOrder + + No +
+ totalTasks + SortOrder + + No +
+ completedTasks + SortOrder + + No +
+ failedTasks + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ tasks + VideoProcessingTaskOrderByRelationAggregateInput + + No +
+
+
+
+

VideoProcessingBatchWhereUniqueInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ AND + VideoProcessingBatchWhereInput | VideoProcessingBatchWhereInput[] + + No +
+ OR + VideoProcessingBatchWhereInput[] + + No +
+ NOT + VideoProcessingBatchWhereInput | VideoProcessingBatchWhereInput[] + + No +
+ status + StringFilter | String + + No +
+ totalTasks + IntFilter | Int + + No +
+ completedTasks + IntFilter | Int + + No +
+ failedTasks + IntFilter | Int + + No +
+ createdAt + DateTimeFilter | DateTime + + No +
+ updatedAt + DateTimeFilter | DateTime + + No +
+ tasks + VideoProcessingTaskListRelationFilter + + No +
+
+
+
+

VideoProcessingBatchOrderByWithAggregationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ status + SortOrder + + No +
+ totalTasks + SortOrder + + No +
+ completedTasks + SortOrder + + No +
+ failedTasks + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ _count + VideoProcessingBatchCountOrderByAggregateInput + + No +
+ _avg + VideoProcessingBatchAvgOrderByAggregateInput + + No +
+ _max + VideoProcessingBatchMaxOrderByAggregateInput + + No +
+ _min + VideoProcessingBatchMinOrderByAggregateInput + + No +
+ _sum + VideoProcessingBatchSumOrderByAggregateInput + + No +
+
+
+
+

VideoProcessingBatchScalarWhereWithAggregatesInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ AND + VideoProcessingBatchScalarWhereWithAggregatesInput | VideoProcessingBatchScalarWhereWithAggregatesInput[] + + No +
+ OR + VideoProcessingBatchScalarWhereWithAggregatesInput[] + + No +
+ NOT + VideoProcessingBatchScalarWhereWithAggregatesInput | VideoProcessingBatchScalarWhereWithAggregatesInput[] + + No +
+ id + StringWithAggregatesFilter | String + + No +
+ status + StringWithAggregatesFilter | String + + No +
+ totalTasks + IntWithAggregatesFilter | Int + + No +
+ completedTasks + IntWithAggregatesFilter | Int + + No +
+ failedTasks + IntWithAggregatesFilter | Int + + No +
+ createdAt + DateTimeWithAggregatesFilter | DateTime + + No +
+ updatedAt + DateTimeWithAggregatesFilter | DateTime + + No +
+
+
+
+

VideoProcessingTaskWhereInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ AND + VideoProcessingTaskWhereInput | VideoProcessingTaskWhereInput[] + + No +
+ OR + VideoProcessingTaskWhereInput[] + + No +
+ NOT + VideoProcessingTaskWhereInput | VideoProcessingTaskWhereInput[] + + No +
+ id + StringFilter | String + + No +
+ viewerUrl + StringNullableFilter | String | Null + + Yes +
+ downloadUrl + StringNullableFilter | String | Null + + Yes +
+ status + StringFilter | String + + No +
+ extractAudio + BoolFilter | Boolean + + No +
+ error + StringNullableFilter | String | Null + + Yes +
+ createdAt + DateTimeFilter | DateTime + + No +
+ updatedAt + DateTimeFilter | DateTime + + No +
+ batchId + StringNullableFilter | String | Null + + Yes +
+ meetingRecordId + StringNullableFilter | String | Null + + Yes +
+ videoId + StringNullableFilter | String | Null + + Yes +
+ audioId + StringNullableFilter | String | Null + + Yes +
+ batch + VideoProcessingBatchNullableScalarRelationFilter | VideoProcessingBatchWhereInput | Null + + Yes +
+ video + MediaFileNullableScalarRelationFilter | MediaFileWhereInput | Null + + Yes +
+ audio + MediaFileNullableScalarRelationFilter | MediaFileWhereInput | Null + + Yes +
+
+
+
+

VideoProcessingTaskOrderByWithRelationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ viewerUrl + SortOrder | SortOrderInput + + No +
+ downloadUrl + SortOrder | SortOrderInput + + No +
+ status + SortOrder + + No +
+ extractAudio + SortOrder + + No +
+ error + SortOrder | SortOrderInput + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ batchId + SortOrder | SortOrderInput + + No +
+ meetingRecordId + SortOrder | SortOrderInput + + No +
+ videoId + SortOrder | SortOrderInput + + No +
+ audioId + SortOrder | SortOrderInput + + No +
+ batch + VideoProcessingBatchOrderByWithRelationInput + + No +
+ video + MediaFileOrderByWithRelationInput + + No +
+ audio + MediaFileOrderByWithRelationInput + + No +
+
+
+
+

VideoProcessingTaskWhereUniqueInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ AND + VideoProcessingTaskWhereInput | VideoProcessingTaskWhereInput[] + + No +
+ OR + VideoProcessingTaskWhereInput[] + + No +
+ NOT + VideoProcessingTaskWhereInput | VideoProcessingTaskWhereInput[] + + No +
+ viewerUrl + StringNullableFilter | String | Null + + Yes +
+ downloadUrl + StringNullableFilter | String | Null + + Yes +
+ status + StringFilter | String + + No +
+ extractAudio + BoolFilter | Boolean + + No +
+ error + StringNullableFilter | String | Null + + Yes +
+ createdAt + DateTimeFilter | DateTime + + No +
+ updatedAt + DateTimeFilter | DateTime + + No +
+ batchId + StringNullableFilter | String | Null + + Yes +
+ meetingRecordId + StringNullableFilter | String | Null + + Yes +
+ videoId + StringNullableFilter | String | Null + + Yes +
+ audioId + StringNullableFilter | String | Null + + Yes +
+ batch + VideoProcessingBatchNullableScalarRelationFilter | VideoProcessingBatchWhereInput | Null + + Yes +
+ video + MediaFileNullableScalarRelationFilter | MediaFileWhereInput | Null + + Yes +
+ audio + MediaFileNullableScalarRelationFilter | MediaFileWhereInput | Null + + Yes +
+
+
+
+

VideoProcessingTaskOrderByWithAggregationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ viewerUrl + SortOrder | SortOrderInput + + No +
+ downloadUrl + SortOrder | SortOrderInput + + No +
+ status + SortOrder + + No +
+ extractAudio + SortOrder + + No +
+ error + SortOrder | SortOrderInput + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ batchId + SortOrder | SortOrderInput + + No +
+ meetingRecordId + SortOrder | SortOrderInput + + No +
+ videoId + SortOrder | SortOrderInput + + No +
+ audioId + SortOrder | SortOrderInput + + No +
+ _count + VideoProcessingTaskCountOrderByAggregateInput + + No +
+ _max + VideoProcessingTaskMaxOrderByAggregateInput + + No +
+ _min + VideoProcessingTaskMinOrderByAggregateInput + + No +
+
+
+
+

VideoProcessingTaskScalarWhereWithAggregatesInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ AND + VideoProcessingTaskScalarWhereWithAggregatesInput | VideoProcessingTaskScalarWhereWithAggregatesInput[] + + No +
+ OR + VideoProcessingTaskScalarWhereWithAggregatesInput[] + + No +
+ NOT + VideoProcessingTaskScalarWhereWithAggregatesInput | VideoProcessingTaskScalarWhereWithAggregatesInput[] + + No +
+ id + StringWithAggregatesFilter | String + + No +
+ viewerUrl + StringNullableWithAggregatesFilter | String | Null + + Yes +
+ downloadUrl + StringNullableWithAggregatesFilter | String | Null + + Yes +
+ status + StringWithAggregatesFilter | String + + No +
+ extractAudio + BoolWithAggregatesFilter | Boolean + + No +
+ error + StringNullableWithAggregatesFilter | String | Null + + Yes +
+ createdAt + DateTimeWithAggregatesFilter | DateTime + + No +
+ updatedAt + DateTimeWithAggregatesFilter | DateTime + + No +
+ batchId + StringNullableWithAggregatesFilter | String | Null + + Yes +
+ meetingRecordId + StringNullableWithAggregatesFilter | String | Null + + Yes +
+ videoId + StringNullableWithAggregatesFilter | String | Null + + Yes +
+ audioId + StringNullableWithAggregatesFilter | String | Null + + Yes +
+
+
+
+

MediaFileCreateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ bucket + String + + No +
+ key + String + + No +
+ mimetype + String + + No +
+ url + String | Null + + Yes +
+ srcUrl + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ meetingRecordId + String | Null + + Yes +
+ title + String | Null + + Yes +
+ description + String | Null + + Yes +
+ fileSize + Int | Null + + Yes +
+ videoProcessingTaskVideos + VideoProcessingTaskCreateNestedManyWithoutVideoInput + + No +
+ videoProcessingTaskAudios + VideoProcessingTaskCreateNestedManyWithoutAudioInput + + No +
+
+
+
+

MediaFileUncheckedCreateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ bucket + String + + No +
+ key + String + + No +
+ mimetype + String + + No +
+ url + String | Null + + Yes +
+ srcUrl + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ meetingRecordId + String | Null + + Yes +
+ title + String | Null + + Yes +
+ description + String | Null + + Yes +
+ fileSize + Int | Null + + Yes +
+ videoProcessingTaskVideos + VideoProcessingTaskUncheckedCreateNestedManyWithoutVideoInput + + No +
+ videoProcessingTaskAudios + VideoProcessingTaskUncheckedCreateNestedManyWithoutAudioInput + + No +
+
+
+
+

MediaFileUpdateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ bucket + String | StringFieldUpdateOperationsInput + + No +
+ key + String | StringFieldUpdateOperationsInput + + No +
+ mimetype + String | StringFieldUpdateOperationsInput + + No +
+ url + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ srcUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ title + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ description + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ fileSize + Int | NullableIntFieldUpdateOperationsInput | Null + + Yes +
+ videoProcessingTaskVideos + VideoProcessingTaskUpdateManyWithoutVideoNestedInput + + No +
+ videoProcessingTaskAudios + VideoProcessingTaskUpdateManyWithoutAudioNestedInput + + No +
+
+
+
+

MediaFileUncheckedUpdateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ bucket + String | StringFieldUpdateOperationsInput + + No +
+ key + String | StringFieldUpdateOperationsInput + + No +
+ mimetype + String | StringFieldUpdateOperationsInput + + No +
+ url + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ srcUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ title + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ description + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ fileSize + Int | NullableIntFieldUpdateOperationsInput | Null + + Yes +
+ videoProcessingTaskVideos + VideoProcessingTaskUncheckedUpdateManyWithoutVideoNestedInput + + No +
+ videoProcessingTaskAudios + VideoProcessingTaskUncheckedUpdateManyWithoutAudioNestedInput + + No +
+
+
+
+

MediaFileCreateManyInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ bucket + String + + No +
+ key + String + + No +
+ mimetype + String + + No +
+ url + String | Null + + Yes +
+ srcUrl + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ meetingRecordId + String | Null + + Yes +
+ title + String | Null + + Yes +
+ description + String | Null + + Yes +
+ fileSize + Int | Null + + Yes +
+
+
+
+

MediaFileUpdateManyMutationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ bucket + String | StringFieldUpdateOperationsInput + + No +
+ key + String | StringFieldUpdateOperationsInput + + No +
+ mimetype + String | StringFieldUpdateOperationsInput + + No +
+ url + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ srcUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ title + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ description + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ fileSize + Int | NullableIntFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

MediaFileUncheckedUpdateManyInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ bucket + String | StringFieldUpdateOperationsInput + + No +
+ key + String | StringFieldUpdateOperationsInput + + No +
+ mimetype + String | StringFieldUpdateOperationsInput + + No +
+ url + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ srcUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ title + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ description + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ fileSize + Int | NullableIntFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

VideoProcessingBatchCreateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ status + String + + No +
+ totalTasks + Int + + No +
+ completedTasks + Int + + No +
+ failedTasks + Int + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ tasks + VideoProcessingTaskCreateNestedManyWithoutBatchInput + + No +
+
+
+
+

VideoProcessingBatchUncheckedCreateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ status + String + + No +
+ totalTasks + Int + + No +
+ completedTasks + Int + + No +
+ failedTasks + Int + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ tasks + VideoProcessingTaskUncheckedCreateNestedManyWithoutBatchInput + + No +
+
+
+
+

VideoProcessingBatchUpdateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ totalTasks + Int | IntFieldUpdateOperationsInput + + No +
+ completedTasks + Int | IntFieldUpdateOperationsInput + + No +
+ failedTasks + Int | IntFieldUpdateOperationsInput + + No +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ tasks + VideoProcessingTaskUpdateManyWithoutBatchNestedInput + + No +
+
+
+
+

VideoProcessingBatchUncheckedUpdateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ totalTasks + Int | IntFieldUpdateOperationsInput + + No +
+ completedTasks + Int | IntFieldUpdateOperationsInput + + No +
+ failedTasks + Int | IntFieldUpdateOperationsInput + + No +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ tasks + VideoProcessingTaskUncheckedUpdateManyWithoutBatchNestedInput + + No +
+
+
+
+

VideoProcessingBatchCreateManyInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ status + String + + No +
+ totalTasks + Int + + No +
+ completedTasks + Int + + No +
+ failedTasks + Int + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+
+
+
+

VideoProcessingBatchUpdateManyMutationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ totalTasks + Int | IntFieldUpdateOperationsInput + + No +
+ completedTasks + Int | IntFieldUpdateOperationsInput + + No +
+ failedTasks + Int | IntFieldUpdateOperationsInput + + No +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+
+
+
+

VideoProcessingBatchUncheckedUpdateManyInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ totalTasks + Int | IntFieldUpdateOperationsInput + + No +
+ completedTasks + Int | IntFieldUpdateOperationsInput + + No +
+ failedTasks + Int | IntFieldUpdateOperationsInput + + No +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+
+
+
+

VideoProcessingTaskCreateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ viewerUrl + String | Null + + Yes +
+ downloadUrl + String | Null + + Yes +
+ status + String + + No +
+ extractAudio + Boolean + + No +
+ error + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ meetingRecordId + String | Null + + Yes +
+ batch + VideoProcessingBatchCreateNestedOneWithoutTasksInput + + No +
+ video + MediaFileCreateNestedOneWithoutVideoProcessingTaskVideosInput + + No +
+ audio + MediaFileCreateNestedOneWithoutVideoProcessingTaskAudiosInput + + No +
+
+
+
+

VideoProcessingTaskUncheckedCreateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ viewerUrl + String | Null + + Yes +
+ downloadUrl + String | Null + + Yes +
+ status + String + + No +
+ extractAudio + Boolean + + No +
+ error + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ batchId + String | Null + + Yes +
+ meetingRecordId + String | Null + + Yes +
+ videoId + String | Null + + Yes +
+ audioId + String | Null + + Yes +
+
+
+
+

VideoProcessingTaskUpdateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ viewerUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ downloadUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ extractAudio + Boolean | BoolFieldUpdateOperationsInput + + No +
+ error + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ batch + VideoProcessingBatchUpdateOneWithoutTasksNestedInput + + No +
+ video + MediaFileUpdateOneWithoutVideoProcessingTaskVideosNestedInput + + No +
+ audio + MediaFileUpdateOneWithoutVideoProcessingTaskAudiosNestedInput + + No +
+
+
+
+

VideoProcessingTaskUncheckedUpdateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ viewerUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ downloadUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ extractAudio + Boolean | BoolFieldUpdateOperationsInput + + No +
+ error + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ batchId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ videoId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ audioId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

VideoProcessingTaskCreateManyInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ viewerUrl + String | Null + + Yes +
+ downloadUrl + String | Null + + Yes +
+ status + String + + No +
+ extractAudio + Boolean + + No +
+ error + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ batchId + String | Null + + Yes +
+ meetingRecordId + String | Null + + Yes +
+ videoId + String | Null + + Yes +
+ audioId + String | Null + + Yes +
+
+
+
+

VideoProcessingTaskUpdateManyMutationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ viewerUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ downloadUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ extractAudio + Boolean | BoolFieldUpdateOperationsInput + + No +
+ error + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

VideoProcessingTaskUncheckedUpdateManyInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ viewerUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ downloadUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ extractAudio + Boolean | BoolFieldUpdateOperationsInput + + No +
+ error + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ batchId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ videoId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ audioId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

StringFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput + + No +
+ in + String | ListStringFieldRefInput + + No +
+ notIn + String | ListStringFieldRefInput + + No +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ mode + QueryMode + + No +
+ not + String | NestedStringFilter + + No +
+
+
+
+

StringNullableFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput | Null + + Yes +
+ in + String | ListStringFieldRefInput | Null + + Yes +
+ notIn + String | ListStringFieldRefInput | Null + + Yes +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ mode + QueryMode + + No +
+ not + String | NestedStringNullableFilter | Null + + Yes +
+
+
+
+

DateTimeFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + DateTime | DateTimeFieldRefInput + + No +
+ in + DateTime | ListDateTimeFieldRefInput + + No +
+ notIn + DateTime | ListDateTimeFieldRefInput + + No +
+ lt + DateTime | DateTimeFieldRefInput + + No +
+ lte + DateTime | DateTimeFieldRefInput + + No +
+ gt + DateTime | DateTimeFieldRefInput + + No +
+ gte + DateTime | DateTimeFieldRefInput + + No +
+ not + DateTime | NestedDateTimeFilter + + No +
+
+
+
+

IntNullableFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Int | IntFieldRefInput | Null + + Yes +
+ in + Int | ListIntFieldRefInput | Null + + Yes +
+ notIn + Int | ListIntFieldRefInput | Null + + Yes +
+ lt + Int | IntFieldRefInput + + No +
+ lte + Int | IntFieldRefInput + + No +
+ gt + Int | IntFieldRefInput + + No +
+ gte + Int | IntFieldRefInput + + No +
+ not + Int | NestedIntNullableFilter | Null + + Yes +
+
+
+
+

VideoProcessingTaskListRelationFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ every + VideoProcessingTaskWhereInput + + No +
+ some + VideoProcessingTaskWhereInput + + No +
+ none + VideoProcessingTaskWhereInput + + No +
+
+
+
+

SortOrderInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ sort + SortOrder + + No +
+ nulls + NullsOrder + + No +
+
+
+
+

VideoProcessingTaskOrderByRelationAggregateInput

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ _count + SortOrder + + No +
+
+
+
+

MediaFileCountOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ bucket + SortOrder + + No +
+ key + SortOrder + + No +
+ mimetype + SortOrder + + No +
+ url + SortOrder + + No +
+ srcUrl + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ meetingRecordId + SortOrder + + No +
+ title + SortOrder + + No +
+ description + SortOrder + + No +
+ fileSize + SortOrder + + No +
+
+
+
+

MediaFileAvgOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ fileSize + SortOrder + + No +
+
+
+
+

MediaFileMaxOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ bucket + SortOrder + + No +
+ key + SortOrder + + No +
+ mimetype + SortOrder + + No +
+ url + SortOrder + + No +
+ srcUrl + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ meetingRecordId + SortOrder + + No +
+ title + SortOrder + + No +
+ description + SortOrder + + No +
+ fileSize + SortOrder + + No +
+
+
+
+

MediaFileMinOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ bucket + SortOrder + + No +
+ key + SortOrder + + No +
+ mimetype + SortOrder + + No +
+ url + SortOrder + + No +
+ srcUrl + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ meetingRecordId + SortOrder + + No +
+ title + SortOrder + + No +
+ description + SortOrder + + No +
+ fileSize + SortOrder + + No +
+
+
+
+

MediaFileSumOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ fileSize + SortOrder + + No +
+
+
+
+

StringWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput + + No +
+ in + String | ListStringFieldRefInput + + No +
+ notIn + String | ListStringFieldRefInput + + No +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ mode + QueryMode + + No +
+ not + String | NestedStringWithAggregatesFilter + + No +
+ _count + NestedIntFilter + + No +
+ _min + NestedStringFilter + + No +
+ _max + NestedStringFilter + + No +
+
+
+
+

StringNullableWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput | Null + + Yes +
+ in + String | ListStringFieldRefInput | Null + + Yes +
+ notIn + String | ListStringFieldRefInput | Null + + Yes +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ mode + QueryMode + + No +
+ not + String | NestedStringNullableWithAggregatesFilter | Null + + Yes +
+ _count + NestedIntNullableFilter + + No +
+ _min + NestedStringNullableFilter + + No +
+ _max + NestedStringNullableFilter + + No +
+
+
+
+

DateTimeWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + DateTime | DateTimeFieldRefInput + + No +
+ in + DateTime | ListDateTimeFieldRefInput + + No +
+ notIn + DateTime | ListDateTimeFieldRefInput + + No +
+ lt + DateTime | DateTimeFieldRefInput + + No +
+ lte + DateTime | DateTimeFieldRefInput + + No +
+ gt + DateTime | DateTimeFieldRefInput + + No +
+ gte + DateTime | DateTimeFieldRefInput + + No +
+ not + DateTime | NestedDateTimeWithAggregatesFilter + + No +
+ _count + NestedIntFilter + + No +
+ _min + NestedDateTimeFilter + + No +
+ _max + NestedDateTimeFilter + + No +
+
+
+
+

IntNullableWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Int | IntFieldRefInput | Null + + Yes +
+ in + Int | ListIntFieldRefInput | Null + + Yes +
+ notIn + Int | ListIntFieldRefInput | Null + + Yes +
+ lt + Int | IntFieldRefInput + + No +
+ lte + Int | IntFieldRefInput + + No +
+ gt + Int | IntFieldRefInput + + No +
+ gte + Int | IntFieldRefInput + + No +
+ not + Int | NestedIntNullableWithAggregatesFilter | Null + + Yes +
+ _count + NestedIntNullableFilter + + No +
+ _avg + NestedFloatNullableFilter + + No +
+ _sum + NestedIntNullableFilter + + No +
+ _min + NestedIntNullableFilter + + No +
+ _max + NestedIntNullableFilter + + No +
+
+
+
+

IntFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Int | IntFieldRefInput + + No +
+ in + Int | ListIntFieldRefInput + + No +
+ notIn + Int | ListIntFieldRefInput + + No +
+ lt + Int | IntFieldRefInput + + No +
+ lte + Int | IntFieldRefInput + + No +
+ gt + Int | IntFieldRefInput + + No +
+ gte + Int | IntFieldRefInput + + No +
+ not + Int | NestedIntFilter + + No +
+
+
+
+

VideoProcessingBatchCountOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ status + SortOrder + + No +
+ totalTasks + SortOrder + + No +
+ completedTasks + SortOrder + + No +
+ failedTasks + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+
+
+
+

VideoProcessingBatchAvgOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ totalTasks + SortOrder + + No +
+ completedTasks + SortOrder + + No +
+ failedTasks + SortOrder + + No +
+
+
+
+

VideoProcessingBatchMaxOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ status + SortOrder + + No +
+ totalTasks + SortOrder + + No +
+ completedTasks + SortOrder + + No +
+ failedTasks + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+
+
+
+

VideoProcessingBatchMinOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ status + SortOrder + + No +
+ totalTasks + SortOrder + + No +
+ completedTasks + SortOrder + + No +
+ failedTasks + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+
+
+
+

VideoProcessingBatchSumOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ totalTasks + SortOrder + + No +
+ completedTasks + SortOrder + + No +
+ failedTasks + SortOrder + + No +
+
+
+
+

IntWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Int | IntFieldRefInput + + No +
+ in + Int | ListIntFieldRefInput + + No +
+ notIn + Int | ListIntFieldRefInput + + No +
+ lt + Int | IntFieldRefInput + + No +
+ lte + Int | IntFieldRefInput + + No +
+ gt + Int | IntFieldRefInput + + No +
+ gte + Int | IntFieldRefInput + + No +
+ not + Int | NestedIntWithAggregatesFilter + + No +
+ _count + NestedIntFilter + + No +
+ _avg + NestedFloatFilter + + No +
+ _sum + NestedIntFilter + + No +
+ _min + NestedIntFilter + + No +
+ _max + NestedIntFilter + + No +
+
+
+
+

BoolFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Boolean | BooleanFieldRefInput + + No +
+ not + Boolean | NestedBoolFilter + + No +
+
+
+
+

VideoProcessingBatchNullableScalarRelationFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ is + VideoProcessingBatchWhereInput | Null + + Yes +
+ isNot + VideoProcessingBatchWhereInput | Null + + Yes +
+
+
+
+

MediaFileNullableScalarRelationFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ is + MediaFileWhereInput | Null + + Yes +
+ isNot + MediaFileWhereInput | Null + + Yes +
+
+
+
+

VideoProcessingTaskCountOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ viewerUrl + SortOrder + + No +
+ downloadUrl + SortOrder + + No +
+ status + SortOrder + + No +
+ extractAudio + SortOrder + + No +
+ error + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ batchId + SortOrder + + No +
+ meetingRecordId + SortOrder + + No +
+ videoId + SortOrder + + No +
+ audioId + SortOrder + + No +
+
+
+
+

VideoProcessingTaskMaxOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ viewerUrl + SortOrder + + No +
+ downloadUrl + SortOrder + + No +
+ status + SortOrder + + No +
+ extractAudio + SortOrder + + No +
+ error + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ batchId + SortOrder + + No +
+ meetingRecordId + SortOrder + + No +
+ videoId + SortOrder + + No +
+ audioId + SortOrder + + No +
+
+
+
+

VideoProcessingTaskMinOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ viewerUrl + SortOrder + + No +
+ downloadUrl + SortOrder + + No +
+ status + SortOrder + + No +
+ extractAudio + SortOrder + + No +
+ error + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ batchId + SortOrder + + No +
+ meetingRecordId + SortOrder + + No +
+ videoId + SortOrder + + No +
+ audioId + SortOrder + + No +
+
+
+
+

BoolWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Boolean | BooleanFieldRefInput + + No +
+ not + Boolean | NestedBoolWithAggregatesFilter + + No +
+ _count + NestedIntFilter + + No +
+ _min + NestedBoolFilter + + No +
+ _max + NestedBoolFilter + + No +
+
+
+ +
+ +
+
+

VideoProcessingTaskUncheckedCreateNestedManyWithoutVideoInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + VideoProcessingTaskCreateWithoutVideoInput | VideoProcessingTaskCreateWithoutVideoInput[] | VideoProcessingTaskUncheckedCreateWithoutVideoInput | VideoProcessingTaskUncheckedCreateWithoutVideoInput[] + + No +
+ connectOrCreate + VideoProcessingTaskCreateOrConnectWithoutVideoInput | VideoProcessingTaskCreateOrConnectWithoutVideoInput[] + + No +
+ createMany + VideoProcessingTaskCreateManyVideoInputEnvelope + + No +
+ connect + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+
+
+
+

VideoProcessingTaskUncheckedCreateNestedManyWithoutAudioInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + VideoProcessingTaskCreateWithoutAudioInput | VideoProcessingTaskCreateWithoutAudioInput[] | VideoProcessingTaskUncheckedCreateWithoutAudioInput | VideoProcessingTaskUncheckedCreateWithoutAudioInput[] + + No +
+ connectOrCreate + VideoProcessingTaskCreateOrConnectWithoutAudioInput | VideoProcessingTaskCreateOrConnectWithoutAudioInput[] + + No +
+ createMany + VideoProcessingTaskCreateManyAudioInputEnvelope + + No +
+ connect + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+
+
+
+

StringFieldUpdateOperationsInput

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ set + String + + No +
+
+
+
+

NullableStringFieldUpdateOperationsInput

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ set + String | Null + + Yes +
+
+
+
+

DateTimeFieldUpdateOperationsInput

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ set + DateTime + + No +
+
+
+
+

NullableIntFieldUpdateOperationsInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ set + Int | Null + + Yes +
+ increment + Int + + No +
+ decrement + Int + + No +
+ multiply + Int + + No +
+ divide + Int + + No +
+
+
+
+

VideoProcessingTaskUpdateManyWithoutVideoNestedInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + VideoProcessingTaskCreateWithoutVideoInput | VideoProcessingTaskCreateWithoutVideoInput[] | VideoProcessingTaskUncheckedCreateWithoutVideoInput | VideoProcessingTaskUncheckedCreateWithoutVideoInput[] + + No +
+ connectOrCreate + VideoProcessingTaskCreateOrConnectWithoutVideoInput | VideoProcessingTaskCreateOrConnectWithoutVideoInput[] + + No +
+ upsert + VideoProcessingTaskUpsertWithWhereUniqueWithoutVideoInput | VideoProcessingTaskUpsertWithWhereUniqueWithoutVideoInput[] + + No +
+ createMany + VideoProcessingTaskCreateManyVideoInputEnvelope + + No +
+ set + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ disconnect + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ delete + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ connect + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ update + VideoProcessingTaskUpdateWithWhereUniqueWithoutVideoInput | VideoProcessingTaskUpdateWithWhereUniqueWithoutVideoInput[] + + No +
+ updateMany + VideoProcessingTaskUpdateManyWithWhereWithoutVideoInput | VideoProcessingTaskUpdateManyWithWhereWithoutVideoInput[] + + No +
+ deleteMany + VideoProcessingTaskScalarWhereInput | VideoProcessingTaskScalarWhereInput[] + + No +
+
+
+
+

VideoProcessingTaskUpdateManyWithoutAudioNestedInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + VideoProcessingTaskCreateWithoutAudioInput | VideoProcessingTaskCreateWithoutAudioInput[] | VideoProcessingTaskUncheckedCreateWithoutAudioInput | VideoProcessingTaskUncheckedCreateWithoutAudioInput[] + + No +
+ connectOrCreate + VideoProcessingTaskCreateOrConnectWithoutAudioInput | VideoProcessingTaskCreateOrConnectWithoutAudioInput[] + + No +
+ upsert + VideoProcessingTaskUpsertWithWhereUniqueWithoutAudioInput | VideoProcessingTaskUpsertWithWhereUniqueWithoutAudioInput[] + + No +
+ createMany + VideoProcessingTaskCreateManyAudioInputEnvelope + + No +
+ set + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ disconnect + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ delete + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ connect + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ update + VideoProcessingTaskUpdateWithWhereUniqueWithoutAudioInput | VideoProcessingTaskUpdateWithWhereUniqueWithoutAudioInput[] + + No +
+ updateMany + VideoProcessingTaskUpdateManyWithWhereWithoutAudioInput | VideoProcessingTaskUpdateManyWithWhereWithoutAudioInput[] + + No +
+ deleteMany + VideoProcessingTaskScalarWhereInput | VideoProcessingTaskScalarWhereInput[] + + No +
+
+
+
+

VideoProcessingTaskUncheckedUpdateManyWithoutVideoNestedInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + VideoProcessingTaskCreateWithoutVideoInput | VideoProcessingTaskCreateWithoutVideoInput[] | VideoProcessingTaskUncheckedCreateWithoutVideoInput | VideoProcessingTaskUncheckedCreateWithoutVideoInput[] + + No +
+ connectOrCreate + VideoProcessingTaskCreateOrConnectWithoutVideoInput | VideoProcessingTaskCreateOrConnectWithoutVideoInput[] + + No +
+ upsert + VideoProcessingTaskUpsertWithWhereUniqueWithoutVideoInput | VideoProcessingTaskUpsertWithWhereUniqueWithoutVideoInput[] + + No +
+ createMany + VideoProcessingTaskCreateManyVideoInputEnvelope + + No +
+ set + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ disconnect + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ delete + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ connect + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ update + VideoProcessingTaskUpdateWithWhereUniqueWithoutVideoInput | VideoProcessingTaskUpdateWithWhereUniqueWithoutVideoInput[] + + No +
+ updateMany + VideoProcessingTaskUpdateManyWithWhereWithoutVideoInput | VideoProcessingTaskUpdateManyWithWhereWithoutVideoInput[] + + No +
+ deleteMany + VideoProcessingTaskScalarWhereInput | VideoProcessingTaskScalarWhereInput[] + + No +
+
+
+
+

VideoProcessingTaskUncheckedUpdateManyWithoutAudioNestedInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + VideoProcessingTaskCreateWithoutAudioInput | VideoProcessingTaskCreateWithoutAudioInput[] | VideoProcessingTaskUncheckedCreateWithoutAudioInput | VideoProcessingTaskUncheckedCreateWithoutAudioInput[] + + No +
+ connectOrCreate + VideoProcessingTaskCreateOrConnectWithoutAudioInput | VideoProcessingTaskCreateOrConnectWithoutAudioInput[] + + No +
+ upsert + VideoProcessingTaskUpsertWithWhereUniqueWithoutAudioInput | VideoProcessingTaskUpsertWithWhereUniqueWithoutAudioInput[] + + No +
+ createMany + VideoProcessingTaskCreateManyAudioInputEnvelope + + No +
+ set + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ disconnect + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ delete + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ connect + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ update + VideoProcessingTaskUpdateWithWhereUniqueWithoutAudioInput | VideoProcessingTaskUpdateWithWhereUniqueWithoutAudioInput[] + + No +
+ updateMany + VideoProcessingTaskUpdateManyWithWhereWithoutAudioInput | VideoProcessingTaskUpdateManyWithWhereWithoutAudioInput[] + + No +
+ deleteMany + VideoProcessingTaskScalarWhereInput | VideoProcessingTaskScalarWhereInput[] + + No +
+
+
+ +
+
+

VideoProcessingTaskUncheckedCreateNestedManyWithoutBatchInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + VideoProcessingTaskCreateWithoutBatchInput | VideoProcessingTaskCreateWithoutBatchInput[] | VideoProcessingTaskUncheckedCreateWithoutBatchInput | VideoProcessingTaskUncheckedCreateWithoutBatchInput[] + + No +
+ connectOrCreate + VideoProcessingTaskCreateOrConnectWithoutBatchInput | VideoProcessingTaskCreateOrConnectWithoutBatchInput[] + + No +
+ createMany + VideoProcessingTaskCreateManyBatchInputEnvelope + + No +
+ connect + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+
+
+
+

IntFieldUpdateOperationsInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ set + Int + + No +
+ increment + Int + + No +
+ decrement + Int + + No +
+ multiply + Int + + No +
+ divide + Int + + No +
+
+
+
+

VideoProcessingTaskUpdateManyWithoutBatchNestedInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + VideoProcessingTaskCreateWithoutBatchInput | VideoProcessingTaskCreateWithoutBatchInput[] | VideoProcessingTaskUncheckedCreateWithoutBatchInput | VideoProcessingTaskUncheckedCreateWithoutBatchInput[] + + No +
+ connectOrCreate + VideoProcessingTaskCreateOrConnectWithoutBatchInput | VideoProcessingTaskCreateOrConnectWithoutBatchInput[] + + No +
+ upsert + VideoProcessingTaskUpsertWithWhereUniqueWithoutBatchInput | VideoProcessingTaskUpsertWithWhereUniqueWithoutBatchInput[] + + No +
+ createMany + VideoProcessingTaskCreateManyBatchInputEnvelope + + No +
+ set + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ disconnect + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ delete + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ connect + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ update + VideoProcessingTaskUpdateWithWhereUniqueWithoutBatchInput | VideoProcessingTaskUpdateWithWhereUniqueWithoutBatchInput[] + + No +
+ updateMany + VideoProcessingTaskUpdateManyWithWhereWithoutBatchInput | VideoProcessingTaskUpdateManyWithWhereWithoutBatchInput[] + + No +
+ deleteMany + VideoProcessingTaskScalarWhereInput | VideoProcessingTaskScalarWhereInput[] + + No +
+
+
+
+

VideoProcessingTaskUncheckedUpdateManyWithoutBatchNestedInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + VideoProcessingTaskCreateWithoutBatchInput | VideoProcessingTaskCreateWithoutBatchInput[] | VideoProcessingTaskUncheckedCreateWithoutBatchInput | VideoProcessingTaskUncheckedCreateWithoutBatchInput[] + + No +
+ connectOrCreate + VideoProcessingTaskCreateOrConnectWithoutBatchInput | VideoProcessingTaskCreateOrConnectWithoutBatchInput[] + + No +
+ upsert + VideoProcessingTaskUpsertWithWhereUniqueWithoutBatchInput | VideoProcessingTaskUpsertWithWhereUniqueWithoutBatchInput[] + + No +
+ createMany + VideoProcessingTaskCreateManyBatchInputEnvelope + + No +
+ set + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ disconnect + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ delete + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ connect + VideoProcessingTaskWhereUniqueInput | VideoProcessingTaskWhereUniqueInput[] + + No +
+ update + VideoProcessingTaskUpdateWithWhereUniqueWithoutBatchInput | VideoProcessingTaskUpdateWithWhereUniqueWithoutBatchInput[] + + No +
+ updateMany + VideoProcessingTaskUpdateManyWithWhereWithoutBatchInput | VideoProcessingTaskUpdateManyWithWhereWithoutBatchInput[] + + No +
+ deleteMany + VideoProcessingTaskScalarWhereInput | VideoProcessingTaskScalarWhereInput[] + + No +
+
+
+
+

VideoProcessingBatchCreateNestedOneWithoutTasksInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + VideoProcessingBatchCreateWithoutTasksInput | VideoProcessingBatchUncheckedCreateWithoutTasksInput + + No +
+ connectOrCreate + VideoProcessingBatchCreateOrConnectWithoutTasksInput + + No +
+ connect + VideoProcessingBatchWhereUniqueInput + + No +
+
+
+
+

MediaFileCreateNestedOneWithoutVideoProcessingTaskVideosInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + MediaFileCreateWithoutVideoProcessingTaskVideosInput | MediaFileUncheckedCreateWithoutVideoProcessingTaskVideosInput + + No +
+ connectOrCreate + MediaFileCreateOrConnectWithoutVideoProcessingTaskVideosInput + + No +
+ connect + MediaFileWhereUniqueInput + + No +
+
+
+
+

MediaFileCreateNestedOneWithoutVideoProcessingTaskAudiosInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + MediaFileCreateWithoutVideoProcessingTaskAudiosInput | MediaFileUncheckedCreateWithoutVideoProcessingTaskAudiosInput + + No +
+ connectOrCreate + MediaFileCreateOrConnectWithoutVideoProcessingTaskAudiosInput + + No +
+ connect + MediaFileWhereUniqueInput + + No +
+
+
+
+

BoolFieldUpdateOperationsInput

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ set + Boolean + + No +
+
+
+
+

VideoProcessingBatchUpdateOneWithoutTasksNestedInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + VideoProcessingBatchCreateWithoutTasksInput | VideoProcessingBatchUncheckedCreateWithoutTasksInput + + No +
+ connectOrCreate + VideoProcessingBatchCreateOrConnectWithoutTasksInput + + No +
+ upsert + VideoProcessingBatchUpsertWithoutTasksInput + + No +
+ disconnect + Boolean | VideoProcessingBatchWhereInput + + No +
+ delete + Boolean | VideoProcessingBatchWhereInput + + No +
+ connect + VideoProcessingBatchWhereUniqueInput + + No +
+ update + VideoProcessingBatchUpdateToOneWithWhereWithoutTasksInput | VideoProcessingBatchUpdateWithoutTasksInput | VideoProcessingBatchUncheckedUpdateWithoutTasksInput + + No +
+
+
+
+

MediaFileUpdateOneWithoutVideoProcessingTaskVideosNestedInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + MediaFileCreateWithoutVideoProcessingTaskVideosInput | MediaFileUncheckedCreateWithoutVideoProcessingTaskVideosInput + + No +
+ connectOrCreate + MediaFileCreateOrConnectWithoutVideoProcessingTaskVideosInput + + No +
+ upsert + MediaFileUpsertWithoutVideoProcessingTaskVideosInput + + No +
+ disconnect + Boolean | MediaFileWhereInput + + No +
+ delete + Boolean | MediaFileWhereInput + + No +
+ connect + MediaFileWhereUniqueInput + + No +
+ update + MediaFileUpdateToOneWithWhereWithoutVideoProcessingTaskVideosInput | MediaFileUpdateWithoutVideoProcessingTaskVideosInput | MediaFileUncheckedUpdateWithoutVideoProcessingTaskVideosInput + + No +
+
+
+
+

MediaFileUpdateOneWithoutVideoProcessingTaskAudiosNestedInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + MediaFileCreateWithoutVideoProcessingTaskAudiosInput | MediaFileUncheckedCreateWithoutVideoProcessingTaskAudiosInput + + No +
+ connectOrCreate + MediaFileCreateOrConnectWithoutVideoProcessingTaskAudiosInput + + No +
+ upsert + MediaFileUpsertWithoutVideoProcessingTaskAudiosInput + + No +
+ disconnect + Boolean | MediaFileWhereInput + + No +
+ delete + Boolean | MediaFileWhereInput + + No +
+ connect + MediaFileWhereUniqueInput + + No +
+ update + MediaFileUpdateToOneWithWhereWithoutVideoProcessingTaskAudiosInput | MediaFileUpdateWithoutVideoProcessingTaskAudiosInput | MediaFileUncheckedUpdateWithoutVideoProcessingTaskAudiosInput + + No +
+
+
+
+

NestedStringFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput + + No +
+ in + String | ListStringFieldRefInput + + No +
+ notIn + String | ListStringFieldRefInput + + No +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ not + String | NestedStringFilter + + No +
+
+
+
+

NestedStringNullableFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput | Null + + Yes +
+ in + String | ListStringFieldRefInput | Null + + Yes +
+ notIn + String | ListStringFieldRefInput | Null + + Yes +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ not + String | NestedStringNullableFilter | Null + + Yes +
+
+
+
+

NestedDateTimeFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + DateTime | DateTimeFieldRefInput + + No +
+ in + DateTime | ListDateTimeFieldRefInput + + No +
+ notIn + DateTime | ListDateTimeFieldRefInput + + No +
+ lt + DateTime | DateTimeFieldRefInput + + No +
+ lte + DateTime | DateTimeFieldRefInput + + No +
+ gt + DateTime | DateTimeFieldRefInput + + No +
+ gte + DateTime | DateTimeFieldRefInput + + No +
+ not + DateTime | NestedDateTimeFilter + + No +
+
+
+
+

NestedIntNullableFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Int | IntFieldRefInput | Null + + Yes +
+ in + Int | ListIntFieldRefInput | Null + + Yes +
+ notIn + Int | ListIntFieldRefInput | Null + + Yes +
+ lt + Int | IntFieldRefInput + + No +
+ lte + Int | IntFieldRefInput + + No +
+ gt + Int | IntFieldRefInput + + No +
+ gte + Int | IntFieldRefInput + + No +
+ not + Int | NestedIntNullableFilter | Null + + Yes +
+
+
+
+

NestedStringWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput + + No +
+ in + String | ListStringFieldRefInput + + No +
+ notIn + String | ListStringFieldRefInput + + No +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ not + String | NestedStringWithAggregatesFilter + + No +
+ _count + NestedIntFilter + + No +
+ _min + NestedStringFilter + + No +
+ _max + NestedStringFilter + + No +
+
+
+
+

NestedIntFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Int | IntFieldRefInput + + No +
+ in + Int | ListIntFieldRefInput + + No +
+ notIn + Int | ListIntFieldRefInput + + No +
+ lt + Int | IntFieldRefInput + + No +
+ lte + Int | IntFieldRefInput + + No +
+ gt + Int | IntFieldRefInput + + No +
+ gte + Int | IntFieldRefInput + + No +
+ not + Int | NestedIntFilter + + No +
+
+
+
+

NestedStringNullableWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput | Null + + Yes +
+ in + String | ListStringFieldRefInput | Null + + Yes +
+ notIn + String | ListStringFieldRefInput | Null + + Yes +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ not + String | NestedStringNullableWithAggregatesFilter | Null + + Yes +
+ _count + NestedIntNullableFilter + + No +
+ _min + NestedStringNullableFilter + + No +
+ _max + NestedStringNullableFilter + + No +
+
+
+
+

NestedDateTimeWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + DateTime | DateTimeFieldRefInput + + No +
+ in + DateTime | ListDateTimeFieldRefInput + + No +
+ notIn + DateTime | ListDateTimeFieldRefInput + + No +
+ lt + DateTime | DateTimeFieldRefInput + + No +
+ lte + DateTime | DateTimeFieldRefInput + + No +
+ gt + DateTime | DateTimeFieldRefInput + + No +
+ gte + DateTime | DateTimeFieldRefInput + + No +
+ not + DateTime | NestedDateTimeWithAggregatesFilter + + No +
+ _count + NestedIntFilter + + No +
+ _min + NestedDateTimeFilter + + No +
+ _max + NestedDateTimeFilter + + No +
+
+
+
+

NestedIntNullableWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Int | IntFieldRefInput | Null + + Yes +
+ in + Int | ListIntFieldRefInput | Null + + Yes +
+ notIn + Int | ListIntFieldRefInput | Null + + Yes +
+ lt + Int | IntFieldRefInput + + No +
+ lte + Int | IntFieldRefInput + + No +
+ gt + Int | IntFieldRefInput + + No +
+ gte + Int | IntFieldRefInput + + No +
+ not + Int | NestedIntNullableWithAggregatesFilter | Null + + Yes +
+ _count + NestedIntNullableFilter + + No +
+ _avg + NestedFloatNullableFilter + + No +
+ _sum + NestedIntNullableFilter + + No +
+ _min + NestedIntNullableFilter + + No +
+ _max + NestedIntNullableFilter + + No +
+
+
+
+

NestedFloatNullableFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Float | FloatFieldRefInput | Null + + Yes +
+ in + Float | ListFloatFieldRefInput | Null + + Yes +
+ notIn + Float | ListFloatFieldRefInput | Null + + Yes +
+ lt + Float | FloatFieldRefInput + + No +
+ lte + Float | FloatFieldRefInput + + No +
+ gt + Float | FloatFieldRefInput + + No +
+ gte + Float | FloatFieldRefInput + + No +
+ not + Float | NestedFloatNullableFilter | Null + + Yes +
+
+
+
+

NestedIntWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Int | IntFieldRefInput + + No +
+ in + Int | ListIntFieldRefInput + + No +
+ notIn + Int | ListIntFieldRefInput + + No +
+ lt + Int | IntFieldRefInput + + No +
+ lte + Int | IntFieldRefInput + + No +
+ gt + Int | IntFieldRefInput + + No +
+ gte + Int | IntFieldRefInput + + No +
+ not + Int | NestedIntWithAggregatesFilter + + No +
+ _count + NestedIntFilter + + No +
+ _avg + NestedFloatFilter + + No +
+ _sum + NestedIntFilter + + No +
+ _min + NestedIntFilter + + No +
+ _max + NestedIntFilter + + No +
+
+
+
+

NestedFloatFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Float | FloatFieldRefInput + + No +
+ in + Float | ListFloatFieldRefInput + + No +
+ notIn + Float | ListFloatFieldRefInput + + No +
+ lt + Float | FloatFieldRefInput + + No +
+ lte + Float | FloatFieldRefInput + + No +
+ gt + Float | FloatFieldRefInput + + No +
+ gte + Float | FloatFieldRefInput + + No +
+ not + Float | NestedFloatFilter + + No +
+
+
+
+

NestedBoolFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Boolean | BooleanFieldRefInput + + No +
+ not + Boolean | NestedBoolFilter + + No +
+
+
+
+

NestedBoolWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Boolean | BooleanFieldRefInput + + No +
+ not + Boolean | NestedBoolWithAggregatesFilter + + No +
+ _count + NestedIntFilter + + No +
+ _min + NestedBoolFilter + + No +
+ _max + NestedBoolFilter + + No +
+
+
+
+

VideoProcessingTaskCreateWithoutVideoInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ viewerUrl + String | Null + + Yes +
+ downloadUrl + String | Null + + Yes +
+ status + String + + No +
+ extractAudio + Boolean + + No +
+ error + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ meetingRecordId + String | Null + + Yes +
+ batch + VideoProcessingBatchCreateNestedOneWithoutTasksInput + + No +
+ audio + MediaFileCreateNestedOneWithoutVideoProcessingTaskAudiosInput + + No +
+
+
+
+

VideoProcessingTaskUncheckedCreateWithoutVideoInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ viewerUrl + String | Null + + Yes +
+ downloadUrl + String | Null + + Yes +
+ status + String + + No +
+ extractAudio + Boolean + + No +
+ error + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ batchId + String | Null + + Yes +
+ meetingRecordId + String | Null + + Yes +
+ audioId + String | Null + + Yes +
+
+
+
+

VideoProcessingTaskCreateOrConnectWithoutVideoInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + VideoProcessingTaskWhereUniqueInput + + No +
+ create + VideoProcessingTaskCreateWithoutVideoInput | VideoProcessingTaskUncheckedCreateWithoutVideoInput + + No +
+
+
+
+

VideoProcessingTaskCreateManyVideoInputEnvelope

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ data + VideoProcessingTaskCreateManyVideoInput | VideoProcessingTaskCreateManyVideoInput[] + + No +
+ skipDuplicates + Boolean + + No +
+
+
+
+

VideoProcessingTaskCreateWithoutAudioInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ viewerUrl + String | Null + + Yes +
+ downloadUrl + String | Null + + Yes +
+ status + String + + No +
+ extractAudio + Boolean + + No +
+ error + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ meetingRecordId + String | Null + + Yes +
+ batch + VideoProcessingBatchCreateNestedOneWithoutTasksInput + + No +
+ video + MediaFileCreateNestedOneWithoutVideoProcessingTaskVideosInput + + No +
+
+
+
+

VideoProcessingTaskUncheckedCreateWithoutAudioInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ viewerUrl + String | Null + + Yes +
+ downloadUrl + String | Null + + Yes +
+ status + String + + No +
+ extractAudio + Boolean + + No +
+ error + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ batchId + String | Null + + Yes +
+ meetingRecordId + String | Null + + Yes +
+ videoId + String | Null + + Yes +
+
+
+
+

VideoProcessingTaskCreateOrConnectWithoutAudioInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + VideoProcessingTaskWhereUniqueInput + + No +
+ create + VideoProcessingTaskCreateWithoutAudioInput | VideoProcessingTaskUncheckedCreateWithoutAudioInput + + No +
+
+
+
+

VideoProcessingTaskCreateManyAudioInputEnvelope

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ data + VideoProcessingTaskCreateManyAudioInput | VideoProcessingTaskCreateManyAudioInput[] + + No +
+ skipDuplicates + Boolean + + No +
+
+
+
+

VideoProcessingTaskUpsertWithWhereUniqueWithoutVideoInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + VideoProcessingTaskWhereUniqueInput + + No +
+ update + VideoProcessingTaskUpdateWithoutVideoInput | VideoProcessingTaskUncheckedUpdateWithoutVideoInput + + No +
+ create + VideoProcessingTaskCreateWithoutVideoInput | VideoProcessingTaskUncheckedCreateWithoutVideoInput + + No +
+
+
+
+

VideoProcessingTaskUpdateWithWhereUniqueWithoutVideoInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + VideoProcessingTaskWhereUniqueInput + + No +
+ data + VideoProcessingTaskUpdateWithoutVideoInput | VideoProcessingTaskUncheckedUpdateWithoutVideoInput + + No +
+
+
+
+

VideoProcessingTaskUpdateManyWithWhereWithoutVideoInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + VideoProcessingTaskScalarWhereInput + + No +
+ data + VideoProcessingTaskUpdateManyMutationInput | VideoProcessingTaskUncheckedUpdateManyWithoutVideoInput + + No +
+
+
+
+

VideoProcessingTaskScalarWhereInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ AND + VideoProcessingTaskScalarWhereInput | VideoProcessingTaskScalarWhereInput[] + + No +
+ OR + VideoProcessingTaskScalarWhereInput[] + + No +
+ NOT + VideoProcessingTaskScalarWhereInput | VideoProcessingTaskScalarWhereInput[] + + No +
+ id + StringFilter | String + + No +
+ viewerUrl + StringNullableFilter | String | Null + + Yes +
+ downloadUrl + StringNullableFilter | String | Null + + Yes +
+ status + StringFilter | String + + No +
+ extractAudio + BoolFilter | Boolean + + No +
+ error + StringNullableFilter | String | Null + + Yes +
+ createdAt + DateTimeFilter | DateTime + + No +
+ updatedAt + DateTimeFilter | DateTime + + No +
+ batchId + StringNullableFilter | String | Null + + Yes +
+ meetingRecordId + StringNullableFilter | String | Null + + Yes +
+ videoId + StringNullableFilter | String | Null + + Yes +
+ audioId + StringNullableFilter | String | Null + + Yes +
+
+
+
+

VideoProcessingTaskUpsertWithWhereUniqueWithoutAudioInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + VideoProcessingTaskWhereUniqueInput + + No +
+ update + VideoProcessingTaskUpdateWithoutAudioInput | VideoProcessingTaskUncheckedUpdateWithoutAudioInput + + No +
+ create + VideoProcessingTaskCreateWithoutAudioInput | VideoProcessingTaskUncheckedCreateWithoutAudioInput + + No +
+
+
+
+

VideoProcessingTaskUpdateWithWhereUniqueWithoutAudioInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + VideoProcessingTaskWhereUniqueInput + + No +
+ data + VideoProcessingTaskUpdateWithoutAudioInput | VideoProcessingTaskUncheckedUpdateWithoutAudioInput + + No +
+
+
+
+

VideoProcessingTaskUpdateManyWithWhereWithoutAudioInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + VideoProcessingTaskScalarWhereInput + + No +
+ data + VideoProcessingTaskUpdateManyMutationInput | VideoProcessingTaskUncheckedUpdateManyWithoutAudioInput + + No +
+
+
+
+

VideoProcessingTaskCreateWithoutBatchInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ viewerUrl + String | Null + + Yes +
+ downloadUrl + String | Null + + Yes +
+ status + String + + No +
+ extractAudio + Boolean + + No +
+ error + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ meetingRecordId + String | Null + + Yes +
+ video + MediaFileCreateNestedOneWithoutVideoProcessingTaskVideosInput + + No +
+ audio + MediaFileCreateNestedOneWithoutVideoProcessingTaskAudiosInput + + No +
+
+
+
+

VideoProcessingTaskUncheckedCreateWithoutBatchInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ viewerUrl + String | Null + + Yes +
+ downloadUrl + String | Null + + Yes +
+ status + String + + No +
+ extractAudio + Boolean + + No +
+ error + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ meetingRecordId + String | Null + + Yes +
+ videoId + String | Null + + Yes +
+ audioId + String | Null + + Yes +
+
+
+
+

VideoProcessingTaskCreateOrConnectWithoutBatchInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + VideoProcessingTaskWhereUniqueInput + + No +
+ create + VideoProcessingTaskCreateWithoutBatchInput | VideoProcessingTaskUncheckedCreateWithoutBatchInput + + No +
+
+
+
+

VideoProcessingTaskCreateManyBatchInputEnvelope

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ data + VideoProcessingTaskCreateManyBatchInput | VideoProcessingTaskCreateManyBatchInput[] + + No +
+ skipDuplicates + Boolean + + No +
+
+
+
+

VideoProcessingTaskUpsertWithWhereUniqueWithoutBatchInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + VideoProcessingTaskWhereUniqueInput + + No +
+ update + VideoProcessingTaskUpdateWithoutBatchInput | VideoProcessingTaskUncheckedUpdateWithoutBatchInput + + No +
+ create + VideoProcessingTaskCreateWithoutBatchInput | VideoProcessingTaskUncheckedCreateWithoutBatchInput + + No +
+
+
+
+

VideoProcessingTaskUpdateWithWhereUniqueWithoutBatchInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + VideoProcessingTaskWhereUniqueInput + + No +
+ data + VideoProcessingTaskUpdateWithoutBatchInput | VideoProcessingTaskUncheckedUpdateWithoutBatchInput + + No +
+
+
+
+

VideoProcessingTaskUpdateManyWithWhereWithoutBatchInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + VideoProcessingTaskScalarWhereInput + + No +
+ data + VideoProcessingTaskUpdateManyMutationInput | VideoProcessingTaskUncheckedUpdateManyWithoutBatchInput + + No +
+
+
+
+

VideoProcessingBatchCreateWithoutTasksInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ status + String + + No +
+ totalTasks + Int + + No +
+ completedTasks + Int + + No +
+ failedTasks + Int + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+
+
+
+

VideoProcessingBatchUncheckedCreateWithoutTasksInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ status + String + + No +
+ totalTasks + Int + + No +
+ completedTasks + Int + + No +
+ failedTasks + Int + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+
+
+
+

VideoProcessingBatchCreateOrConnectWithoutTasksInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + VideoProcessingBatchWhereUniqueInput + + No +
+ create + VideoProcessingBatchCreateWithoutTasksInput | VideoProcessingBatchUncheckedCreateWithoutTasksInput + + No +
+
+
+
+

MediaFileCreateWithoutVideoProcessingTaskVideosInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ bucket + String + + No +
+ key + String + + No +
+ mimetype + String + + No +
+ url + String | Null + + Yes +
+ srcUrl + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ meetingRecordId + String | Null + + Yes +
+ title + String | Null + + Yes +
+ description + String | Null + + Yes +
+ fileSize + Int | Null + + Yes +
+ videoProcessingTaskAudios + VideoProcessingTaskCreateNestedManyWithoutAudioInput + + No +
+
+
+
+

MediaFileUncheckedCreateWithoutVideoProcessingTaskVideosInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ bucket + String + + No +
+ key + String + + No +
+ mimetype + String + + No +
+ url + String | Null + + Yes +
+ srcUrl + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ meetingRecordId + String | Null + + Yes +
+ title + String | Null + + Yes +
+ description + String | Null + + Yes +
+ fileSize + Int | Null + + Yes +
+ videoProcessingTaskAudios + VideoProcessingTaskUncheckedCreateNestedManyWithoutAudioInput + + No +
+
+
+
+

MediaFileCreateOrConnectWithoutVideoProcessingTaskVideosInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + MediaFileWhereUniqueInput + + No +
+ create + MediaFileCreateWithoutVideoProcessingTaskVideosInput | MediaFileUncheckedCreateWithoutVideoProcessingTaskVideosInput + + No +
+
+
+
+

MediaFileCreateWithoutVideoProcessingTaskAudiosInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ bucket + String + + No +
+ key + String + + No +
+ mimetype + String + + No +
+ url + String | Null + + Yes +
+ srcUrl + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ meetingRecordId + String | Null + + Yes +
+ title + String | Null + + Yes +
+ description + String | Null + + Yes +
+ fileSize + Int | Null + + Yes +
+ videoProcessingTaskVideos + VideoProcessingTaskCreateNestedManyWithoutVideoInput + + No +
+
+
+
+

MediaFileUncheckedCreateWithoutVideoProcessingTaskAudiosInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ bucket + String + + No +
+ key + String + + No +
+ mimetype + String + + No +
+ url + String | Null + + Yes +
+ srcUrl + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ meetingRecordId + String | Null + + Yes +
+ title + String | Null + + Yes +
+ description + String | Null + + Yes +
+ fileSize + Int | Null + + Yes +
+ videoProcessingTaskVideos + VideoProcessingTaskUncheckedCreateNestedManyWithoutVideoInput + + No +
+
+
+
+

MediaFileCreateOrConnectWithoutVideoProcessingTaskAudiosInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + MediaFileWhereUniqueInput + + No +
+ create + MediaFileCreateWithoutVideoProcessingTaskAudiosInput | MediaFileUncheckedCreateWithoutVideoProcessingTaskAudiosInput + + No +
+
+
+
+

VideoProcessingBatchUpsertWithoutTasksInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ update + VideoProcessingBatchUpdateWithoutTasksInput | VideoProcessingBatchUncheckedUpdateWithoutTasksInput + + No +
+ create + VideoProcessingBatchCreateWithoutTasksInput | VideoProcessingBatchUncheckedCreateWithoutTasksInput + + No +
+ where + VideoProcessingBatchWhereInput + + No +
+
+
+
+

VideoProcessingBatchUpdateToOneWithWhereWithoutTasksInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + VideoProcessingBatchWhereInput + + No +
+ data + VideoProcessingBatchUpdateWithoutTasksInput | VideoProcessingBatchUncheckedUpdateWithoutTasksInput + + No +
+
+
+
+

VideoProcessingBatchUpdateWithoutTasksInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ totalTasks + Int | IntFieldUpdateOperationsInput + + No +
+ completedTasks + Int | IntFieldUpdateOperationsInput + + No +
+ failedTasks + Int | IntFieldUpdateOperationsInput + + No +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+
+
+
+

VideoProcessingBatchUncheckedUpdateWithoutTasksInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ totalTasks + Int | IntFieldUpdateOperationsInput + + No +
+ completedTasks + Int | IntFieldUpdateOperationsInput + + No +
+ failedTasks + Int | IntFieldUpdateOperationsInput + + No +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+
+
+
+

MediaFileUpsertWithoutVideoProcessingTaskVideosInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ update + MediaFileUpdateWithoutVideoProcessingTaskVideosInput | MediaFileUncheckedUpdateWithoutVideoProcessingTaskVideosInput + + No +
+ create + MediaFileCreateWithoutVideoProcessingTaskVideosInput | MediaFileUncheckedCreateWithoutVideoProcessingTaskVideosInput + + No +
+ where + MediaFileWhereInput + + No +
+
+
+
+

MediaFileUpdateToOneWithWhereWithoutVideoProcessingTaskVideosInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + MediaFileWhereInput + + No +
+ data + MediaFileUpdateWithoutVideoProcessingTaskVideosInput | MediaFileUncheckedUpdateWithoutVideoProcessingTaskVideosInput + + No +
+
+
+
+

MediaFileUpdateWithoutVideoProcessingTaskVideosInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ bucket + String | StringFieldUpdateOperationsInput + + No +
+ key + String | StringFieldUpdateOperationsInput + + No +
+ mimetype + String | StringFieldUpdateOperationsInput + + No +
+ url + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ srcUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ title + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ description + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ fileSize + Int | NullableIntFieldUpdateOperationsInput | Null + + Yes +
+ videoProcessingTaskAudios + VideoProcessingTaskUpdateManyWithoutAudioNestedInput + + No +
+
+
+
+

MediaFileUncheckedUpdateWithoutVideoProcessingTaskVideosInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ bucket + String | StringFieldUpdateOperationsInput + + No +
+ key + String | StringFieldUpdateOperationsInput + + No +
+ mimetype + String | StringFieldUpdateOperationsInput + + No +
+ url + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ srcUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ title + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ description + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ fileSize + Int | NullableIntFieldUpdateOperationsInput | Null + + Yes +
+ videoProcessingTaskAudios + VideoProcessingTaskUncheckedUpdateManyWithoutAudioNestedInput + + No +
+
+
+
+

MediaFileUpsertWithoutVideoProcessingTaskAudiosInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ update + MediaFileUpdateWithoutVideoProcessingTaskAudiosInput | MediaFileUncheckedUpdateWithoutVideoProcessingTaskAudiosInput + + No +
+ create + MediaFileCreateWithoutVideoProcessingTaskAudiosInput | MediaFileUncheckedCreateWithoutVideoProcessingTaskAudiosInput + + No +
+ where + MediaFileWhereInput + + No +
+
+
+
+

MediaFileUpdateToOneWithWhereWithoutVideoProcessingTaskAudiosInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + MediaFileWhereInput + + No +
+ data + MediaFileUpdateWithoutVideoProcessingTaskAudiosInput | MediaFileUncheckedUpdateWithoutVideoProcessingTaskAudiosInput + + No +
+
+
+
+

MediaFileUpdateWithoutVideoProcessingTaskAudiosInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ bucket + String | StringFieldUpdateOperationsInput + + No +
+ key + String | StringFieldUpdateOperationsInput + + No +
+ mimetype + String | StringFieldUpdateOperationsInput + + No +
+ url + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ srcUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ title + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ description + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ fileSize + Int | NullableIntFieldUpdateOperationsInput | Null + + Yes +
+ videoProcessingTaskVideos + VideoProcessingTaskUpdateManyWithoutVideoNestedInput + + No +
+
+
+
+

MediaFileUncheckedUpdateWithoutVideoProcessingTaskAudiosInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ bucket + String | StringFieldUpdateOperationsInput + + No +
+ key + String | StringFieldUpdateOperationsInput + + No +
+ mimetype + String | StringFieldUpdateOperationsInput + + No +
+ url + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ srcUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ title + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ description + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ fileSize + Int | NullableIntFieldUpdateOperationsInput | Null + + Yes +
+ videoProcessingTaskVideos + VideoProcessingTaskUncheckedUpdateManyWithoutVideoNestedInput + + No +
+
+
+
+

VideoProcessingTaskCreateManyVideoInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ viewerUrl + String | Null + + Yes +
+ downloadUrl + String | Null + + Yes +
+ status + String + + No +
+ extractAudio + Boolean + + No +
+ error + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ batchId + String | Null + + Yes +
+ meetingRecordId + String | Null + + Yes +
+ audioId + String | Null + + Yes +
+
+
+
+

VideoProcessingTaskCreateManyAudioInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ viewerUrl + String | Null + + Yes +
+ downloadUrl + String | Null + + Yes +
+ status + String + + No +
+ extractAudio + Boolean + + No +
+ error + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ batchId + String | Null + + Yes +
+ meetingRecordId + String | Null + + Yes +
+ videoId + String | Null + + Yes +
+
+
+
+

VideoProcessingTaskUpdateWithoutVideoInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ viewerUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ downloadUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ extractAudio + Boolean | BoolFieldUpdateOperationsInput + + No +
+ error + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ batch + VideoProcessingBatchUpdateOneWithoutTasksNestedInput + + No +
+ audio + MediaFileUpdateOneWithoutVideoProcessingTaskAudiosNestedInput + + No +
+
+
+
+

VideoProcessingTaskUncheckedUpdateWithoutVideoInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ viewerUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ downloadUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ extractAudio + Boolean | BoolFieldUpdateOperationsInput + + No +
+ error + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ batchId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ audioId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

VideoProcessingTaskUncheckedUpdateManyWithoutVideoInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ viewerUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ downloadUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ extractAudio + Boolean | BoolFieldUpdateOperationsInput + + No +
+ error + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ batchId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ audioId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

VideoProcessingTaskUpdateWithoutAudioInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ viewerUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ downloadUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ extractAudio + Boolean | BoolFieldUpdateOperationsInput + + No +
+ error + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ batch + VideoProcessingBatchUpdateOneWithoutTasksNestedInput + + No +
+ video + MediaFileUpdateOneWithoutVideoProcessingTaskVideosNestedInput + + No +
+
+
+
+

VideoProcessingTaskUncheckedUpdateWithoutAudioInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ viewerUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ downloadUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ extractAudio + Boolean | BoolFieldUpdateOperationsInput + + No +
+ error + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ batchId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ videoId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

VideoProcessingTaskUncheckedUpdateManyWithoutAudioInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ viewerUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ downloadUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ extractAudio + Boolean | BoolFieldUpdateOperationsInput + + No +
+ error + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ batchId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ videoId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

VideoProcessingTaskCreateManyBatchInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ viewerUrl + String | Null + + Yes +
+ downloadUrl + String | Null + + Yes +
+ status + String + + No +
+ extractAudio + Boolean + + No +
+ error + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ meetingRecordId + String | Null + + Yes +
+ videoId + String | Null + + Yes +
+ audioId + String | Null + + Yes +
+
+
+
+

VideoProcessingTaskUpdateWithoutBatchInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ viewerUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ downloadUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ extractAudio + Boolean | BoolFieldUpdateOperationsInput + + No +
+ error + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ video + MediaFileUpdateOneWithoutVideoProcessingTaskVideosNestedInput + + No +
+ audio + MediaFileUpdateOneWithoutVideoProcessingTaskAudiosNestedInput + + No +
+
+
+
+

VideoProcessingTaskUncheckedUpdateWithoutBatchInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ viewerUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ downloadUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ extractAudio + Boolean | BoolFieldUpdateOperationsInput + + No +
+ error + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ videoId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ audioId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

VideoProcessingTaskUncheckedUpdateManyWithoutBatchInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ viewerUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ downloadUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ extractAudio + Boolean | BoolFieldUpdateOperationsInput + + No +
+ error + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ videoId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ audioId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+
+ +
+
+
+

Output Types

+
+ +
+

MediaFile

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ bucket + String + + Yes +
+ key + String + + Yes +
+ mimetype + String + + Yes +
+ url + String + + No +
+ srcUrl + String + + No +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ meetingRecordId + String + + No +
+ title + String + + No +
+ description + String + + No +
+ fileSize + Int + + No +
+ videoProcessingTaskVideos + VideoProcessingTask[] + + No +
+ videoProcessingTaskAudios + VideoProcessingTask[] + + No +
+ _count + MediaFileCountOutputType + + Yes +
+
+
+
+

VideoProcessingBatch

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ status + String + + Yes +
+ totalTasks + Int + + Yes +
+ completedTasks + Int + + Yes +
+ failedTasks + Int + + Yes +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ tasks + VideoProcessingTask[] + + No +
+ _count + VideoProcessingBatchCountOutputType + + Yes +
+
+
+
+

VideoProcessingTask

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ viewerUrl + String + + No +
+ downloadUrl + String + + No +
+ status + String + + Yes +
+ extractAudio + Boolean + + Yes +
+ error + String + + No +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ batchId + String + + No +
+ meetingRecordId + String + + No +
+ videoId + String + + No +
+ audioId + String + + No +
+ batch + VideoProcessingBatch + + No +
+ video + MediaFile + + No +
+ audio + MediaFile + + No +
+
+
+
+

CreateManyMediaFileAndReturnOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ bucket + String + + Yes +
+ key + String + + Yes +
+ mimetype + String + + Yes +
+ url + String + + No +
+ srcUrl + String + + No +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ meetingRecordId + String + + No +
+ title + String + + No +
+ description + String + + No +
+ fileSize + Int + + No +
+
+
+
+

UpdateManyMediaFileAndReturnOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ bucket + String + + Yes +
+ key + String + + Yes +
+ mimetype + String + + Yes +
+ url + String + + No +
+ srcUrl + String + + No +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ meetingRecordId + String + + No +
+ title + String + + No +
+ description + String + + No +
+ fileSize + Int + + No +
+
+
+
+

CreateManyVideoProcessingBatchAndReturnOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ status + String + + Yes +
+ totalTasks + Int + + Yes +
+ completedTasks + Int + + Yes +
+ failedTasks + Int + + Yes +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+
+
+
+

UpdateManyVideoProcessingBatchAndReturnOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ status + String + + Yes +
+ totalTasks + Int + + Yes +
+ completedTasks + Int + + Yes +
+ failedTasks + Int + + Yes +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+
+
+
+

CreateManyVideoProcessingTaskAndReturnOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ viewerUrl + String + + No +
+ downloadUrl + String + + No +
+ status + String + + Yes +
+ extractAudio + Boolean + + Yes +
+ error + String + + No +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ batchId + String + + No +
+ meetingRecordId + String + + No +
+ videoId + String + + No +
+ audioId + String + + No +
+ batch + VideoProcessingBatch + + No +
+ video + MediaFile + + No +
+ audio + MediaFile + + No +
+
+
+
+

UpdateManyVideoProcessingTaskAndReturnOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ viewerUrl + String + + No +
+ downloadUrl + String + + No +
+ status + String + + Yes +
+ extractAudio + Boolean + + Yes +
+ error + String + + No +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ batchId + String + + No +
+ meetingRecordId + String + + No +
+ videoId + String + + No +
+ audioId + String + + No +
+ batch + VideoProcessingBatch + + No +
+ video + MediaFile + + No +
+ audio + MediaFile + + No +
+
+
+
+

AggregateMediaFile

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ _count + MediaFileCountAggregateOutputType + + No +
+ _avg + MediaFileAvgAggregateOutputType + + No +
+ _sum + MediaFileSumAggregateOutputType + + No +
+ _min + MediaFileMinAggregateOutputType + + No +
+ _max + MediaFileMaxAggregateOutputType + + No +
+
+
+
+

MediaFileGroupByOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ bucket + String + + Yes +
+ key + String + + Yes +
+ mimetype + String + + Yes +
+ url + String + + No +
+ srcUrl + String + + No +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ meetingRecordId + String + + No +
+ title + String + + No +
+ description + String + + No +
+ fileSize + Int + + No +
+ _count + MediaFileCountAggregateOutputType + + No +
+ _avg + MediaFileAvgAggregateOutputType + + No +
+ _sum + MediaFileSumAggregateOutputType + + No +
+ _min + MediaFileMinAggregateOutputType + + No +
+ _max + MediaFileMaxAggregateOutputType + + No +
+
+
+
+

AggregateVideoProcessingBatch

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ _count + VideoProcessingBatchCountAggregateOutputType + + No +
+ _avg + VideoProcessingBatchAvgAggregateOutputType + + No +
+ _sum + VideoProcessingBatchSumAggregateOutputType + + No +
+ _min + VideoProcessingBatchMinAggregateOutputType + + No +
+ _max + VideoProcessingBatchMaxAggregateOutputType + + No +
+
+
+
+

VideoProcessingBatchGroupByOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ status + String + + Yes +
+ totalTasks + Int + + Yes +
+ completedTasks + Int + + Yes +
+ failedTasks + Int + + Yes +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ _count + VideoProcessingBatchCountAggregateOutputType + + No +
+ _avg + VideoProcessingBatchAvgAggregateOutputType + + No +
+ _sum + VideoProcessingBatchSumAggregateOutputType + + No +
+ _min + VideoProcessingBatchMinAggregateOutputType + + No +
+ _max + VideoProcessingBatchMaxAggregateOutputType + + No +
+
+
+
+

AggregateVideoProcessingTask

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ _count + VideoProcessingTaskCountAggregateOutputType + + No +
+ _min + VideoProcessingTaskMinAggregateOutputType + + No +
+ _max + VideoProcessingTaskMaxAggregateOutputType + + No +
+
+
+
+

VideoProcessingTaskGroupByOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ viewerUrl + String + + No +
+ downloadUrl + String + + No +
+ status + String + + Yes +
+ extractAudio + Boolean + + Yes +
+ error + String + + No +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ batchId + String + + No +
+ meetingRecordId + String + + No +
+ videoId + String + + No +
+ audioId + String + + No +
+ _count + VideoProcessingTaskCountAggregateOutputType + + No +
+ _min + VideoProcessingTaskMinAggregateOutputType + + No +
+ _max + VideoProcessingTaskMaxAggregateOutputType + + No +
+
+
+
+

AffectedRowsOutput

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ count + Int + + Yes +
+
+
+
+

MediaFileCountOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ videoProcessingTaskVideos + Int + + Yes +
+ videoProcessingTaskAudios + Int + + Yes +
+
+
+
+

MediaFileCountAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + Int + + Yes +
+ bucket + Int + + Yes +
+ key + Int + + Yes +
+ mimetype + Int + + Yes +
+ url + Int + + Yes +
+ srcUrl + Int + + Yes +
+ createdAt + Int + + Yes +
+ updatedAt + Int + + Yes +
+ meetingRecordId + Int + + Yes +
+ title + Int + + Yes +
+ description + Int + + Yes +
+ fileSize + Int + + Yes +
+ _all + Int + + Yes +
+
+
+
+

MediaFileAvgAggregateOutputType

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ fileSize + Float + + No +
+
+
+
+

MediaFileSumAggregateOutputType

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ fileSize + Int + + No +
+
+
+
+

MediaFileMinAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ bucket + String + + No +
+ key + String + + No +
+ mimetype + String + + No +
+ url + String + + No +
+ srcUrl + String + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ meetingRecordId + String + + No +
+ title + String + + No +
+ description + String + + No +
+ fileSize + Int + + No +
+
+
+
+

MediaFileMaxAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ bucket + String + + No +
+ key + String + + No +
+ mimetype + String + + No +
+ url + String + + No +
+ srcUrl + String + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ meetingRecordId + String + + No +
+ title + String + + No +
+ description + String + + No +
+ fileSize + Int + + No +
+
+
+
+

VideoProcessingBatchCountOutputType

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ tasks + Int + + Yes +
+
+
+
+

VideoProcessingBatchCountAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + Int + + Yes +
+ status + Int + + Yes +
+ totalTasks + Int + + Yes +
+ completedTasks + Int + + Yes +
+ failedTasks + Int + + Yes +
+ createdAt + Int + + Yes +
+ updatedAt + Int + + Yes +
+ _all + Int + + Yes +
+
+
+
+

VideoProcessingBatchAvgAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ totalTasks + Float + + No +
+ completedTasks + Float + + No +
+ failedTasks + Float + + No +
+
+
+
+

VideoProcessingBatchSumAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ totalTasks + Int + + No +
+ completedTasks + Int + + No +
+ failedTasks + Int + + No +
+
+
+
+

VideoProcessingBatchMinAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ status + String + + No +
+ totalTasks + Int + + No +
+ completedTasks + Int + + No +
+ failedTasks + Int + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+
+
+
+

VideoProcessingBatchMaxAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ status + String + + No +
+ totalTasks + Int + + No +
+ completedTasks + Int + + No +
+ failedTasks + Int + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+
+
+
+

VideoProcessingTaskCountAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + Int + + Yes +
+ viewerUrl + Int + + Yes +
+ downloadUrl + Int + + Yes +
+ status + Int + + Yes +
+ extractAudio + Int + + Yes +
+ error + Int + + Yes +
+ createdAt + Int + + Yes +
+ updatedAt + Int + + Yes +
+ batchId + Int + + Yes +
+ meetingRecordId + Int + + Yes +
+ videoId + Int + + Yes +
+ audioId + Int + + Yes +
+ _all + Int + + Yes +
+
+
+
+

VideoProcessingTaskMinAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ viewerUrl + String + + No +
+ downloadUrl + String + + No +
+ status + String + + No +
+ extractAudio + Boolean + + No +
+ error + String + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ batchId + String + + No +
+ meetingRecordId + String + + No +
+ videoId + String + + No +
+ audioId + String + + No +
+
+
+
+

VideoProcessingTaskMaxAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ viewerUrl + String + + No +
+ downloadUrl + String + + No +
+ status + String + + No +
+ extractAudio + Boolean + + No +
+ error + String + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ batchId + String + + No +
+ meetingRecordId + String + + No +
+ videoId + String + + No +
+ audioId + String + + No +
+
+ +
+
+
+
+ +
+
+
+
+ + diff --git a/services/media/db/docs/styles/main.css b/services/media/db/docs/styles/main.css new file mode 100644 index 0000000..78f97c8 --- /dev/null +++ b/services/media/db/docs/styles/main.css @@ -0,0 +1 @@ +/*! tailwindcss v3.2.6 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}html{-webkit-text-size-adjust:100%;font-feature-settings:normal;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]{display:none}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.sticky{position:sticky}.top-0{top:0}.my-16{margin-bottom:4rem;margin-top:4rem}.my-4{margin-bottom:1rem;margin-top:1rem}.my-8{margin-bottom:2rem;margin-top:2rem}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-4{margin-left:1rem}.mr-4{margin-right:1rem}.mt-1{margin-top:.25rem}.mt-12{margin-top:3rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.flex{display:flex}.table{display:table}.h-screen{height:100vh}.min-h-screen{min-height:100vh}.w-1\/5{width:20%}.w-full{width:100%}.flex-shrink-0{flex-shrink:0}.table-auto{table-layout:auto}.overflow-auto{overflow:auto}.overflow-x-hidden{overflow-x:hidden}.border{border-width:1px}.border-l-2{border-left-width:2px}.border-gray-400{--tw-border-opacity:1;border-color:rgb(156 163 175/var(--tw-border-opacity))}.bg-gray-200{--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.p-4{padding:1rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.pl-3{padding-left:.75rem}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-lg{font-size:1.125rem}.text-lg,.text-xl{line-height:1.75rem}.text-xl{font-size:1.25rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity))}.text-gray-800{--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity))}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}body{--code-inner-color:#718096;--code-token1-color:#d5408c;--code-token2-color:#805ad5;--code-token3-color:#319795;--code-token4-color:#dd6b21;--code-token5-color:#690;--code-token6-color:#9a6e3a;--code-token7-color:#e90;--code-linenum-color:#cbd5e0;--code-added-color:#47bb78;--code-added-bg-color:#d9f4e6;--code-deleted-color:#e53e3e;--code-deleted-bg-color:#f5e4e7;--code-highlight-color:#a0aec0;--code-highlight-bg-color:#e2e8f0;--code-result-bg-color:#e7edf3;--main-font-color:#1a202c;--border-color:#e2e8f0;--code-bgd-color:#f6f8fa}code[class*=language-],pre[class*=language-],pre[class*=language-] code{word-wrap:normal;border-radius:8px;color:var(--main-font-color)!important;display:block;font-family:Roboto Mono,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:14px;font-variant:no-common-ligatures no-discretionary-ligatures no-historical-ligatures no-contextual;grid-template-rows:max-content;-webkit-hyphens:none;hyphens:none;line-height:1.5;overflow:auto;-moz-tab-size:4;-o-tab-size:4;tab-size:4;text-align:left;white-space:pre;width:100%;word-break:normal;word-spacing:normal}pre[class*=language-]{border-radius:1em;margin:0;overflow:auto;padding:1em}:not(pre)>code[class*=language-],pre[class*=language-]{background:var(--code-bgd-color)!important}:not(pre)>code[class*=language-]{border-radius:.3em;padding:.1em;white-space:normal}.inline-code,code.inline-code{font-feature-settings:"clig" 0,"calt" 0;background:var(--code-inline-bgd-color);border-radius:5px;color:var(--main-font-color);display:inline;font-family:Roboto Mono;font-size:14px;font-style:normal;font-variant:no-common-ligatures no-discretionary-ligatures no-historical-ligatures no-contextual;font-weight:500;line-height:24px;padding:.05em .3em .2em;vertical-align:baseline}.inline-code{background-color:var(--border-color)}.top-section h1 inlinecode{font-size:2rem}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:var(--code-inner-color)!important;font-style:normal!important}.token.namespace{opacity:.7}.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag,.token.type-args{color:var(--code-token4-color)!important}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:var(--code-token5-color)!important}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:var(--code-token6-color)!important}.token.atrule,.token.attr-value,.token.keyword{color:var(--code-token1-color)!important}.token.boolean,.token.class-name,.token.function,.token[class*=class-name]{color:var(--code-token2-color)!important}.token.important,.token.regex,.token.variable{color:var(--code-token7-color)!important}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.annotation{color:var(--code-token3-color)!important} \ No newline at end of file diff --git a/media/data/index.ts b/services/media/db/index.ts similarity index 99% rename from media/data/index.ts rename to services/media/db/index.ts index 9fc7f61..9819f7d 100644 --- a/media/data/index.ts +++ b/services/media/db/index.ts @@ -1,6 +1,7 @@ -import { SQLDatabase } from "encore.dev/storage/sqldb"; import { PrismaClient } from "@prisma/client/media/index.js"; + import { Bucket } from "encore.dev/storage/objects"; +import { SQLDatabase } from "encore.dev/storage/sqldb"; // Define the database connection const psql = new SQLDatabase("media", { diff --git a/media/data/migrations/20250312062309_init/migration.sql b/services/media/db/migrations/20250312062309_init/migration.sql similarity index 100% rename from media/data/migrations/20250312062309_init/migration.sql rename to services/media/db/migrations/20250312062309_init/migration.sql diff --git a/archives/data/migrations/migration_lock.toml b/services/media/db/migrations/migration_lock.toml similarity index 100% rename from archives/data/migrations/migration_lock.toml rename to services/media/db/migrations/migration_lock.toml diff --git a/services/media/db/models/canonical.ts b/services/media/db/models/canonical.ts new file mode 100644 index 0000000..3f01ed0 --- /dev/null +++ b/services/media/db/models/canonical.ts @@ -0,0 +1,47 @@ +// DO NOT EDIT — Auto-generated file; see https://github.com/mogzol/prisma-generator-typescript-interfaces + +export type MediaFileModel = { + id: string; + bucket: string; + key: string; + mimetype: string; + url: string | null; + srcUrl: string | null; + createdAt: Date; + updatedAt: Date; + meetingRecordId: string | null; + title: string | null; + description: string | null; + fileSize: number | null; + videoProcessingTaskVideos?: VideoProcessingTaskModel[]; + videoProcessingTaskAudios?: VideoProcessingTaskModel[]; +}; + +export type VideoProcessingBatchModel = { + id: string; + status: string; + totalTasks: number; + completedTasks: number; + failedTasks: number; + createdAt: Date; + updatedAt: Date; + tasks?: VideoProcessingTaskModel[]; +}; + +export type VideoProcessingTaskModel = { + id: string; + viewerUrl: string | null; + downloadUrl: string | null; + status: string; + extractAudio: boolean; + error: string | null; + createdAt: Date; + updatedAt: Date; + batchId: string | null; + meetingRecordId: string | null; + videoId: string | null; + audioId: string | null; + batch?: VideoProcessingBatchModel | null; + video?: MediaFileModel | null; + audio?: MediaFileModel | null; +}; diff --git a/services/media/db/models/db.ts b/services/media/db/models/db.ts new file mode 100644 index 0000000..3f01ed0 --- /dev/null +++ b/services/media/db/models/db.ts @@ -0,0 +1,47 @@ +// DO NOT EDIT — Auto-generated file; see https://github.com/mogzol/prisma-generator-typescript-interfaces + +export type MediaFileModel = { + id: string; + bucket: string; + key: string; + mimetype: string; + url: string | null; + srcUrl: string | null; + createdAt: Date; + updatedAt: Date; + meetingRecordId: string | null; + title: string | null; + description: string | null; + fileSize: number | null; + videoProcessingTaskVideos?: VideoProcessingTaskModel[]; + videoProcessingTaskAudios?: VideoProcessingTaskModel[]; +}; + +export type VideoProcessingBatchModel = { + id: string; + status: string; + totalTasks: number; + completedTasks: number; + failedTasks: number; + createdAt: Date; + updatedAt: Date; + tasks?: VideoProcessingTaskModel[]; +}; + +export type VideoProcessingTaskModel = { + id: string; + viewerUrl: string | null; + downloadUrl: string | null; + status: string; + extractAudio: boolean; + error: string | null; + createdAt: Date; + updatedAt: Date; + batchId: string | null; + meetingRecordId: string | null; + videoId: string | null; + audioId: string | null; + batch?: VideoProcessingBatchModel | null; + video?: MediaFileModel | null; + audio?: MediaFileModel | null; +}; diff --git a/services/media/db/models/dto.ts b/services/media/db/models/dto.ts new file mode 100644 index 0000000..0ca9e11 --- /dev/null +++ b/services/media/db/models/dto.ts @@ -0,0 +1,41 @@ +// DO NOT EDIT — Auto-generated file; see https://github.com/mogzol/prisma-generator-typescript-interfaces + +export type MediaFileDto = { + id: string; + bucket: string; + key: string; + mimetype: string; + url: string | null; + srcUrl: string | null; + createdAt: string; + updatedAt: string; + meetingRecordId: string | null; + title: string | null; + description: string | null; + fileSize: number | null; +}; + +export type VideoProcessingBatchDto = { + id: string; + status: string; + totalTasks: number; + completedTasks: number; + failedTasks: number; + createdAt: string; + updatedAt: string; +}; + +export type VideoProcessingTaskDto = { + id: string; + viewerUrl: string | null; + downloadUrl: string | null; + status: string; + extractAudio: boolean; + error: string | null; + createdAt: string; + updatedAt: string; + batchId: string | null; + meetingRecordId: string | null; + videoId: string | null; + audioId: string | null; +}; diff --git a/services/media/db/models/serialized.ts b/services/media/db/models/serialized.ts new file mode 100644 index 0000000..cb72abc --- /dev/null +++ b/services/media/db/models/serialized.ts @@ -0,0 +1,47 @@ +// DO NOT EDIT — Auto-generated file; see https://github.com/mogzol/prisma-generator-typescript-interfaces + +export type MediaFileDto = { + id: string; + bucket: string; + key: string; + mimetype: string; + url: string | null; + srcUrl: string | null; + createdAt: string; + updatedAt: string; + meetingRecordId: string | null; + title: string | null; + description: string | null; + fileSize: number | null; + videoProcessingTaskVideos?: VideoProcessingTaskDto[]; + videoProcessingTaskAudios?: VideoProcessingTaskDto[]; +}; + +export type VideoProcessingBatchDto = { + id: string; + status: string; + totalTasks: number; + completedTasks: number; + failedTasks: number; + createdAt: string; + updatedAt: string; + tasks?: VideoProcessingTaskDto[]; +}; + +export type VideoProcessingTaskDto = { + id: string; + viewerUrl: string | null; + downloadUrl: string | null; + status: string; + extractAudio: boolean; + error: string | null; + createdAt: string; + updatedAt: string; + batchId: string | null; + meetingRecordId: string | null; + videoId: string | null; + audioId: string | null; + batch?: VideoProcessingBatchDto | null; + video?: MediaFileDto | null; + audio?: MediaFileDto | null; +}; diff --git a/services/media/db/schema.prisma b/services/media/db/schema.prisma new file mode 100644 index 0000000..a23da4a --- /dev/null +++ b/services/media/db/schema.prisma @@ -0,0 +1,114 @@ +// This is your Prisma schema file for this service, +// learn more about it in the docs: https://pris.ly/d/prisma-schema + +generator client { + provider = "prisma-client-js" + previewFeatures = ["driverAdapters", "metrics"] + binaryTargets = ["native", "debian-openssl-3.0.x"] + output = "../../node_modules/@prisma/client/media" +} + +generator json { + provider = "prisma-json-types-generator" + engineType = "library" + clientOutput = "../../node_modules/@prisma/client/media" +} + +generator docs { + provider = "node node_modules/prisma-docs-generator" + output = "./docs" +} + +generator markdown { + provider = "prisma-markdown" + output = "./docs/README.md" + title = "Media Service Database Schema" +} + +generator typescriptInterfaces { + provider = "prisma-generator-typescript-interfaces" + modelType = "type" + enumType = "object" + headerComment = "DO NOT EDIT — Auto-generated file; see https://github.com/mogzol/prisma-generator-typescript-interfaces" + modelSuffix = "Model" + output = "./models/db.ts" + prettier = true +} + +generator typescriptInterfacesJson { + provider = "prisma-generator-typescript-interfaces" + modelType = "type" + enumType = "stringUnion" + enumPrefix = "$" + headerComment = "DO NOT EDIT — Auto-generated file; see https://github.com/mogzol/prisma-generator-typescript-interfaces" + output = "./models/dto.ts" + modelSuffix = "Dto" + dateType = "string" + bigIntType = "string" + decimalType = "string" + bytesType = "ArrayObject" + omitRelations = true + prettier = true +} + +datasource db { + provider = "postgresql" + url = env("MEDIA_DATABASE_URL") +} + +/// Models related to media files and processing tasks + +model MediaFile { + id String @id @default(ulid()) + bucket String + key String + mimetype String + url String? + srcUrl String? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + // External references maintained by ID only + meetingRecordId String? + + // MediaFile metadata + title String? + description String? + fileSize Int? + + // Tasks related to this media file + videoProcessingTaskVideos VideoProcessingTask[] @relation("task_video") + videoProcessingTaskAudios VideoProcessingTask[] @relation("task_audio") +} + +model VideoProcessingBatch { + id String @id @default(ulid()) + status String // queued, processing, completed, failed + totalTasks Int + completedTasks Int @default(0) + failedTasks Int @default(0) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + tasks VideoProcessingTask[] +} + +model VideoProcessingTask { + id String @id @default(ulid()) + viewerUrl String? + downloadUrl String? + status String // queued, processing, completed, failed + extractAudio Boolean @default(true) + error String? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + batchId String? + meetingRecordId String? // Reference to TGov service's MeetingRecord + videoId String? + audioId String? + + batch VideoProcessingBatch? @relation(fields: [batchId], references: [id]) + video MediaFile? @relation("task_video", fields: [videoId], references: [id]) + audio MediaFile? @relation("task_audio", fields: [audioId], references: [id]) +} diff --git a/media/downloader.ts b/services/media/downloader.ts similarity index 89% rename from media/downloader.ts rename to services/media/downloader.ts index f3a6c79..8ff25e7 100644 --- a/media/downloader.ts +++ b/services/media/downloader.ts @@ -3,11 +3,13 @@ * * Provides functions for downloading videos from various sources, including m3u8 streams. */ -import ffmpeg from "fluent-ffmpeg"; import fs from "fs/promises"; import path from "path"; + import logger from "encore.dev/log"; +import ffmpeg from "fluent-ffmpeg"; + // The types for progress and codec data from fluent-ffmpeg export interface ProgressData { frames: number; @@ -29,15 +31,15 @@ export interface ProgressData { export async function downloadVideo( url: string, outputPath: string, - progressCallback?: (progress: ProgressData) => void + progressCallback?: (progress: ProgressData) => void, ): Promise { // Ensure output directory exists await fs.mkdir(path.dirname(outputPath), { recursive: true }); return new Promise((resolve, reject) => { - const command = ffmpeg(url) + const command = ffmpeg() + .addInput(url) .inputOptions("-protocol_whitelist", "file,http,https,tcp,tls,crypto") - .outputOptions("-c", "copy") .output(outputPath); if (progressCallback) { @@ -45,7 +47,7 @@ export async function downloadVideo( } else { command.on("progress", (progress) => { logger.info( - `Download progress: ${progress.percent?.toFixed(2)}% complete` + `Download progress: ${progress.percent?.toFixed(2)}% complete`, ); }); } @@ -77,28 +79,24 @@ export async function downloadVideo( export async function downloadVideoWithAudioExtraction( url: string, videoOutputPath: string, - audioOutputPath: string + audioOutputPath: string, ): Promise { // Ensure output directories exist await fs.mkdir(path.dirname(videoOutputPath), { recursive: true }); await fs.mkdir(path.dirname(audioOutputPath), { recursive: true }); return new Promise((resolve, reject) => { - ffmpeg(url) + ffmpeg() + .addInput(url) .inputOptions("-protocol_whitelist", "file,http,https,tcp,tls,crypto") // Output 1: Video file with video and audio .output(videoOutputPath) - .outputOptions("-c", "copy") - // Output 2: Audio file with just audio .output(audioOutputPath) - .outputOptions("-vn") // No video - .outputOptions("-acodec", "libmp3lame") // Use MP3 codec - .outputOptions("-ab", "128k") // Audio bitrate - + .withNoVideo() .on("progress", (progress) => { logger.info( - `Download progress: ${progress.percent?.toFixed(2)}% complete` + `Download progress: ${progress.percent?.toFixed(2)}% complete`, ); }) .on("end", () => { diff --git a/media/encore.service.ts b/services/media/encore.service.ts similarity index 100% rename from media/encore.service.ts rename to services/media/encore.service.ts diff --git a/media/extractor.ts b/services/media/extractor.ts similarity index 87% rename from media/extractor.ts rename to services/media/extractor.ts index 58d54a5..76791ee 100644 --- a/media/extractor.ts +++ b/services/media/extractor.ts @@ -3,11 +3,13 @@ * * Provides functions for extracting and splitting audio and video tracks from video files. */ -import ffmpeg from "fluent-ffmpeg"; import fs from "fs/promises"; import path from "path"; + import logger from "encore.dev/log"; +import ffmpeg from "fluent-ffmpeg"; + /** * Extracts the audio track from a video file * @@ -17,21 +19,23 @@ import logger from "encore.dev/log"; */ export async function extractAudioTrack( videoPath: string, - outputPath: string + outputPath: string, ): Promise { // Ensure output directory exists await fs.mkdir(path.dirname(outputPath), { recursive: true }); return new Promise((resolve, reject) => { - ffmpeg(videoPath) - .outputOptions("-vn -c:a copy") // No video + ffmpeg() + .addInput(videoPath) .output(outputPath) + .addOutputOption("-vn") // No video + .addOutputOption("-c:a", "copy") // Copy audio codec (no re-encoding) .on("start", (commandLine) => { logger.info(`Audio extraction started: ${commandLine}`); }) .on("progress", (progress) => { logger.info( - `Audio extraction progress: ${progress.percent?.toFixed(2)}% complete` + `Audio extraction progress: ${progress.percent?.toFixed(2)}% complete`, ); }) .on("end", () => { @@ -55,21 +59,23 @@ export async function extractAudioTrack( */ export async function extractVideoTrack( videoPath: string, - outputPath: string + outputPath: string, ): Promise { // Ensure output directory exists await fs.mkdir(path.dirname(outputPath), { recursive: true }); return new Promise((resolve, reject) => { - ffmpeg(videoPath) - .outputOptions("-an -c:v copy") // No audio, copy video codec + ffmpeg() + .addInput(videoPath) .output(outputPath) + .addOutputOption("-an") + .addOutputOption("-c:v", "copy") // No audio, copy video codec (no re-encoding) .on("start", (commandLine) => { logger.info(`Video extraction started: ${commandLine}`); }) .on("progress", (progress) => { logger.info( - `Video extraction progress: ${progress.percent?.toFixed(2)}% complete` + `Video extraction progress: ${progress.percent?.toFixed(2)}% complete`, ); }) .on("end", () => { @@ -94,7 +100,7 @@ export async function extractVideoTrack( export async function extractAudioAndVideo( inputPath: string, videoOutputPath: string, - audioOutputPath: string + audioOutputPath: string, ): Promise { // Ensure output directories exist await fs.mkdir(path.dirname(videoOutputPath), { recursive: true }); @@ -104,13 +110,13 @@ export async function extractAudioAndVideo( const command = ffmpeg(inputPath); // First output: video only - command.output(videoOutputPath).outputOptions([ + command.output(videoOutputPath).addOutputOptions([ "-an", // No audio "-c:v copy", // Copy video codec (no re-encoding) ]); // Second output: audio only - command.output(audioOutputPath).outputOptions([ + command.output(audioOutputPath).addOutputOption([ "-vn", // No video "-c:a copy", // Copy audio codec (no re-encoding) ]); @@ -121,7 +127,7 @@ export async function extractAudioAndVideo( }) .on("progress", (progress) => { logger.info( - `Extraction progress: ${progress.percent?.toFixed(2)}% complete` + `Extraction progress: ${progress.percent?.toFixed(2)}% complete`, ); }) .on("end", () => { diff --git a/media/index.ts b/services/media/index.ts similarity index 97% rename from media/index.ts rename to services/media/index.ts index 04e34a5..38e72dc 100644 --- a/media/index.ts +++ b/services/media/index.ts @@ -6,11 +6,13 @@ * - Process videos (extract audio) * - Retrieve processed videos and audio */ +import crypto from "crypto"; + +import { db } from "./db"; +import { processMedia } from "./processor"; + import { api } from "encore.dev/api"; import logger from "encore.dev/log"; -import crypto from "crypto"; -import { db } from "./data"; -import { processMedia, ProcessedMediaResult } from "./processor"; // Interface for downloading videos endpoints interface DownloadRequest { @@ -87,7 +89,7 @@ export const downloadVideos = api( } return { results }; - } + }, ); /** @@ -114,12 +116,13 @@ export const getMediaInfo = api( mimetype: mediaFile.mimetype, key: mediaFile.key, bucket: mediaFile.bucket, + createdAt: mediaFile.createdAt, title: mediaFile.title, description: mediaFile.description, fileSize: mediaFile.fileSize, }; - } + }, ); /** @@ -150,7 +153,7 @@ export const listVideos = api( description: video.description, fileSize: video.fileSize, })); - } + }, ); /** @@ -181,5 +184,5 @@ export const listAudio = api( description: audio.description, fileSize: audio.fileSize, })); - } + }, ); diff --git a/services/media/processor.ts b/services/media/processor.ts new file mode 100644 index 0000000..b4ff3b1 --- /dev/null +++ b/services/media/processor.ts @@ -0,0 +1,218 @@ +/** + * Media Processor Module + * + * Provides high-level functions for downloading, processing, and storing media files + */ +import crypto from "crypto"; +import fs from "fs/promises"; +import path from "node:path"; + +import env from "../../env"; +import { db, recordings } from "./db"; +import { downloadVideo, downloadVideoWithAudioExtraction } from "./downloader"; + +import logger from "encore.dev/log"; + +import { fileTypeFromBuffer } from "file-type"; + +export interface ProcessingOptions { + filename?: string; + extractAudio?: boolean; + meetingRecordId?: string; +} + +export interface ProcessedMediaResult { + videoId: string; + audioId?: string; + videoUrl?: string; + audioUrl?: string; + videoMimetype?: string; + audioMimetype?: string; +} + +/** + * Process a video from a URL, with options to download and save directly to cloud storage + * + * @param url The m3u8 URL or other video URL to process + * @param options Processing options + * @returns Database IDs and URLs for the processed files + */ +export async function processMedia( + url: string, + options: ProcessingOptions = {}, +): Promise { + const { + filename = `video_${Date.now()}`, + extractAudio = true, + meetingRecordId, + } = options; + + // Generate unique keys for cloud storage + const videoFilename = `${filename}.mp4`; + const audioFilename = `${filename}.mp3`; + + // Hash the URL to use as part of the key + const urlHash = crypto + .createHash("sha256") + .update(url) + .digest("base64url") + .substring(0, 12); + const videoKey = `${urlHash}_${videoFilename}`; + const audioKey = `${urlHash}_${audioFilename}`; + + logger.info(`Processing media from ${url}`); + logger.info(`Video key: ${videoKey}`); + if (extractAudio) logger.info(`Audio key: ${audioKey}`); + + const tempDir = await fs.mkdtemp( + env.TMP_DIR + path.sep + `media-processor-${filename}-`, + ); + + try { + // Create a temporary directory for processing if needed + await fs.mkdir(env.TMP_DIR, { recursive: true }); + + const videoPath = path.join(`${tempDir}`, `${videoFilename}`); + const audioPath = + extractAudio ? path.join(`${tempDir}`, `${audioFilename}`) : undefined; + // Create temp directory + await fs.mkdir(tempDir, { recursive: true }); + + // Step 1: Download the video/audio to temporary location + logger.info(`Downloading video to temp location: ${videoPath}`); + if (!audioPath) await downloadVideo(url, videoPath); + else await downloadVideoWithAudioExtraction(url, videoPath, audioPath); + + // Step 2: Upload files to storage and save to database + const result = await uploadAndSaveToDb( + videoPath, + audioPath, + videoKey, + audioKey, + url, + meetingRecordId, + ); + + return result; + } finally { + // Clean up temporary files + try { + await fs.rm(tempDir, { recursive: true, force: true }); + logger.info(`Cleaned up temporary directory: ${tempDir}`); + } catch (err) { + logger.error(`Failed to clean up temporary directory: ${err}`); + } + } +} + +/** + * Upload files to storage bucket and update database + */ +async function uploadAndSaveToDb( + videoPath: string, + audioPath: string | undefined, + videoKey: string, + audioKey: string, + sourceUrl: string, + meetingRecordId?: string, +): Promise { + // Read files and get their content types + const videoBuffer = await fs.readFile(videoPath); + // Use file-type to detect the actual mimetype of the video + const videoTypeResult = await fileTypeFromBuffer(videoBuffer); + const videoType = videoTypeResult?.mime || "application/octet-stream"; + logger.info(`Detected video mimetype: ${videoType}`); + + let audioBuffer: Buffer | undefined; + let audioType: string | undefined; + + if (audioPath) { + audioBuffer = await fs.readFile(audioPath); + // Use file-type to detect the actual mimetype of the audio + const audioTypeResult = await fileTypeFromBuffer(audioBuffer); + audioType = audioTypeResult?.mime || "application/octet-stream"; + logger.info(`Detected audio mimetype: ${audioType}`); + } + + try { + // First upload files to storage before creating database records + const [videoAttrs, audioAttrs] = await Promise.all([ + recordings.upload(videoKey, videoBuffer, { contentType: videoType }), + audioBuffer && audioType ? + recordings.upload(audioKey, audioBuffer, { contentType: audioType }) + : Promise.resolve(null), + ]); + + // Now use a transaction to create database records + // This ensures that either all records are created or none are + return await db.$transaction(async (tx) => { + const videoFile = await tx.mediaFile.create({ + data: { + bucket: "recordings", + key: videoKey, + mimetype: videoType, + url: recordings.publicUrl(videoKey), + srcUrl: sourceUrl, + meetingRecordId, + fileSize: videoAttrs.size, + title: `Video ${new Date().toISOString().split("T")[0]}`, + description: `Video processed from ${sourceUrl}`, + }, + }); + + let audioFile; + if (audioBuffer && audioType && audioAttrs) { + audioFile = await tx.mediaFile.create({ + data: { + bucket: "recordings", + key: audioKey, + mimetype: audioType, + url: recordings.publicUrl(audioKey), + srcUrl: sourceUrl, + meetingRecordId, + fileSize: audioAttrs.size, + title: `Audio ${new Date().toISOString().split("T")[0]}`, + description: `Audio extracted from ${sourceUrl}`, + }, + }); + } + + return { + videoId: videoFile.id, + audioId: audioFile?.id, + videoUrl: videoFile.url || undefined, + audioUrl: audioFile?.url || undefined, + videoMimetype: videoFile.mimetype, + audioMimetype: audioFile?.mimetype, + }; + }); + } catch (error) { + // If anything fails, attempt to clean up any uploaded files + logger.error(`Failed to process media: ${error}`); + + try { + // Try to remove uploaded files if they exist + const cleanupPromises = []; + cleanupPromises.push( + recordings.exists(videoKey).then((exists) => { + if (exists) return recordings.remove(videoKey); + }), + ); + + if (audioBuffer && audioType) { + cleanupPromises.push( + recordings.exists(audioKey).then((exists) => { + if (exists) return recordings.remove(audioKey); + }), + ); + } + + await Promise.allSettled(cleanupPromises); + logger.info("Cleaned up uploaded files after transaction failure"); + } catch (cleanupError) { + logger.error(`Failed to clean up files after error: ${cleanupError}`); + } + + throw error; // Re-throw the original error + } +} diff --git a/tgov/browser.ts b/services/scrapers/browser.ts similarity index 69% rename from tgov/browser.ts rename to services/scrapers/browser.ts index bece833..8b89965 100644 --- a/tgov/browser.ts +++ b/services/scrapers/browser.ts @@ -1,3 +1,5 @@ +import env from "../../env"; + import { LaunchOptions } from "puppeteer"; // Default launch options for Puppeteer @@ -6,6 +8,4 @@ export const launchOptions: LaunchOptions = { }; // Use chromium path from environment if available -if (process.env.CHROMIUM_PATH) { - launchOptions.executablePath = process.env.CHROMIUM_PATH; -} +if (process.env.CHROMIUM_PATH) launchOptions.executablePath = env.CHROMIUM_PATH; diff --git a/services/scrapers/encore.service.ts b/services/scrapers/encore.service.ts new file mode 100644 index 0000000..7a889bd --- /dev/null +++ b/services/scrapers/encore.service.ts @@ -0,0 +1,12 @@ +import { Service } from "encore.dev/service"; + +/** + * Media service for managing audio and video processing + * + * This service is responsible for: + * - Downloading videos from URLs + * - Extracting audio from videos + * - Processing and storing media files + * - Providing APIs for media access and conversion + */ +export default new Service("scrapers"); diff --git a/services/scrapers/tgov/constants.ts b/services/scrapers/tgov/constants.ts new file mode 100644 index 0000000..c3ce973 --- /dev/null +++ b/services/scrapers/tgov/constants.ts @@ -0,0 +1,8 @@ +/** + * Constants for the TGov service + */ +export const TGOV = { + BASE_URL: "https://tulsa-ok.granicus.com", + INDEX_PATHNAME: "/ViewPublisher.php", + PLAYER_PATHNAME: "/MediaPlayer.php", +}; diff --git a/services/scrapers/tgov/index.ts b/services/scrapers/tgov/index.ts new file mode 100644 index 0000000..9c1d89f --- /dev/null +++ b/services/scrapers/tgov/index.ts @@ -0,0 +1,69 @@ +import { TGovIndexMeetingRawJSON } from "../../tgov/db/models/json"; +import { scrapeIndexPage } from "./scrapeIndexPage"; +import { scrapeMediaPage } from "./scrapeMediaPage"; + +import { api, APIError } from "encore.dev/api"; +import logger from "encore.dev/log"; + +type TgovScrapeResponse = { data: TGovIndexMeetingRawJSON[] }; + +/** + * Scrape the Tulsa Government (TGov) index page for new meeting information. + * This includes committee names, meeting names, dates, durations, agenda URLs, and video URLs. + * The scraped data is then stored in the database for further processing. + */ +export const scrapeTGovIndex = api( + { + auth: false, + expose: true, + method: "GET", + path: "/scrape/tgov", + tags: ["mvp", "scraper", "tgov"], + + }, + async (): Promise => { + try { + logger.info("Starting TGov index scrape"); + const data = await scrapeIndexPage(); + return { data }; + } catch (error) { + const err = error instanceof Error ? error : new Error(String(error)); + const msg = `Error while scraping TGov index: ${err.message}`; + logger.error(err, msg); + throw APIError.internal(msg, err); + } + }, +); + +type TgovScrapeVideoParams = { + hint: { meetingId: string } | { clipId: string } | { url: string }; +}; + +type TgovScrapeVideoResponse = { videoUrl: string }; + +/** + * Extracts video URL from a TGov viewer page + * + * The TGov website doesn't provide direct video URLs. This endpoint accepts + * a viewer page URL and returns the actual video URL that can be downloaded. + */ +export const scrapeVideoDownloadUrl = api( + { + auth: false, + expose: true, + method: "POST", + path: "/scrape/tgov/video-url", + }, + async (params: TgovScrapeVideoParams): Promise => { + try { + logger.info("Extracting video download URL from viewer", params); + const videoUrl = await scrapeMediaPage(params.hint); + return { videoUrl }; + } catch (error) { + const err = error instanceof Error ? error : new Error(String(error)); + const msg = `Error while extracting video URL: ${err.message}`; + logger.error(err, msg, params); + throw APIError.internal(msg, err); + } + }, +); diff --git a/archives/tgov/scrape.ts b/services/scrapers/tgov/scrapeIndexPage.ts similarity index 52% rename from archives/tgov/scrape.ts rename to services/scrapers/tgov/scrapeIndexPage.ts index 11fe1b2..b8f2d3e 100644 --- a/archives/tgov/scrape.ts +++ b/services/scrapers/tgov/scrapeIndexPage.ts @@ -1,35 +1,49 @@ +import { TGovIndexMeetingRawJSON } from "../../tgov/db/models/json"; +import { launchOptions } from "../browser"; +import { TGOV } from "./constants"; + import logger from "encore.dev/log"; + import puppeteer from "puppeteer"; -import { tgov_urls } from "../constants"; -import { normalizeDate, normalizeName } from "./util"; -import { db } from "../data"; -import { launchOptions } from "./browser"; +/** + * This particular scraper is only suited for view 4, currently, but apparently + * there are others (view 1, view 2, view 3). Is the data the same? + */ +const VIEW_ID = "4"; + +/** + * Scrapes the TGov index page for meeting information + * + * This function is responsible for extracting committee names, + * meeting dates, durations, agenda URLs, and video URLs from + * the TGov website and storing them in the database. + * + * + * @returns A promise that resolves when scraping is complete + */ +export async function scrapeIndexPage(): Promise { + const browser = await puppeteer.launch(launchOptions); + const page = await browser.newPage(); -export async function scrapeIndex() { - // TODO: Apparently there are other "views" (namely, 2 and 3 work) — but do they have different data? - const VIEW_ID = "4"; + const url = new URL(TGOV.INDEX_PATHNAME, TGOV.BASE_URL); - const url = new URL(tgov_urls.TGOV_INDEX_PATHNAME, tgov_urls.TGOV_BASE_URL); url.searchParams.set("view_id", VIEW_ID); - const browser = await puppeteer.launch(launchOptions); - const page = await browser.newPage(); - await page.goto(url.href, { waitUntil: "networkidle0" }); - const data = await page.evaluate(async () => { + const data = await page.evaluate(async (VIEW_ID) => { const results = []; const yearsContent = Array.from( document.querySelectorAll( - ".TabbedPanelsContentGroup .TabbedPanelsContent" - ) + ".TabbedPanelsContentGroup .TabbedPanelsContent", + ), ); for (const contentDiv of yearsContent) { const collapsibles = Array.from( - contentDiv.querySelectorAll(".CollapsiblePanel") + contentDiv.querySelectorAll(".CollapsiblePanel"), ); for (const panel of collapsibles) { @@ -42,7 +56,7 @@ export async function scrapeIndex() { } const rows = Array.from( - panel.querySelectorAll(".listingTable tbody .listingRow") + panel.querySelectorAll(".listingTable tbody .listingRow"), ); for (const row of rows) { @@ -56,9 +70,6 @@ export async function scrapeIndex() { const agendaEl = columns[3]?.querySelector("a"); const videoEl = columns[4]?.querySelector("a"); - const agendaViewUrl = agendaEl?.getAttribute("href") || undefined; - const videoClickHandler = videoEl?.getAttribute("onclick") || ""; - /** * This complex regex aims for a fully "correct" parsing of the `window.open` * expression to extract the first parameter (the URL). It handles cases where: @@ -71,64 +82,46 @@ export async function scrapeIndex() { const parser = /^window\.open\((?['"])(?.+?)(?.*\)$/; - const videoViewUrl = - parser.exec(videoClickHandler)?.groups?.url || - videoEl?.getAttribute("href") || - undefined; + const base = new URL(window.location.href).origin; + + let videoViewUrl; + videoViewUrl = parser.exec(videoEl?.getAttribute("onclick") || ""); + videoViewUrl = videoViewUrl?.groups?.url; + videoViewUrl ||= videoEl?.getAttribute("href"); + videoViewUrl &&= new URL(videoViewUrl, base).href; + videoViewUrl ??= undefined; + + let agendaViewUrl; + agendaViewUrl = agendaEl?.getAttribute("href"); + agendaViewUrl &&= new URL(agendaViewUrl, base).href; + agendaViewUrl ??= undefined; + + let clipId; + + try { + const parsedUrl = new URL(videoViewUrl || agendaViewUrl || ""); + const clipIdParam = parsedUrl.searchParams.get("clip_id"); + if (clipIdParam) clipId = clipIdParam; + } catch {} results.push({ + viewId: VIEW_ID, + clipId, committee, name, date, duration, - agendaViewUrl, videoViewUrl, + agendaViewUrl, }); } } } return results; - }); - - await browser.close(); - - /* - Debugging inside the browser context is difficult, so we do minimal processing - in the browser context and do the rest here. - */ - const groups = Map.groupBy(data, ({ committee }) => normalizeName(committee)); - - for (const committeeName of groups.keys()) { - const committee = await db.committee.upsert({ - where: { name: committeeName }, - update: {}, - create: { name: committeeName }, - }); - - for (const rawJson of groups.get(committeeName) || []) { - const { startedAt, endedAt } = normalizeDate(rawJson); - const name = normalizeName(`${rawJson.name}__${rawJson.date}`); - - await db.meetingRecord.upsert({ - where: { - committeeId_startedAt: { - committeeId: committee.id, - startedAt, - }, - }, - update: {}, - create: { - name, - rawJson: { - ...rawJson, - viewId: VIEW_ID, - }, - startedAt, - endedAt, - committee: { connect: committee }, - }, - }); - } - } + }, VIEW_ID); + + logger.info("Successfully scraped TGov index", data); + + return data; } diff --git a/services/scrapers/tgov/scrapeMediaPage.ts b/services/scrapers/tgov/scrapeMediaPage.ts new file mode 100644 index 0000000..fc2629b --- /dev/null +++ b/services/scrapers/tgov/scrapeMediaPage.ts @@ -0,0 +1,78 @@ +import { launchOptions } from "../browser"; +import { TGOV } from "./constants"; + +import { tgov } from "~encore/clients"; + +import { APIError } from "encore.dev/api"; +import logger from "encore.dev/log"; + +import puppeteer from "puppeteer"; + +type ViewerMeta = + | { + url: string | URL; + clipId?: string; + meetingId?: string; + } + | { + clipId: string; + url?: string | URL; + meetingId?: string; + } + | { + meetingId: string; + url?: string | URL; + clipId?: string; + }; + +/** + * Scrapes a TGov MediaPlayer viewer page for the download URL of the video. + * + * @param viewer - An object with at least one of: + * - url: The URL of the viewer page + * - clipId: The clip ID of the video + * - meetingId: The meeting ID of the video + * + * The order above indicates the order of precedence. If the URL is provided or + * can be derived from the clip ID it is used, otherwise the TGov service is + * invoked and an additional DB query is made to get the URL. + */ +export async function scrapeMediaPage(viewer: ViewerMeta): Promise { + if (!viewer.url && !viewer.clipId && viewer.meetingId) { + const { meeting } = await tgov.getMeeting({ id: viewer.meetingId }); + viewer.url = meeting?.videoViewUrl; + viewer.clipId = meeting?.rawJson.clipId; + } + + if (!viewer.url && viewer.clipId) { + viewer.url = new URL(TGOV.PLAYER_PATHNAME, TGOV.BASE_URL); + viewer.url.searchParams.set("clip_id", viewer.clipId); + } + + if (viewer.url) logger.info("Extracting video URL", viewer); + else throw APIError.notFound("Failed to resolve Video viewer URL"); + + const browser = await puppeteer.launch(launchOptions); + const page = await browser.newPage(); + await page.goto(new URL(viewer.url).href, { waitUntil: "domcontentloaded" }); + + const videoUrl = await page.evaluate(() => { + // May be defined in the global scope of the page + var video_url: string | null | undefined; + + if (typeof video_url === "string") return video_url; + + const videoEl = document.querySelector("video > source"); + if (!videoEl) throw new Error("Selector 'video > source' found no element"); + + video_url = videoEl.getAttribute("src"); + if (!video_url) throw new Error("No src attribute found on element"); + + return video_url; + }); + + logger.info("Successfully extracted video URL", { ...viewer, videoUrl }); + + await browser.close(); + return videoUrl; +} diff --git a/archives/tgov/util.ts b/services/scrapers/tgov/util.ts similarity index 54% rename from archives/tgov/util.ts rename to services/scrapers/tgov/util.ts index c9bc72c..2c6db5f 100644 --- a/archives/tgov/util.ts +++ b/services/scrapers/tgov/util.ts @@ -1,28 +1,42 @@ import logger from "encore.dev/log"; + import { tz } from "@date-fns/tz"; import { addHours, addMinutes, parse } from "date-fns"; /** - * Normalize a scraped name into it's canonical form (as used in the database). - * - Removes all non-word characters except for dashes "-" - * - Converts to lowercase - * - Replaces each group of contiguous spaces with a single dash + * Types for TGov-specific data + */ +export interface TGovDateInfo { + date: string; + duration: string; +} + +/** + * Normalize a scraped name into its canonical form (as used in the database). + * + * In order, this function: + * - Trims the name + * - Converts the name to lowercase + * - Changes spaces to underscores + * - Removes all non-word characters except for dashes + * - Collapses multiple dashes into a single dash + * - collapses multiple underscores into a single underscore + * * @param name - The name to normalize (e.g. a committee name, meeting name, etc.) */ export function normalizeName(name: string): string { return name + .trim() .toLowerCase() - .replace(/\s+/g, "-") - .replace(/[^-\w]+/g, ""); + .replace(/\s+/g, "_") + .replace(/[^-\w]/g, "") + .replace(/-+/g, "-") + .replace(/_+/g, "_"); } -type TGovDateInfo = Pick< - PrismaJson.TGovIndexMeetingRawJSON, - "date" | "duration" ->; - /** - * Since TGov's dates are implicitly in the America/Chicago timezone and use a + * Extract startedAt and endedAt timestamps from raw TGov date info + Since TGov's dates are implicitly in the America/Chicago timezone and use a * non-standard format, special care must be taken to parse them correctly. * * The date format is "MMMM d, y - h:mm a" (e.g. "June 1, 2021 - 10:00 AM"). @@ -35,36 +49,28 @@ type TGovDateInfo = Pick< * - calculating end time from the inputs * - converting to UTC and formatting as ISO 8601 * - * @param raw - The raw date and duration information from TGov. - * @returns An object with the normalized start and end times. + * @param raw The raw date information from TGov + * @returns Object containing normalized startedAt and endedAt timestamps */ export function normalizeDate(raw: TGovDateInfo): { startedAt: string; endedAt: string; } { const timeZone = "America/Chicago"; - const durationFormat = /(?\d+?h)\s+?(?\d+?)m/; + const durationFormat = /(?\d+?)h\s+?(?\d+?)m/; - /** - *Times on TGov's website are implicitly in the America/Chicago timezone - */ const start = parse( raw.date, "MMMM d, y - h:mm a", new Intl.DateTimeFormat("en-US", { timeZone }).format(Date.now()), - { in: tz(timeZone) } + { in: tz(timeZone) }, ); - let end; - let duration; - - duration = raw.duration.match(durationFormat)?.groups; - - if (!duration) { - logger.warn("Failed to parse duration", raw.duration); - duration = { hours: "0", minutes: "0" }; - } + let duration = raw.duration.match(durationFormat)?.groups; + if (!duration) logger.warn("Failed to parse duration", raw.duration); + duration ??= { hours: "0", minutes: "0" }; + let end; end = start.withTimeZone(timeZone); end = addHours(end, parseInt(duration.hours)); end = addMinutes(end, parseInt(duration.minutes)); diff --git a/services/tgov/cron.ts b/services/tgov/cron.ts new file mode 100644 index 0000000..d266f77 --- /dev/null +++ b/services/tgov/cron.ts @@ -0,0 +1,12 @@ +import { pull } from "."; + +import { CronJob } from "encore.dev/cron"; + +/** + * Scrapes the TGov index page daily at 12:01 AM. + */ +export const dailyTgovScrape = new CronJob("daily-tgov-scrape", { + endpoint: pull, + title: "TGov Daily Scrape", + schedule: "1 0 * * *", +}); diff --git a/services/tgov/db/docs/README.md b/services/tgov/db/docs/README.md new file mode 100644 index 0000000..11a7b75 --- /dev/null +++ b/services/tgov/db/docs/README.md @@ -0,0 +1,56 @@ +# Models +> Generated by [`prisma-markdown`](https://github.com/samchon/prisma-markdown) + +- [default](#default) + +## default +```mermaid +erDiagram +"Committee" { + String id PK + String name UK + DateTime createdAt + DateTime updatedAt +} +"MeetingRecord" { + String id PK + String name UK + DateTime startedAt + DateTime endedAt + DateTime createdAt + DateTime updatedAt + String committeeId FK + String videoViewUrl "nullable" + String agendaViewUrl "nullable" + Json rawJson + String videoId "nullable" + String audioId "nullable" + String agendaId "nullable" +} +"MeetingRecord" }o--|| "Committee" : committee +``` + +### `Committee` + +**Properties** + - `id`: + - `name`: + - `createdAt`: + - `updatedAt`: + +### `MeetingRecord` + +**Properties** + - `id`: + - `name`: + - `startedAt`: + - `endedAt`: + - `createdAt`: + - `updatedAt`: + - `committeeId`: + - `videoViewUrl`: + - `agendaViewUrl`: + - `rawJson`: [MeetingRawJSON] + - `videoId`: + - `audioId`: + - `agendaId`: \ No newline at end of file diff --git a/services/tgov/db/docs/index.html b/services/tgov/db/docs/index.html new file mode 100644 index 0000000..7aaf277 --- /dev/null +++ b/services/tgov/db/docs/index.html @@ -0,0 +1,13035 @@ + + + + + + + + Prisma Generated Docs + + + + +
+
+
+ + + + + + + + +
+ +
+
Models
+ +
Types
+ +
+ +
+
+ +
+

Models

+ +
+

Committee

+ + +
+

Fields

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesRequiredComment
+ id + + String + +
    +
  • @id
  • @default(ulid())
  • +
+
+ Yes + + - +
+ name + + String + +
    +
  • @unique
  • +
+
+ Yes + + - +
+ createdAt + + DateTime + +
    +
  • @default(now())
  • +
+
+ Yes + + - +
+ updatedAt + + DateTime + +
    +
  • @updatedAt
  • +
+
+ Yes + + - +
+ meetingRecords + + MeetingRecord[] + +
    +
  • -
  • +
+
+ Yes + + - +
+
+
+
+
+

Operations

+
+ +
+

findUnique

+

Find zero or one Committee

+
+
// Get one Committee
+const committee = await prisma.committee.findUnique({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + CommitteeWhereUniqueInput + + Yes +
+

Output

+
Type: Committee
+
Required: + No
+
List: + No
+
+
+
+

findFirst

+

Find first Committee

+
+
// Get one Committee
+const committee = await prisma.committee.findFirst({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + CommitteeWhereInput + + No +
+ orderBy + + CommitteeOrderByWithRelationInput[] | CommitteeOrderByWithRelationInput + + No +
+ cursor + + CommitteeWhereUniqueInput + + No +
+ take + + Int + + No +
+ skip + + Int + + No +
+ distinct + + CommitteeScalarFieldEnum | CommitteeScalarFieldEnum[] + + No +
+

Output

+
Type: Committee
+
Required: + No
+
List: + No
+
+
+
+

findMany

+

Find zero or more Committee

+
+
// Get all Committee
+const Committee = await prisma.committee.findMany()
+// Get first 10 Committee
+const Committee = await prisma.committee.findMany({ take: 10 })
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + CommitteeWhereInput + + No +
+ orderBy + + CommitteeOrderByWithRelationInput[] | CommitteeOrderByWithRelationInput + + No +
+ cursor + + CommitteeWhereUniqueInput + + No +
+ take + + Int + + No +
+ skip + + Int + + No +
+ distinct + + CommitteeScalarFieldEnum | CommitteeScalarFieldEnum[] + + No +
+

Output

+
Type: Committee
+
Required: + Yes
+
List: + Yes
+
+
+
+

create

+

Create one Committee

+
+
// Create one Committee
+const Committee = await prisma.committee.create({
+  data: {
+    // ... data to create a Committee
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + CommitteeCreateInput | CommitteeUncheckedCreateInput + + Yes +
+

Output

+
Type: Committee
+
Required: + Yes
+
List: + No
+
+
+
+

delete

+

Delete one Committee

+
+
// Delete one Committee
+const Committee = await prisma.committee.delete({
+  where: {
+    // ... filter to delete one Committee
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + CommitteeWhereUniqueInput + + Yes +
+

Output

+
Type: Committee
+
Required: + No
+
List: + No
+
+
+
+

update

+

Update one Committee

+
+
// Update one Committee
+const committee = await prisma.committee.update({
+  where: {
+    // ... provide filter here
+  },
+  data: {
+    // ... provide data here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + CommitteeUpdateInput | CommitteeUncheckedUpdateInput + + Yes +
+ where + + CommitteeWhereUniqueInput + + Yes +
+

Output

+
Type: Committee
+
Required: + No
+
List: + No
+
+
+
+

deleteMany

+

Delete zero or more Committee

+
+
// Delete a few Committee
+const { count } = await prisma.committee.deleteMany({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + CommitteeWhereInput + + No +
+ limit + + Int + + No +
+

Output

+ +
Required: + Yes
+
List: + No
+
+
+
+

updateMany

+

Update zero or one Committee

+
+
const { count } = await prisma.committee.updateMany({
+  where: {
+    // ... provide filter here
+  },
+  data: {
+    // ... provide data here
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + CommitteeUpdateManyMutationInput | CommitteeUncheckedUpdateManyInput + + Yes +
+ where + + CommitteeWhereInput + + No +
+ limit + + Int + + No +
+

Output

+ +
Required: + Yes
+
List: + No
+
+
+
+

upsert

+

Create or update one Committee

+
+
// Update or create a Committee
+const committee = await prisma.committee.upsert({
+  create: {
+    // ... data to create a Committee
+  },
+  update: {
+    // ... in case it already exists, update
+  },
+  where: {
+    // ... the filter for the Committee we want to update
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + CommitteeWhereUniqueInput + + Yes +
+ create + + CommitteeCreateInput | CommitteeUncheckedCreateInput + + Yes +
+ update + + CommitteeUpdateInput | CommitteeUncheckedUpdateInput + + Yes +
+

Output

+
Type: Committee
+
Required: + Yes
+
List: + No
+
+ +
+
+
+
+
+

MeetingRecord

+ + + + + + + + + + + + + + + + + + + + + + + + +
NameValue
+ @@unique +
    +
  • committeeId
  • startedAt
  • +
+
+ @@index +
    +
  • committeeId
  • startedAt
  • +
+
+ +
+

Fields

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesRequiredComment
+ id + + String + +
    +
  • @id
  • @default(ulid())
  • +
+
+ Yes + + - +
+ name + + String + +
    +
  • @unique
  • +
+
+ Yes + + - +
+ startedAt + + DateTime + +
    +
  • -
  • +
+
+ Yes + + - +
+ endedAt + + DateTime + +
    +
  • -
  • +
+
+ Yes + + - +
+ createdAt + + DateTime + +
    +
  • @default(now())
  • +
+
+ Yes + + - +
+ updatedAt + + DateTime + +
    +
  • @updatedAt
  • +
+
+ Yes + + - +
+ committeeId + + String + +
    +
  • -
  • +
+
+ Yes + + - +
+ videoViewUrl + + String? + +
    +
  • -
  • +
+
+ No + + - +
+ agendaViewUrl + + String? + +
    +
  • -
  • +
+
+ No + + - +
+ rawJson + + Json + +
    +
  • -
  • +
+
+ Yes + + [MeetingRawJSON] +
+ videoId + + String? + +
    +
  • -
  • +
+
+ No + + - +
+ audioId + + String? + +
    +
  • -
  • +
+
+ No + + - +
+ agendaId + + String? + +
    +
  • -
  • +
+
+ No + + - +
+ committee + + Committee + +
    +
  • -
  • +
+
+ Yes + + - +
+
+
+
+
+

Operations

+
+ +
+

findUnique

+

Find zero or one MeetingRecord

+
+
// Get one MeetingRecord
+const meetingRecord = await prisma.meetingRecord.findUnique({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + MeetingRecordWhereUniqueInput + + Yes +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

findFirst

+

Find first MeetingRecord

+
+
// Get one MeetingRecord
+const meetingRecord = await prisma.meetingRecord.findFirst({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + MeetingRecordWhereInput + + No +
+ orderBy + + MeetingRecordOrderByWithRelationInput[] | MeetingRecordOrderByWithRelationInput + + No +
+ cursor + + MeetingRecordWhereUniqueInput + + No +
+ take + + Int + + No +
+ skip + + Int + + No +
+ distinct + + MeetingRecordScalarFieldEnum | MeetingRecordScalarFieldEnum[] + + No +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

findMany

+

Find zero or more MeetingRecord

+
+
// Get all MeetingRecord
+const MeetingRecord = await prisma.meetingRecord.findMany()
+// Get first 10 MeetingRecord
+const MeetingRecord = await prisma.meetingRecord.findMany({ take: 10 })
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + MeetingRecordWhereInput + + No +
+ orderBy + + MeetingRecordOrderByWithRelationInput[] | MeetingRecordOrderByWithRelationInput + + No +
+ cursor + + MeetingRecordWhereUniqueInput + + No +
+ take + + Int + + No +
+ skip + + Int + + No +
+ distinct + + MeetingRecordScalarFieldEnum | MeetingRecordScalarFieldEnum[] + + No +
+

Output

+ +
Required: + Yes
+
List: + Yes
+
+
+
+

create

+

Create one MeetingRecord

+
+
// Create one MeetingRecord
+const MeetingRecord = await prisma.meetingRecord.create({
+  data: {
+    // ... data to create a MeetingRecord
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + MeetingRecordCreateInput | MeetingRecordUncheckedCreateInput + + Yes +
+

Output

+ +
Required: + Yes
+
List: + No
+
+
+
+

delete

+

Delete one MeetingRecord

+
+
// Delete one MeetingRecord
+const MeetingRecord = await prisma.meetingRecord.delete({
+  where: {
+    // ... filter to delete one MeetingRecord
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + MeetingRecordWhereUniqueInput + + Yes +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

update

+

Update one MeetingRecord

+
+
// Update one MeetingRecord
+const meetingRecord = await prisma.meetingRecord.update({
+  where: {
+    // ... provide filter here
+  },
+  data: {
+    // ... provide data here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + MeetingRecordUpdateInput | MeetingRecordUncheckedUpdateInput + + Yes +
+ where + + MeetingRecordWhereUniqueInput + + Yes +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

deleteMany

+

Delete zero or more MeetingRecord

+
+
// Delete a few MeetingRecord
+const { count } = await prisma.meetingRecord.deleteMany({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + MeetingRecordWhereInput + + No +
+ limit + + Int + + No +
+

Output

+ +
Required: + Yes
+
List: + No
+
+
+
+

updateMany

+

Update zero or one MeetingRecord

+
+
const { count } = await prisma.meetingRecord.updateMany({
+  where: {
+    // ... provide filter here
+  },
+  data: {
+    // ... provide data here
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + MeetingRecordUpdateManyMutationInput | MeetingRecordUncheckedUpdateManyInput + + Yes +
+ where + + MeetingRecordWhereInput + + No +
+ limit + + Int + + No +
+

Output

+ +
Required: + Yes
+
List: + No
+
+
+
+

upsert

+

Create or update one MeetingRecord

+
+
// Update or create a MeetingRecord
+const meetingRecord = await prisma.meetingRecord.upsert({
+  create: {
+    // ... data to create a MeetingRecord
+  },
+  update: {
+    // ... in case it already exists, update
+  },
+  where: {
+    // ... the filter for the MeetingRecord we want to update
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + MeetingRecordWhereUniqueInput + + Yes +
+ create + + MeetingRecordCreateInput | MeetingRecordUncheckedCreateInput + + Yes +
+ update + + MeetingRecordUpdateInput | MeetingRecordUncheckedUpdateInput + + Yes +
+

Output

+ +
Required: + Yes
+
List: + No
+
+ +
+
+
+ +
+ +
+

Types

+
+
+

Input Types

+
+ +
+

CommitteeWhereInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ AND + CommitteeWhereInput | CommitteeWhereInput[] + + No +
+ OR + CommitteeWhereInput[] + + No +
+ NOT + CommitteeWhereInput | CommitteeWhereInput[] + + No +
+ id + StringFilter | String + + No +
+ name + StringFilter | String + + No +
+ createdAt + DateTimeFilter | DateTime + + No +
+ updatedAt + DateTimeFilter | DateTime + + No +
+ meetingRecords + MeetingRecordListRelationFilter + + No +
+
+
+
+

CommitteeOrderByWithRelationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ name + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ meetingRecords + MeetingRecordOrderByRelationAggregateInput + + No +
+
+
+
+

CommitteeWhereUniqueInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ name + String + + No +
+ AND + CommitteeWhereInput | CommitteeWhereInput[] + + No +
+ OR + CommitteeWhereInput[] + + No +
+ NOT + CommitteeWhereInput | CommitteeWhereInput[] + + No +
+ createdAt + DateTimeFilter | DateTime + + No +
+ updatedAt + DateTimeFilter | DateTime + + No +
+ meetingRecords + MeetingRecordListRelationFilter + + No +
+
+
+
+

CommitteeOrderByWithAggregationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ name + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ _count + CommitteeCountOrderByAggregateInput + + No +
+ _max + CommitteeMaxOrderByAggregateInput + + No +
+ _min + CommitteeMinOrderByAggregateInput + + No +
+
+
+
+

CommitteeScalarWhereWithAggregatesInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ AND + CommitteeScalarWhereWithAggregatesInput | CommitteeScalarWhereWithAggregatesInput[] + + No +
+ OR + CommitteeScalarWhereWithAggregatesInput[] + + No +
+ NOT + CommitteeScalarWhereWithAggregatesInput | CommitteeScalarWhereWithAggregatesInput[] + + No +
+ id + StringWithAggregatesFilter | String + + No +
+ name + StringWithAggregatesFilter | String + + No +
+ createdAt + DateTimeWithAggregatesFilter | DateTime + + No +
+ updatedAt + DateTimeWithAggregatesFilter | DateTime + + No +
+
+
+
+

MeetingRecordWhereInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ AND + MeetingRecordWhereInput | MeetingRecordWhereInput[] + + No +
+ OR + MeetingRecordWhereInput[] + + No +
+ NOT + MeetingRecordWhereInput | MeetingRecordWhereInput[] + + No +
+ id + StringFilter | String + + No +
+ name + StringFilter | String + + No +
+ startedAt + DateTimeFilter | DateTime + + No +
+ endedAt + DateTimeFilter | DateTime + + No +
+ createdAt + DateTimeFilter | DateTime + + No +
+ updatedAt + DateTimeFilter | DateTime + + No +
+ committeeId + StringFilter | String + + No +
+ videoViewUrl + StringNullableFilter | String | Null + + Yes +
+ agendaViewUrl + StringNullableFilter | String | Null + + Yes +
+ rawJson + JsonFilter + + No +
+ videoId + StringNullableFilter | String | Null + + Yes +
+ audioId + StringNullableFilter | String | Null + + Yes +
+ agendaId + StringNullableFilter | String | Null + + Yes +
+ committee + CommitteeScalarRelationFilter | CommitteeWhereInput + + No +
+
+
+
+

MeetingRecordOrderByWithRelationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ name + SortOrder + + No +
+ startedAt + SortOrder + + No +
+ endedAt + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ committeeId + SortOrder + + No +
+ videoViewUrl + SortOrder | SortOrderInput + + No +
+ agendaViewUrl + SortOrder | SortOrderInput + + No +
+ rawJson + SortOrder + + No +
+ videoId + SortOrder | SortOrderInput + + No +
+ audioId + SortOrder | SortOrderInput + + No +
+ agendaId + SortOrder | SortOrderInput + + No +
+ committee + CommitteeOrderByWithRelationInput + + No +
+
+
+
+

MeetingRecordWhereUniqueInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ name + String + + No +
+ committeeId_startedAt + MeetingRecordCommitteeIdStartedAtCompoundUniqueInput + + No +
+ AND + MeetingRecordWhereInput | MeetingRecordWhereInput[] + + No +
+ OR + MeetingRecordWhereInput[] + + No +
+ NOT + MeetingRecordWhereInput | MeetingRecordWhereInput[] + + No +
+ startedAt + DateTimeFilter | DateTime + + No +
+ endedAt + DateTimeFilter | DateTime + + No +
+ createdAt + DateTimeFilter | DateTime + + No +
+ updatedAt + DateTimeFilter | DateTime + + No +
+ committeeId + StringFilter | String + + No +
+ videoViewUrl + StringNullableFilter | String | Null + + Yes +
+ agendaViewUrl + StringNullableFilter | String | Null + + Yes +
+ rawJson + JsonFilter + + No +
+ videoId + StringNullableFilter | String | Null + + Yes +
+ audioId + StringNullableFilter | String | Null + + Yes +
+ agendaId + StringNullableFilter | String | Null + + Yes +
+ committee + CommitteeScalarRelationFilter | CommitteeWhereInput + + No +
+
+
+
+

MeetingRecordOrderByWithAggregationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ name + SortOrder + + No +
+ startedAt + SortOrder + + No +
+ endedAt + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ committeeId + SortOrder + + No +
+ videoViewUrl + SortOrder | SortOrderInput + + No +
+ agendaViewUrl + SortOrder | SortOrderInput + + No +
+ rawJson + SortOrder + + No +
+ videoId + SortOrder | SortOrderInput + + No +
+ audioId + SortOrder | SortOrderInput + + No +
+ agendaId + SortOrder | SortOrderInput + + No +
+ _count + MeetingRecordCountOrderByAggregateInput + + No +
+ _max + MeetingRecordMaxOrderByAggregateInput + + No +
+ _min + MeetingRecordMinOrderByAggregateInput + + No +
+
+
+
+

MeetingRecordScalarWhereWithAggregatesInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ AND + MeetingRecordScalarWhereWithAggregatesInput | MeetingRecordScalarWhereWithAggregatesInput[] + + No +
+ OR + MeetingRecordScalarWhereWithAggregatesInput[] + + No +
+ NOT + MeetingRecordScalarWhereWithAggregatesInput | MeetingRecordScalarWhereWithAggregatesInput[] + + No +
+ id + StringWithAggregatesFilter | String + + No +
+ name + StringWithAggregatesFilter | String + + No +
+ startedAt + DateTimeWithAggregatesFilter | DateTime + + No +
+ endedAt + DateTimeWithAggregatesFilter | DateTime + + No +
+ createdAt + DateTimeWithAggregatesFilter | DateTime + + No +
+ updatedAt + DateTimeWithAggregatesFilter | DateTime + + No +
+ committeeId + StringWithAggregatesFilter | String + + No +
+ videoViewUrl + StringNullableWithAggregatesFilter | String | Null + + Yes +
+ agendaViewUrl + StringNullableWithAggregatesFilter | String | Null + + Yes +
+ rawJson + JsonWithAggregatesFilter + + No +
+ videoId + StringNullableWithAggregatesFilter | String | Null + + Yes +
+ audioId + StringNullableWithAggregatesFilter | String | Null + + Yes +
+ agendaId + StringNullableWithAggregatesFilter | String | Null + + Yes +
+
+
+
+

CommitteeCreateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ name + String + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ meetingRecords + MeetingRecordCreateNestedManyWithoutCommitteeInput + + No +
+
+
+
+

CommitteeUncheckedCreateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ name + String + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ meetingRecords + MeetingRecordUncheckedCreateNestedManyWithoutCommitteeInput + + No +
+
+
+
+

CommitteeUpdateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ name + String | StringFieldUpdateOperationsInput + + No +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ meetingRecords + MeetingRecordUpdateManyWithoutCommitteeNestedInput + + No +
+
+
+
+

CommitteeUncheckedUpdateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ name + String | StringFieldUpdateOperationsInput + + No +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ meetingRecords + MeetingRecordUncheckedUpdateManyWithoutCommitteeNestedInput + + No +
+
+
+
+

CommitteeCreateManyInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ name + String + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+
+
+
+

CommitteeUpdateManyMutationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ name + String | StringFieldUpdateOperationsInput + + No +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+
+
+
+

CommitteeUncheckedUpdateManyInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ name + String | StringFieldUpdateOperationsInput + + No +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+
+
+
+

MeetingRecordCreateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ name + String + + No +
+ startedAt + DateTime + + No +
+ endedAt + DateTime + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ videoViewUrl + String | Null + + Yes +
+ agendaViewUrl + String | Null + + Yes +
+ rawJson + JsonNullValueInput | Json + + No +
+ videoId + String | Null + + Yes +
+ audioId + String | Null + + Yes +
+ agendaId + String | Null + + Yes +
+ committee + CommitteeCreateNestedOneWithoutMeetingRecordsInput + + No +
+
+
+
+

MeetingRecordUncheckedCreateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ name + String + + No +
+ startedAt + DateTime + + No +
+ endedAt + DateTime + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ committeeId + String + + No +
+ videoViewUrl + String | Null + + Yes +
+ agendaViewUrl + String | Null + + Yes +
+ rawJson + JsonNullValueInput | Json + + No +
+ videoId + String | Null + + Yes +
+ audioId + String | Null + + Yes +
+ agendaId + String | Null + + Yes +
+
+
+
+

MeetingRecordUpdateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ name + String | StringFieldUpdateOperationsInput + + No +
+ startedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ endedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ videoViewUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ agendaViewUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ rawJson + JsonNullValueInput | Json + + No +
+ videoId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ audioId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ agendaId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ committee + CommitteeUpdateOneRequiredWithoutMeetingRecordsNestedInput + + No +
+
+
+
+

MeetingRecordUncheckedUpdateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ name + String | StringFieldUpdateOperationsInput + + No +
+ startedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ endedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ committeeId + String | StringFieldUpdateOperationsInput + + No +
+ videoViewUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ agendaViewUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ rawJson + JsonNullValueInput | Json + + No +
+ videoId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ audioId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ agendaId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

MeetingRecordCreateManyInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ name + String + + No +
+ startedAt + DateTime + + No +
+ endedAt + DateTime + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ committeeId + String + + No +
+ videoViewUrl + String | Null + + Yes +
+ agendaViewUrl + String | Null + + Yes +
+ rawJson + JsonNullValueInput | Json + + No +
+ videoId + String | Null + + Yes +
+ audioId + String | Null + + Yes +
+ agendaId + String | Null + + Yes +
+
+
+
+

MeetingRecordUpdateManyMutationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ name + String | StringFieldUpdateOperationsInput + + No +
+ startedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ endedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ videoViewUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ agendaViewUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ rawJson + JsonNullValueInput | Json + + No +
+ videoId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ audioId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ agendaId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

MeetingRecordUncheckedUpdateManyInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ name + String | StringFieldUpdateOperationsInput + + No +
+ startedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ endedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ committeeId + String | StringFieldUpdateOperationsInput + + No +
+ videoViewUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ agendaViewUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ rawJson + JsonNullValueInput | Json + + No +
+ videoId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ audioId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ agendaId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

StringFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput + + No +
+ in + String | ListStringFieldRefInput + + No +
+ notIn + String | ListStringFieldRefInput + + No +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ mode + QueryMode + + No +
+ not + String | NestedStringFilter + + No +
+
+
+
+

DateTimeFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + DateTime | DateTimeFieldRefInput + + No +
+ in + DateTime | ListDateTimeFieldRefInput + + No +
+ notIn + DateTime | ListDateTimeFieldRefInput + + No +
+ lt + DateTime | DateTimeFieldRefInput + + No +
+ lte + DateTime | DateTimeFieldRefInput + + No +
+ gt + DateTime | DateTimeFieldRefInput + + No +
+ gte + DateTime | DateTimeFieldRefInput + + No +
+ not + DateTime | NestedDateTimeFilter + + No +
+
+
+
+

MeetingRecordListRelationFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ every + MeetingRecordWhereInput + + No +
+ some + MeetingRecordWhereInput + + No +
+ none + MeetingRecordWhereInput + + No +
+
+
+
+

MeetingRecordOrderByRelationAggregateInput

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ _count + SortOrder + + No +
+
+
+
+

CommitteeCountOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ name + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+
+
+
+

CommitteeMaxOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ name + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+
+
+
+

CommitteeMinOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ name + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+
+
+
+

StringWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput + + No +
+ in + String | ListStringFieldRefInput + + No +
+ notIn + String | ListStringFieldRefInput + + No +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ mode + QueryMode + + No +
+ not + String | NestedStringWithAggregatesFilter + + No +
+ _count + NestedIntFilter + + No +
+ _min + NestedStringFilter + + No +
+ _max + NestedStringFilter + + No +
+
+
+
+

DateTimeWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + DateTime | DateTimeFieldRefInput + + No +
+ in + DateTime | ListDateTimeFieldRefInput + + No +
+ notIn + DateTime | ListDateTimeFieldRefInput + + No +
+ lt + DateTime | DateTimeFieldRefInput + + No +
+ lte + DateTime | DateTimeFieldRefInput + + No +
+ gt + DateTime | DateTimeFieldRefInput + + No +
+ gte + DateTime | DateTimeFieldRefInput + + No +
+ not + DateTime | NestedDateTimeWithAggregatesFilter + + No +
+ _count + NestedIntFilter + + No +
+ _min + NestedDateTimeFilter + + No +
+ _max + NestedDateTimeFilter + + No +
+
+
+
+

StringNullableFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput | Null + + Yes +
+ in + String | ListStringFieldRefInput | Null + + Yes +
+ notIn + String | ListStringFieldRefInput | Null + + Yes +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ mode + QueryMode + + No +
+ not + String | NestedStringNullableFilter | Null + + Yes +
+
+
+
+

JsonFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Json | JsonFieldRefInput | JsonNullValueFilter + + No +
+ path + String + + No +
+ mode + QueryMode | EnumQueryModeFieldRefInput + + No +
+ string_contains + String | StringFieldRefInput + + No +
+ string_starts_with + String | StringFieldRefInput + + No +
+ string_ends_with + String | StringFieldRefInput + + No +
+ array_starts_with + Json | JsonFieldRefInput | Null + + Yes +
+ array_ends_with + Json | JsonFieldRefInput | Null + + Yes +
+ array_contains + Json | JsonFieldRefInput | Null + + Yes +
+ lt + Json | JsonFieldRefInput + + No +
+ lte + Json | JsonFieldRefInput + + No +
+ gt + Json | JsonFieldRefInput + + No +
+ gte + Json | JsonFieldRefInput + + No +
+ not + Json | JsonFieldRefInput | JsonNullValueFilter + + No +
+
+
+
+

CommitteeScalarRelationFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ is + CommitteeWhereInput + + No +
+ isNot + CommitteeWhereInput + + No +
+
+
+
+

SortOrderInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ sort + SortOrder + + No +
+ nulls + NullsOrder + + No +
+
+
+
+

MeetingRecordCommitteeIdStartedAtCompoundUniqueInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ committeeId + String + + No +
+ startedAt + DateTime + + No +
+
+
+
+

MeetingRecordCountOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ name + SortOrder + + No +
+ startedAt + SortOrder + + No +
+ endedAt + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ committeeId + SortOrder + + No +
+ videoViewUrl + SortOrder + + No +
+ agendaViewUrl + SortOrder + + No +
+ rawJson + SortOrder + + No +
+ videoId + SortOrder + + No +
+ audioId + SortOrder + + No +
+ agendaId + SortOrder + + No +
+
+
+
+

MeetingRecordMaxOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ name + SortOrder + + No +
+ startedAt + SortOrder + + No +
+ endedAt + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ committeeId + SortOrder + + No +
+ videoViewUrl + SortOrder + + No +
+ agendaViewUrl + SortOrder + + No +
+ videoId + SortOrder + + No +
+ audioId + SortOrder + + No +
+ agendaId + SortOrder + + No +
+
+
+
+

MeetingRecordMinOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ name + SortOrder + + No +
+ startedAt + SortOrder + + No +
+ endedAt + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ committeeId + SortOrder + + No +
+ videoViewUrl + SortOrder + + No +
+ agendaViewUrl + SortOrder + + No +
+ videoId + SortOrder + + No +
+ audioId + SortOrder + + No +
+ agendaId + SortOrder + + No +
+
+
+
+

StringNullableWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput | Null + + Yes +
+ in + String | ListStringFieldRefInput | Null + + Yes +
+ notIn + String | ListStringFieldRefInput | Null + + Yes +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ mode + QueryMode + + No +
+ not + String | NestedStringNullableWithAggregatesFilter | Null + + Yes +
+ _count + NestedIntNullableFilter + + No +
+ _min + NestedStringNullableFilter + + No +
+ _max + NestedStringNullableFilter + + No +
+
+
+
+

JsonWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Json | JsonFieldRefInput | JsonNullValueFilter + + No +
+ path + String + + No +
+ mode + QueryMode | EnumQueryModeFieldRefInput + + No +
+ string_contains + String | StringFieldRefInput + + No +
+ string_starts_with + String | StringFieldRefInput + + No +
+ string_ends_with + String | StringFieldRefInput + + No +
+ array_starts_with + Json | JsonFieldRefInput | Null + + Yes +
+ array_ends_with + Json | JsonFieldRefInput | Null + + Yes +
+ array_contains + Json | JsonFieldRefInput | Null + + Yes +
+ lt + Json | JsonFieldRefInput + + No +
+ lte + Json | JsonFieldRefInput + + No +
+ gt + Json | JsonFieldRefInput + + No +
+ gte + Json | JsonFieldRefInput + + No +
+ not + Json | JsonFieldRefInput | JsonNullValueFilter + + No +
+ _count + NestedIntFilter + + No +
+ _min + NestedJsonFilter + + No +
+ _max + NestedJsonFilter + + No +
+
+
+
+

MeetingRecordCreateNestedManyWithoutCommitteeInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + MeetingRecordCreateWithoutCommitteeInput | MeetingRecordCreateWithoutCommitteeInput[] | MeetingRecordUncheckedCreateWithoutCommitteeInput | MeetingRecordUncheckedCreateWithoutCommitteeInput[] + + No +
+ connectOrCreate + MeetingRecordCreateOrConnectWithoutCommitteeInput | MeetingRecordCreateOrConnectWithoutCommitteeInput[] + + No +
+ createMany + MeetingRecordCreateManyCommitteeInputEnvelope + + No +
+ connect + MeetingRecordWhereUniqueInput | MeetingRecordWhereUniqueInput[] + + No +
+
+
+
+

MeetingRecordUncheckedCreateNestedManyWithoutCommitteeInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + MeetingRecordCreateWithoutCommitteeInput | MeetingRecordCreateWithoutCommitteeInput[] | MeetingRecordUncheckedCreateWithoutCommitteeInput | MeetingRecordUncheckedCreateWithoutCommitteeInput[] + + No +
+ connectOrCreate + MeetingRecordCreateOrConnectWithoutCommitteeInput | MeetingRecordCreateOrConnectWithoutCommitteeInput[] + + No +
+ createMany + MeetingRecordCreateManyCommitteeInputEnvelope + + No +
+ connect + MeetingRecordWhereUniqueInput | MeetingRecordWhereUniqueInput[] + + No +
+
+
+
+

StringFieldUpdateOperationsInput

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ set + String + + No +
+
+
+
+

DateTimeFieldUpdateOperationsInput

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ set + DateTime + + No +
+
+
+
+

MeetingRecordUpdateManyWithoutCommitteeNestedInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + MeetingRecordCreateWithoutCommitteeInput | MeetingRecordCreateWithoutCommitteeInput[] | MeetingRecordUncheckedCreateWithoutCommitteeInput | MeetingRecordUncheckedCreateWithoutCommitteeInput[] + + No +
+ connectOrCreate + MeetingRecordCreateOrConnectWithoutCommitteeInput | MeetingRecordCreateOrConnectWithoutCommitteeInput[] + + No +
+ upsert + MeetingRecordUpsertWithWhereUniqueWithoutCommitteeInput | MeetingRecordUpsertWithWhereUniqueWithoutCommitteeInput[] + + No +
+ createMany + MeetingRecordCreateManyCommitteeInputEnvelope + + No +
+ set + MeetingRecordWhereUniqueInput | MeetingRecordWhereUniqueInput[] + + No +
+ disconnect + MeetingRecordWhereUniqueInput | MeetingRecordWhereUniqueInput[] + + No +
+ delete + MeetingRecordWhereUniqueInput | MeetingRecordWhereUniqueInput[] + + No +
+ connect + MeetingRecordWhereUniqueInput | MeetingRecordWhereUniqueInput[] + + No +
+ update + MeetingRecordUpdateWithWhereUniqueWithoutCommitteeInput | MeetingRecordUpdateWithWhereUniqueWithoutCommitteeInput[] + + No +
+ updateMany + MeetingRecordUpdateManyWithWhereWithoutCommitteeInput | MeetingRecordUpdateManyWithWhereWithoutCommitteeInput[] + + No +
+ deleteMany + MeetingRecordScalarWhereInput | MeetingRecordScalarWhereInput[] + + No +
+
+
+
+

MeetingRecordUncheckedUpdateManyWithoutCommitteeNestedInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + MeetingRecordCreateWithoutCommitteeInput | MeetingRecordCreateWithoutCommitteeInput[] | MeetingRecordUncheckedCreateWithoutCommitteeInput | MeetingRecordUncheckedCreateWithoutCommitteeInput[] + + No +
+ connectOrCreate + MeetingRecordCreateOrConnectWithoutCommitteeInput | MeetingRecordCreateOrConnectWithoutCommitteeInput[] + + No +
+ upsert + MeetingRecordUpsertWithWhereUniqueWithoutCommitteeInput | MeetingRecordUpsertWithWhereUniqueWithoutCommitteeInput[] + + No +
+ createMany + MeetingRecordCreateManyCommitteeInputEnvelope + + No +
+ set + MeetingRecordWhereUniqueInput | MeetingRecordWhereUniqueInput[] + + No +
+ disconnect + MeetingRecordWhereUniqueInput | MeetingRecordWhereUniqueInput[] + + No +
+ delete + MeetingRecordWhereUniqueInput | MeetingRecordWhereUniqueInput[] + + No +
+ connect + MeetingRecordWhereUniqueInput | MeetingRecordWhereUniqueInput[] + + No +
+ update + MeetingRecordUpdateWithWhereUniqueWithoutCommitteeInput | MeetingRecordUpdateWithWhereUniqueWithoutCommitteeInput[] + + No +
+ updateMany + MeetingRecordUpdateManyWithWhereWithoutCommitteeInput | MeetingRecordUpdateManyWithWhereWithoutCommitteeInput[] + + No +
+ deleteMany + MeetingRecordScalarWhereInput | MeetingRecordScalarWhereInput[] + + No +
+
+
+
+

CommitteeCreateNestedOneWithoutMeetingRecordsInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + CommitteeCreateWithoutMeetingRecordsInput | CommitteeUncheckedCreateWithoutMeetingRecordsInput + + No +
+ connectOrCreate + CommitteeCreateOrConnectWithoutMeetingRecordsInput + + No +
+ connect + CommitteeWhereUniqueInput + + No +
+
+
+
+

NullableStringFieldUpdateOperationsInput

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ set + String | Null + + Yes +
+
+
+
+

CommitteeUpdateOneRequiredWithoutMeetingRecordsNestedInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + CommitteeCreateWithoutMeetingRecordsInput | CommitteeUncheckedCreateWithoutMeetingRecordsInput + + No +
+ connectOrCreate + CommitteeCreateOrConnectWithoutMeetingRecordsInput + + No +
+ upsert + CommitteeUpsertWithoutMeetingRecordsInput + + No +
+ connect + CommitteeWhereUniqueInput + + No +
+ update + CommitteeUpdateToOneWithWhereWithoutMeetingRecordsInput | CommitteeUpdateWithoutMeetingRecordsInput | CommitteeUncheckedUpdateWithoutMeetingRecordsInput + + No +
+
+
+
+

NestedStringFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput + + No +
+ in + String | ListStringFieldRefInput + + No +
+ notIn + String | ListStringFieldRefInput + + No +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ not + String | NestedStringFilter + + No +
+
+
+
+

NestedDateTimeFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + DateTime | DateTimeFieldRefInput + + No +
+ in + DateTime | ListDateTimeFieldRefInput + + No +
+ notIn + DateTime | ListDateTimeFieldRefInput + + No +
+ lt + DateTime | DateTimeFieldRefInput + + No +
+ lte + DateTime | DateTimeFieldRefInput + + No +
+ gt + DateTime | DateTimeFieldRefInput + + No +
+ gte + DateTime | DateTimeFieldRefInput + + No +
+ not + DateTime | NestedDateTimeFilter + + No +
+
+
+
+

NestedStringWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput + + No +
+ in + String | ListStringFieldRefInput + + No +
+ notIn + String | ListStringFieldRefInput + + No +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ not + String | NestedStringWithAggregatesFilter + + No +
+ _count + NestedIntFilter + + No +
+ _min + NestedStringFilter + + No +
+ _max + NestedStringFilter + + No +
+
+
+
+

NestedIntFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Int | IntFieldRefInput + + No +
+ in + Int | ListIntFieldRefInput + + No +
+ notIn + Int | ListIntFieldRefInput + + No +
+ lt + Int | IntFieldRefInput + + No +
+ lte + Int | IntFieldRefInput + + No +
+ gt + Int | IntFieldRefInput + + No +
+ gte + Int | IntFieldRefInput + + No +
+ not + Int | NestedIntFilter + + No +
+
+
+
+

NestedDateTimeWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + DateTime | DateTimeFieldRefInput + + No +
+ in + DateTime | ListDateTimeFieldRefInput + + No +
+ notIn + DateTime | ListDateTimeFieldRefInput + + No +
+ lt + DateTime | DateTimeFieldRefInput + + No +
+ lte + DateTime | DateTimeFieldRefInput + + No +
+ gt + DateTime | DateTimeFieldRefInput + + No +
+ gte + DateTime | DateTimeFieldRefInput + + No +
+ not + DateTime | NestedDateTimeWithAggregatesFilter + + No +
+ _count + NestedIntFilter + + No +
+ _min + NestedDateTimeFilter + + No +
+ _max + NestedDateTimeFilter + + No +
+
+
+
+

NestedStringNullableFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput | Null + + Yes +
+ in + String | ListStringFieldRefInput | Null + + Yes +
+ notIn + String | ListStringFieldRefInput | Null + + Yes +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ not + String | NestedStringNullableFilter | Null + + Yes +
+
+
+
+

NestedStringNullableWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput | Null + + Yes +
+ in + String | ListStringFieldRefInput | Null + + Yes +
+ notIn + String | ListStringFieldRefInput | Null + + Yes +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ not + String | NestedStringNullableWithAggregatesFilter | Null + + Yes +
+ _count + NestedIntNullableFilter + + No +
+ _min + NestedStringNullableFilter + + No +
+ _max + NestedStringNullableFilter + + No +
+
+
+
+

NestedIntNullableFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Int | IntFieldRefInput | Null + + Yes +
+ in + Int | ListIntFieldRefInput | Null + + Yes +
+ notIn + Int | ListIntFieldRefInput | Null + + Yes +
+ lt + Int | IntFieldRefInput + + No +
+ lte + Int | IntFieldRefInput + + No +
+ gt + Int | IntFieldRefInput + + No +
+ gte + Int | IntFieldRefInput + + No +
+ not + Int | NestedIntNullableFilter | Null + + Yes +
+
+
+
+

NestedJsonFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Json | JsonFieldRefInput | JsonNullValueFilter + + No +
+ path + String + + No +
+ mode + QueryMode | EnumQueryModeFieldRefInput + + No +
+ string_contains + String | StringFieldRefInput + + No +
+ string_starts_with + String | StringFieldRefInput + + No +
+ string_ends_with + String | StringFieldRefInput + + No +
+ array_starts_with + Json | JsonFieldRefInput | Null + + Yes +
+ array_ends_with + Json | JsonFieldRefInput | Null + + Yes +
+ array_contains + Json | JsonFieldRefInput | Null + + Yes +
+ lt + Json | JsonFieldRefInput + + No +
+ lte + Json | JsonFieldRefInput + + No +
+ gt + Json | JsonFieldRefInput + + No +
+ gte + Json | JsonFieldRefInput + + No +
+ not + Json | JsonFieldRefInput | JsonNullValueFilter + + No +
+
+
+
+

MeetingRecordCreateWithoutCommitteeInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ name + String + + No +
+ startedAt + DateTime + + No +
+ endedAt + DateTime + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ videoViewUrl + String | Null + + Yes +
+ agendaViewUrl + String | Null + + Yes +
+ rawJson + JsonNullValueInput | Json + + No +
+ videoId + String | Null + + Yes +
+ audioId + String | Null + + Yes +
+ agendaId + String | Null + + Yes +
+
+
+
+

MeetingRecordUncheckedCreateWithoutCommitteeInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ name + String + + No +
+ startedAt + DateTime + + No +
+ endedAt + DateTime + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ videoViewUrl + String | Null + + Yes +
+ agendaViewUrl + String | Null + + Yes +
+ rawJson + JsonNullValueInput | Json + + No +
+ videoId + String | Null + + Yes +
+ audioId + String | Null + + Yes +
+ agendaId + String | Null + + Yes +
+
+
+
+

MeetingRecordCreateOrConnectWithoutCommitteeInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + MeetingRecordWhereUniqueInput + + No +
+ create + MeetingRecordCreateWithoutCommitteeInput | MeetingRecordUncheckedCreateWithoutCommitteeInput + + No +
+
+
+
+

MeetingRecordCreateManyCommitteeInputEnvelope

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ data + MeetingRecordCreateManyCommitteeInput | MeetingRecordCreateManyCommitteeInput[] + + No +
+ skipDuplicates + Boolean + + No +
+
+
+
+

MeetingRecordUpsertWithWhereUniqueWithoutCommitteeInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + MeetingRecordWhereUniqueInput + + No +
+ update + MeetingRecordUpdateWithoutCommitteeInput | MeetingRecordUncheckedUpdateWithoutCommitteeInput + + No +
+ create + MeetingRecordCreateWithoutCommitteeInput | MeetingRecordUncheckedCreateWithoutCommitteeInput + + No +
+
+
+
+

MeetingRecordUpdateWithWhereUniqueWithoutCommitteeInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + MeetingRecordWhereUniqueInput + + No +
+ data + MeetingRecordUpdateWithoutCommitteeInput | MeetingRecordUncheckedUpdateWithoutCommitteeInput + + No +
+
+
+
+

MeetingRecordUpdateManyWithWhereWithoutCommitteeInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + MeetingRecordScalarWhereInput + + No +
+ data + MeetingRecordUpdateManyMutationInput | MeetingRecordUncheckedUpdateManyWithoutCommitteeInput + + No +
+
+
+
+

MeetingRecordScalarWhereInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ AND + MeetingRecordScalarWhereInput | MeetingRecordScalarWhereInput[] + + No +
+ OR + MeetingRecordScalarWhereInput[] + + No +
+ NOT + MeetingRecordScalarWhereInput | MeetingRecordScalarWhereInput[] + + No +
+ id + StringFilter | String + + No +
+ name + StringFilter | String + + No +
+ startedAt + DateTimeFilter | DateTime + + No +
+ endedAt + DateTimeFilter | DateTime + + No +
+ createdAt + DateTimeFilter | DateTime + + No +
+ updatedAt + DateTimeFilter | DateTime + + No +
+ committeeId + StringFilter | String + + No +
+ videoViewUrl + StringNullableFilter | String | Null + + Yes +
+ agendaViewUrl + StringNullableFilter | String | Null + + Yes +
+ rawJson + JsonFilter + + No +
+ videoId + StringNullableFilter | String | Null + + Yes +
+ audioId + StringNullableFilter | String | Null + + Yes +
+ agendaId + StringNullableFilter | String | Null + + Yes +
+
+
+
+

CommitteeCreateWithoutMeetingRecordsInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ name + String + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+
+
+
+

CommitteeUncheckedCreateWithoutMeetingRecordsInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ name + String + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+
+
+
+

CommitteeCreateOrConnectWithoutMeetingRecordsInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + CommitteeWhereUniqueInput + + No +
+ create + CommitteeCreateWithoutMeetingRecordsInput | CommitteeUncheckedCreateWithoutMeetingRecordsInput + + No +
+
+
+
+

CommitteeUpsertWithoutMeetingRecordsInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ update + CommitteeUpdateWithoutMeetingRecordsInput | CommitteeUncheckedUpdateWithoutMeetingRecordsInput + + No +
+ create + CommitteeCreateWithoutMeetingRecordsInput | CommitteeUncheckedCreateWithoutMeetingRecordsInput + + No +
+ where + CommitteeWhereInput + + No +
+
+
+
+

CommitteeUpdateToOneWithWhereWithoutMeetingRecordsInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + CommitteeWhereInput + + No +
+ data + CommitteeUpdateWithoutMeetingRecordsInput | CommitteeUncheckedUpdateWithoutMeetingRecordsInput + + No +
+
+
+
+

CommitteeUpdateWithoutMeetingRecordsInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ name + String | StringFieldUpdateOperationsInput + + No +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+
+
+
+

CommitteeUncheckedUpdateWithoutMeetingRecordsInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ name + String | StringFieldUpdateOperationsInput + + No +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+
+
+
+

MeetingRecordCreateManyCommitteeInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ name + String + + No +
+ startedAt + DateTime + + No +
+ endedAt + DateTime + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ videoViewUrl + String | Null + + Yes +
+ agendaViewUrl + String | Null + + Yes +
+ rawJson + JsonNullValueInput | Json + + No +
+ videoId + String | Null + + Yes +
+ audioId + String | Null + + Yes +
+ agendaId + String | Null + + Yes +
+
+
+
+

MeetingRecordUpdateWithoutCommitteeInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ name + String | StringFieldUpdateOperationsInput + + No +
+ startedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ endedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ videoViewUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ agendaViewUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ rawJson + JsonNullValueInput | Json + + No +
+ videoId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ audioId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ agendaId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

MeetingRecordUncheckedUpdateWithoutCommitteeInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ name + String | StringFieldUpdateOperationsInput + + No +
+ startedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ endedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ videoViewUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ agendaViewUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ rawJson + JsonNullValueInput | Json + + No +
+ videoId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ audioId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ agendaId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

MeetingRecordUncheckedUpdateManyWithoutCommitteeInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ name + String | StringFieldUpdateOperationsInput + + No +
+ startedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ endedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ videoViewUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ agendaViewUrl + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ rawJson + JsonNullValueInput | Json + + No +
+ videoId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ audioId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ agendaId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+
+ +
+
+
+

Output Types

+
+ +
+

Committee

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ name + String + + Yes +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ meetingRecords + MeetingRecord[] + + No +
+ _count + CommitteeCountOutputType + + Yes +
+
+
+
+

MeetingRecord

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ name + String + + Yes +
+ startedAt + DateTime + + Yes +
+ endedAt + DateTime + + Yes +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ committeeId + String + + Yes +
+ videoViewUrl + String + + No +
+ agendaViewUrl + String + + No +
+ rawJson + Json + + Yes +
+ videoId + String + + No +
+ audioId + String + + No +
+ agendaId + String + + No +
+ committee + Committee + + Yes +
+
+
+
+

CreateManyCommitteeAndReturnOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ name + String + + Yes +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+
+
+
+

UpdateManyCommitteeAndReturnOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ name + String + + Yes +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+
+
+
+

CreateManyMeetingRecordAndReturnOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ name + String + + Yes +
+ startedAt + DateTime + + Yes +
+ endedAt + DateTime + + Yes +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ committeeId + String + + Yes +
+ videoViewUrl + String + + No +
+ agendaViewUrl + String + + No +
+ rawJson + Json + + Yes +
+ videoId + String + + No +
+ audioId + String + + No +
+ agendaId + String + + No +
+ committee + Committee + + Yes +
+
+
+
+

UpdateManyMeetingRecordAndReturnOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ name + String + + Yes +
+ startedAt + DateTime + + Yes +
+ endedAt + DateTime + + Yes +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ committeeId + String + + Yes +
+ videoViewUrl + String + + No +
+ agendaViewUrl + String + + No +
+ rawJson + Json + + Yes +
+ videoId + String + + No +
+ audioId + String + + No +
+ agendaId + String + + No +
+ committee + Committee + + Yes +
+
+
+
+

AggregateCommittee

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ _count + CommitteeCountAggregateOutputType + + No +
+ _min + CommitteeMinAggregateOutputType + + No +
+ _max + CommitteeMaxAggregateOutputType + + No +
+
+
+
+

CommitteeGroupByOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ name + String + + Yes +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ _count + CommitteeCountAggregateOutputType + + No +
+ _min + CommitteeMinAggregateOutputType + + No +
+ _max + CommitteeMaxAggregateOutputType + + No +
+
+
+
+

AggregateMeetingRecord

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ _count + MeetingRecordCountAggregateOutputType + + No +
+ _min + MeetingRecordMinAggregateOutputType + + No +
+ _max + MeetingRecordMaxAggregateOutputType + + No +
+
+
+
+

MeetingRecordGroupByOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ name + String + + Yes +
+ startedAt + DateTime + + Yes +
+ endedAt + DateTime + + Yes +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ committeeId + String + + Yes +
+ videoViewUrl + String + + No +
+ agendaViewUrl + String + + No +
+ rawJson + Json + + Yes +
+ videoId + String + + No +
+ audioId + String + + No +
+ agendaId + String + + No +
+ _count + MeetingRecordCountAggregateOutputType + + No +
+ _min + MeetingRecordMinAggregateOutputType + + No +
+ _max + MeetingRecordMaxAggregateOutputType + + No +
+
+
+
+

AffectedRowsOutput

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ count + Int + + Yes +
+
+
+
+

CommitteeCountOutputType

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ meetingRecords + Int + + Yes +
+
+
+
+

CommitteeCountAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + Int + + Yes +
+ name + Int + + Yes +
+ createdAt + Int + + Yes +
+ updatedAt + Int + + Yes +
+ _all + Int + + Yes +
+
+
+
+

CommitteeMinAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ name + String + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+
+
+
+

CommitteeMaxAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ name + String + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+
+
+
+

MeetingRecordCountAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + Int + + Yes +
+ name + Int + + Yes +
+ startedAt + Int + + Yes +
+ endedAt + Int + + Yes +
+ createdAt + Int + + Yes +
+ updatedAt + Int + + Yes +
+ committeeId + Int + + Yes +
+ videoViewUrl + Int + + Yes +
+ agendaViewUrl + Int + + Yes +
+ rawJson + Int + + Yes +
+ videoId + Int + + Yes +
+ audioId + Int + + Yes +
+ agendaId + Int + + Yes +
+ _all + Int + + Yes +
+
+
+
+

MeetingRecordMinAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ name + String + + No +
+ startedAt + DateTime + + No +
+ endedAt + DateTime + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ committeeId + String + + No +
+ videoViewUrl + String + + No +
+ agendaViewUrl + String + + No +
+ videoId + String + + No +
+ audioId + String + + No +
+ agendaId + String + + No +
+
+
+
+

MeetingRecordMaxAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ name + String + + No +
+ startedAt + DateTime + + No +
+ endedAt + DateTime + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ committeeId + String + + No +
+ videoViewUrl + String + + No +
+ agendaViewUrl + String + + No +
+ videoId + String + + No +
+ audioId + String + + No +
+ agendaId + String + + No +
+
+ +
+
+
+
+ +
+
+
+
+ + diff --git a/services/tgov/db/docs/styles/main.css b/services/tgov/db/docs/styles/main.css new file mode 100644 index 0000000..78f97c8 --- /dev/null +++ b/services/tgov/db/docs/styles/main.css @@ -0,0 +1 @@ +/*! tailwindcss v3.2.6 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}html{-webkit-text-size-adjust:100%;font-feature-settings:normal;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]{display:none}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.sticky{position:sticky}.top-0{top:0}.my-16{margin-bottom:4rem;margin-top:4rem}.my-4{margin-bottom:1rem;margin-top:1rem}.my-8{margin-bottom:2rem;margin-top:2rem}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-4{margin-left:1rem}.mr-4{margin-right:1rem}.mt-1{margin-top:.25rem}.mt-12{margin-top:3rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.flex{display:flex}.table{display:table}.h-screen{height:100vh}.min-h-screen{min-height:100vh}.w-1\/5{width:20%}.w-full{width:100%}.flex-shrink-0{flex-shrink:0}.table-auto{table-layout:auto}.overflow-auto{overflow:auto}.overflow-x-hidden{overflow-x:hidden}.border{border-width:1px}.border-l-2{border-left-width:2px}.border-gray-400{--tw-border-opacity:1;border-color:rgb(156 163 175/var(--tw-border-opacity))}.bg-gray-200{--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.p-4{padding:1rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.pl-3{padding-left:.75rem}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-lg{font-size:1.125rem}.text-lg,.text-xl{line-height:1.75rem}.text-xl{font-size:1.25rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity))}.text-gray-800{--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity))}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}body{--code-inner-color:#718096;--code-token1-color:#d5408c;--code-token2-color:#805ad5;--code-token3-color:#319795;--code-token4-color:#dd6b21;--code-token5-color:#690;--code-token6-color:#9a6e3a;--code-token7-color:#e90;--code-linenum-color:#cbd5e0;--code-added-color:#47bb78;--code-added-bg-color:#d9f4e6;--code-deleted-color:#e53e3e;--code-deleted-bg-color:#f5e4e7;--code-highlight-color:#a0aec0;--code-highlight-bg-color:#e2e8f0;--code-result-bg-color:#e7edf3;--main-font-color:#1a202c;--border-color:#e2e8f0;--code-bgd-color:#f6f8fa}code[class*=language-],pre[class*=language-],pre[class*=language-] code{word-wrap:normal;border-radius:8px;color:var(--main-font-color)!important;display:block;font-family:Roboto Mono,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:14px;font-variant:no-common-ligatures no-discretionary-ligatures no-historical-ligatures no-contextual;grid-template-rows:max-content;-webkit-hyphens:none;hyphens:none;line-height:1.5;overflow:auto;-moz-tab-size:4;-o-tab-size:4;tab-size:4;text-align:left;white-space:pre;width:100%;word-break:normal;word-spacing:normal}pre[class*=language-]{border-radius:1em;margin:0;overflow:auto;padding:1em}:not(pre)>code[class*=language-],pre[class*=language-]{background:var(--code-bgd-color)!important}:not(pre)>code[class*=language-]{border-radius:.3em;padding:.1em;white-space:normal}.inline-code,code.inline-code{font-feature-settings:"clig" 0,"calt" 0;background:var(--code-inline-bgd-color);border-radius:5px;color:var(--main-font-color);display:inline;font-family:Roboto Mono;font-size:14px;font-style:normal;font-variant:no-common-ligatures no-discretionary-ligatures no-historical-ligatures no-contextual;font-weight:500;line-height:24px;padding:.05em .3em .2em;vertical-align:baseline}.inline-code{background-color:var(--border-color)}.top-section h1 inlinecode{font-size:2rem}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:var(--code-inner-color)!important;font-style:normal!important}.token.namespace{opacity:.7}.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag,.token.type-args{color:var(--code-token4-color)!important}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:var(--code-token5-color)!important}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:var(--code-token6-color)!important}.token.atrule,.token.attr-value,.token.keyword{color:var(--code-token1-color)!important}.token.boolean,.token.class-name,.token.function,.token[class*=class-name]{color:var(--code-token2-color)!important}.token.important,.token.regex,.token.variable{color:var(--code-token7-color)!important}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.annotation{color:var(--code-token3-color)!important} \ No newline at end of file diff --git a/tgov/data/index.ts b/services/tgov/db/index.ts similarity index 79% rename from tgov/data/index.ts rename to services/tgov/db/index.ts index 835fe6c..50f65a7 100644 --- a/tgov/data/index.ts +++ b/services/tgov/db/index.ts @@ -1,5 +1,8 @@ +import { Prisma, PrismaClient } from "@prisma/client/tgov/index.js"; + import { SQLDatabase } from "encore.dev/storage/sqldb"; -import { PrismaClient } from "@prisma/client/tgov/index.js"; + +export { Prisma }; // Define the database connection const psql = new SQLDatabase("tgov", { diff --git a/tgov/data/migrations/20250312051656_init/migration.sql b/services/tgov/db/migrations/20250312051656_init/migration.sql similarity index 100% rename from tgov/data/migrations/20250312051656_init/migration.sql rename to services/tgov/db/migrations/20250312051656_init/migration.sql diff --git a/documents/data/migrations/migration_lock.toml b/services/tgov/db/migrations/migration_lock.toml similarity index 100% rename from documents/data/migrations/migration_lock.toml rename to services/tgov/db/migrations/migration_lock.toml diff --git a/services/tgov/db/models/db.ts b/services/tgov/db/models/db.ts new file mode 100644 index 0000000..0a8fa6a --- /dev/null +++ b/services/tgov/db/models/db.ts @@ -0,0 +1,35 @@ +// DO NOT EDIT — Auto-generated file; see https://github.com/mogzol/prisma-generator-typescript-interfaces + +export type CommitteeModel = { + id: string; + name: string; + createdAt: Date; + updatedAt: Date; + meetingRecords?: MeetingRecordModel[]; +}; + +export type MeetingRecordModel = { + id: string; + name: string; + startedAt: Date; + endedAt: Date; + createdAt: Date; + updatedAt: Date; + committeeId: string; + videoViewUrl: string | null; + agendaViewUrl: string | null; + rawJson: JsonValue; + videoId: string | null; + audioId: string | null; + agendaId: string | null; + committee?: CommitteeModel; +}; + +type JsonValue = + | string + | number + | boolean + | { [key in string]: JsonValue } + | {} + | Array + | null; diff --git a/services/tgov/db/models/dto.ts b/services/tgov/db/models/dto.ts new file mode 100644 index 0000000..5e7c5d9 --- /dev/null +++ b/services/tgov/db/models/dto.ts @@ -0,0 +1,31 @@ +export type CommitteeDto = { + id: string; + name: string; + createdAt: string; + updatedAt: string; +}; + +export type MeetingRecordDto = { + id: string; + name: string; + startedAt: string; + endedAt: string; + createdAt: string; + updatedAt: string; + committeeId: string; + videoViewUrl: string | null; + agendaViewUrl: string | null; + rawJson: JsonValue; + videoId: string | null; + audioId: string | null; + agendaId: string | null; +}; + +type JsonValue = + | string + | number + | boolean + | { [key in string]: JsonValue } + | {} + | Array + | null; diff --git a/services/tgov/db/models/index.ts b/services/tgov/db/models/index.ts new file mode 100644 index 0000000..58a42ce --- /dev/null +++ b/services/tgov/db/models/index.ts @@ -0,0 +1,12 @@ +import * as Db from "./db"; +import * as Dto from "./dto"; +import * as Json from "./json"; + +export { Json, Dto, Db }; +export default { Json, Dto, Db }; + +declare global { + namespace PrismaJson { + export type MeetingRawJSON = Json.MeetingRawJSON; + } +} diff --git a/services/tgov/db/models/json.ts b/services/tgov/db/models/json.ts new file mode 100644 index 0000000..b8ff954 --- /dev/null +++ b/services/tgov/db/models/json.ts @@ -0,0 +1 @@ +export * from "./json/MeetingRawJSON"; diff --git a/services/tgov/db/models/json/MeetingRawJSON.ts b/services/tgov/db/models/json/MeetingRawJSON.ts new file mode 100644 index 0000000..879ef82 --- /dev/null +++ b/services/tgov/db/models/json/MeetingRawJSON.ts @@ -0,0 +1,12 @@ +export type MeetingRawJSON = TGovIndexMeetingRawJSON; + +export type TGovIndexMeetingRawJSON = { + committee: string; + name: string; + date: string; + duration: string; + viewId: string; + clipId?: string; + agendaViewUrl: string | undefined; + videoViewUrl: string | undefined; +}; diff --git a/services/tgov/db/schema.prisma b/services/tgov/db/schema.prisma new file mode 100644 index 0000000..9be3e2c --- /dev/null +++ b/services/tgov/db/schema.prisma @@ -0,0 +1,91 @@ +// This is your Prisma schema file for this service, +// learn more about it in the docs: https://pris.ly/d/prisma-schema + +generator client { + provider = "prisma-client-js" + previewFeatures = ["driverAdapters", "metrics"] + binaryTargets = ["native", "debian-openssl-3.0.x"] + output = "../../node_modules/@prisma/client/tgov" +} + +generator json { + provider = "prisma-json-types-generator" + engineType = "library" + clientOutput = "../../node_modules/@prisma/client/tgov" +} + +generator docs { + provider = "node node_modules/prisma-docs-generator" + output = "./docs" +} + +generator markdown { + provider = "prisma-markdown" + output = "./docs/README.md" + title = "TGov Service Database Schema" +} + +generator typescriptInterfaces { + provider = "prisma-generator-typescript-interfaces" + modelType = "type" + enumType = "object" + headerComment = "DO NOT EDIT — Auto-generated file; see https://github.com/mogzol/prisma-generator-typescript-interfaces" + modelSuffix = "Model" + output = "./models/db.ts" + prettier = true +} + +generator typescriptInterfacesJson { + provider = "prisma-generator-typescript-interfaces" + modelType = "type" + enumType = "stringUnion" + enumPrefix = "$" + headerComment = "DO NOT EDIT — Auto-generated file; see https://github.com/mogzol/prisma-generator-typescript-interfaces" + output = "./models/dto.ts" + modelSuffix = "Dto" + dateType = "string" + bigIntType = "string" + decimalType = "string" + bytesType = "ArrayObject" + omitRelations = true + prettier = true +} + +datasource db { + provider = "postgresql" + url = env("TGOV_DATABASE_URL") +} + +/// Models related to TGov meeting data + +model Committee { + id String @id @default(ulid()) + name String @unique + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + meetingRecords MeetingRecord[] +} + +model MeetingRecord { + id String @id @default(ulid()) + name String @unique + startedAt DateTime @db.Timestamptz(6) + endedAt DateTime @db.Timestamptz(6) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + committeeId String + videoViewUrl String? + agendaViewUrl String? + + ///[MeetingRawJSON] + rawJson Json + + // Foreign keys to link with other services + videoId String? + audioId String? + agendaId String? + + committee Committee @relation(fields: [committeeId], references: [id]) + + @@unique([committeeId, startedAt]) +} diff --git a/tgov/encore.service.ts b/services/tgov/encore.service.ts similarity index 100% rename from tgov/encore.service.ts rename to services/tgov/encore.service.ts diff --git a/services/tgov/index.ts b/services/tgov/index.ts new file mode 100644 index 0000000..78a3ae8 --- /dev/null +++ b/services/tgov/index.ts @@ -0,0 +1,261 @@ +import { normalizeDate, normalizeName } from "../scrapers/tgov/util"; +import { db, Prisma } from "./db"; +import { MeetingRecordModel } from "./db/models/db"; +import { TGovIndexMeetingRawJSON } from "./db/models/json"; + +import { scrapers } from "~encore/clients"; + +import { api, APIError, Query } from "encore.dev/api"; +import logger from "encore.dev/log"; + +type ListMeetingsParams = { + hasUnsavedAgenda?: Query; + committeeId?: Query; + beforeDate?: Query; + afterDate?: Query; + cursor?: Query; + prev?: Query; + next?: Query; + sort?: Query<"name" | "startedAt" | "committee">; + sortDirection?: Query<"asc" | "desc">; +}; + +/** + * Lists all meetings with optional filtering capabilities + */ +export const listMeetings = api( + { + auth: false, + expose: true, + method: "GET", + path: "/tgov/meetings", + }, + async ( + params: ListMeetingsParams, + ): Promise<{ meetings: MeetingRecordModel[]; total: number }> => { + try { + const where: Prisma.MeetingRecordWhereInput = {}; + const orderBy: Prisma.MeetingRecordOrderByWithRelationInput = {}; + + if (params.committeeId) where.committeeId = params.committeeId; + if (params.afterDate) where.startedAt = { gte: params.afterDate }; + + if (params.hasUnsavedAgenda === false) { + where.OR = [{ agendaViewUrl: null }, { agendaId: { not: null } }]; + } + + if (params.hasUnsavedAgenda === true) { + where.AND = [{ agendaViewUrl: { not: null } }, { agendaId: null }]; + } + + if (params.sort === "committee") { + orderBy.committee = { + name: (params.sortDirection || "asc") as "asc" | "desc", + }; + } else if (params.sort) { + orderBy[params.sort as "name" | "startedAt"] = (params.sortDirection || + "desc") as "asc" | "desc"; + } + + const [meetings, total] = await Promise.all([ + db.meetingRecord + .findMany({ + where, + include: { committee: true }, + orderBy: {}, + }) + .then((meetings) => + meetings.map((meeting) => ({ + ...meeting, + })), + ), + db.meetingRecord.count({ where }), + ]); + + logger.debug("Retrieved meetings", { + count: meetings.length, + total, + committeeId: params.committeeId || "all", + }); + + return { meetings, total }; + } catch (error) { + const err = error instanceof Error ? error : new Error(String(error)); + const msg = `Error while listing meetings: ${err.message}`; + logger.error(err, msg, params); + throw APIError.internal(msg, err); + } + }, +); + +/** + * Lists all committees + */ +export const listCommittees = api( + { + auth: false, + expose: true, + method: "GET", + path: "/tgov/committees", + }, + async (): Promise<{ + committees: Array<{ + id: string; + name: string; + }>; + }> => { + try { + const committees = await db.committee.findMany({ + orderBy: { name: "asc" }, + }); + + logger.debug("Retrieved committees", { count: committees.length }); + + return { + committees: committees.map((committee) => ({ + id: committee.id, + name: committee.name, + })), + }; + } catch (error) { + logger.error("Failed to list committees", { + error: error instanceof Error ? error.message : String(error), + }); + throw APIError.internal("Failed to list committees"); + } + }, +); + +export const pull = api( + { + method: "POST", + expose: true, + auth: false, + path: "/tgov/pull", + }, + async () => { + const { data } = await scrapers.scrapeTGovIndex(); + const groups = Map.groupBy(data, (d) => normalizeName(d.committee)); + + for (const committeeName of groups.keys()) { + // Create or update the committee record + const committee = await db.committee.upsert({ + where: { name: committeeName }, + update: {}, + create: { name: committeeName }, + }); + + //TODO There isn't much consistency or convention in how things are named + // Process each meeting for this committee + for (const rawJson of groups.get(committeeName) || []) { + const { startedAt, endedAt } = normalizeDate(rawJson); + const name = normalizeName(`${rawJson.name}__${rawJson.date}`); + + // Create or update the meeting record + await db.meetingRecord.upsert({ + where: { + committeeId_startedAt: { + committeeId: committee.id, + startedAt, + }, + }, + update: {}, + create: { + name, + rawJson, + startedAt, + endedAt, + videoViewUrl: rawJson.videoViewUrl, + agendaViewUrl: rawJson.agendaViewUrl, + committee: { connect: committee }, + }, + }); + } + } + }, +); + +/** + * Get a single meeting by ID with all related details + */ +export const getMeeting = api( + { + auth: false, + expose: true, + method: "GET", + path: "/tgov/meetings/:id", + }, + async (params: { + id: string; + }): Promise<{ + meeting: { + id: string; + name: string; + startedAt: Date; + endedAt: Date; + committee: { id: string; name: string }; + videoViewUrl?: string; + agendaViewUrl?: string; + videoId?: string; + audioId?: string; + agendaId?: string; + rawJson: TGovIndexMeetingRawJSON; + createdAt: Date; + updatedAt: Date; + }; + }> => { + const { id } = params; + + try { + // Get the meeting with its committee relation + const meeting = await db.meetingRecord.findUnique({ + where: { id }, + include: { + committee: true, + }, + }); + + if (!meeting) { + logger.info("Meeting not found", { meetingId: id }); + throw APIError.notFound(`Meeting with ID ${id} not found`); + } + + logger.debug("Retrieved meeting details", { + meetingId: id, + committeeName: meeting.committee.name, + }); + + return { + meeting: { + id: meeting.id, + name: meeting.name, + startedAt: meeting.startedAt, + endedAt: meeting.endedAt, + committee: { + id: meeting.committee.id, + name: meeting.committee.name, + }, + videoViewUrl: meeting.videoViewUrl || undefined, + agendaViewUrl: meeting.agendaViewUrl || undefined, + videoId: meeting.videoId || undefined, + audioId: meeting.audioId || undefined, + agendaId: meeting.agendaId || undefined, + rawJson: meeting.rawJson, + createdAt: meeting.createdAt, + updatedAt: meeting.updatedAt, + }, + }; + } catch (error) { + if (error instanceof APIError) { + throw error; // Rethrow API errors like NotFound + } + + logger.error("Failed to get meeting", { + meetingId: id, + error: error instanceof Error ? error.message : String(error), + }); + + throw APIError.internal(`Failed to get meeting details for ID ${id}`); + } + }, +); diff --git a/services/transcription/db/docs/README.md b/services/transcription/db/docs/README.md new file mode 100644 index 0000000..6ed566b --- /dev/null +++ b/services/transcription/db/docs/README.md @@ -0,0 +1,88 @@ +# Transcription Service Database Schema +> Generated by [`prisma-markdown`](https://github.com/samchon/prisma-markdown) + +- [default](#default) + +## default +```mermaid +erDiagram +"Transcription" { + String id PK + String text + String language "nullable" + String model + Float confidence "nullable" + Int processingTime "nullable" + String status + String error "nullable" + DateTime createdAt + DateTime updatedAt + String audioFileId + String meetingRecordId "nullable" +} +"TranscriptionSegment" { + String id PK + Int index + Float start + Float end + String text + Float confidence "nullable" + String transcriptionId FK +} +"TranscriptionJob" { + String id PK + String status + Int priority + String model + String language "nullable" + String error "nullable" + DateTime createdAt + DateTime updatedAt + String audioFileId + String meetingRecordId "nullable" + String transcriptionId "nullable" +} +"TranscriptionSegment" }o--|| "Transcription" : transcription +``` + +### `Transcription` + +**Properties** + - `id`: + - `text`: + - `language`: + - `model`: + - `confidence`: + - `processingTime`: + - `status`: + - `error`: + - `createdAt`: + - `updatedAt`: + - `audioFileId`: + - `meetingRecordId`: + +### `TranscriptionSegment` + +**Properties** + - `id`: + - `index`: + - `start`: + - `end`: + - `text`: + - `confidence`: + - `transcriptionId`: + +### `TranscriptionJob` + +**Properties** + - `id`: + - `status`: + - `priority`: + - `model`: + - `language`: + - `error`: + - `createdAt`: + - `updatedAt`: + - `audioFileId`: + - `meetingRecordId`: + - `transcriptionId`: \ No newline at end of file diff --git a/services/transcription/db/docs/index.html b/services/transcription/db/docs/index.html new file mode 100644 index 0000000..4e0b156 --- /dev/null +++ b/services/transcription/db/docs/index.html @@ -0,0 +1,20346 @@ + + + + + + + + Prisma Generated Docs + + + + +
+
+
+ + + + + + + + +
+ +
+
Models
+ +
Types
+ +
+ +
+
+ +
+

Models

+ +
+

Transcription

+ + +
+

Fields

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesRequiredComment
+ id + + String + +
    +
  • @id
  • @default(ulid())
  • +
+
+ Yes + + - +
+ text + + String + +
    +
  • -
  • +
+
+ Yes + + - +
+ language + + String? + +
    +
  • -
  • +
+
+ No + + - +
+ model + + String + +
    +
  • -
  • +
+
+ Yes + + - +
+ confidence + + Float? + +
    +
  • -
  • +
+
+ No + + - +
+ processingTime + + Int? + +
    +
  • -
  • +
+
+ No + + - +
+ status + + String + +
    +
  • -
  • +
+
+ Yes + + - +
+ error + + String? + +
    +
  • -
  • +
+
+ No + + - +
+ createdAt + + DateTime + +
    +
  • @default(now())
  • +
+
+ Yes + + - +
+ updatedAt + + DateTime + +
    +
  • @updatedAt
  • +
+
+ Yes + + - +
+ audioFileId + + String + +
    +
  • -
  • +
+
+ Yes + + - +
+ meetingRecordId + + String? + +
    +
  • -
  • +
+
+ No + + - +
+ segments + + TranscriptionSegment[] + +
    +
  • -
  • +
+
+ Yes + + - +
+
+
+
+
+

Operations

+
+ +
+

findUnique

+

Find zero or one Transcription

+
+
// Get one Transcription
+const transcription = await prisma.transcription.findUnique({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + TranscriptionWhereUniqueInput + + Yes +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

findFirst

+

Find first Transcription

+
+
// Get one Transcription
+const transcription = await prisma.transcription.findFirst({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + TranscriptionWhereInput + + No +
+ orderBy + + TranscriptionOrderByWithRelationInput[] | TranscriptionOrderByWithRelationInput + + No +
+ cursor + + TranscriptionWhereUniqueInput + + No +
+ take + + Int + + No +
+ skip + + Int + + No +
+ distinct + + TranscriptionScalarFieldEnum | TranscriptionScalarFieldEnum[] + + No +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

findMany

+

Find zero or more Transcription

+
+
// Get all Transcription
+const Transcription = await prisma.transcription.findMany()
+// Get first 10 Transcription
+const Transcription = await prisma.transcription.findMany({ take: 10 })
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + TranscriptionWhereInput + + No +
+ orderBy + + TranscriptionOrderByWithRelationInput[] | TranscriptionOrderByWithRelationInput + + No +
+ cursor + + TranscriptionWhereUniqueInput + + No +
+ take + + Int + + No +
+ skip + + Int + + No +
+ distinct + + TranscriptionScalarFieldEnum | TranscriptionScalarFieldEnum[] + + No +
+

Output

+ +
Required: + Yes
+
List: + Yes
+
+
+
+

create

+

Create one Transcription

+
+
// Create one Transcription
+const Transcription = await prisma.transcription.create({
+  data: {
+    // ... data to create a Transcription
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + TranscriptionCreateInput | TranscriptionUncheckedCreateInput + + Yes +
+

Output

+ +
Required: + Yes
+
List: + No
+
+
+
+

delete

+

Delete one Transcription

+
+
// Delete one Transcription
+const Transcription = await prisma.transcription.delete({
+  where: {
+    // ... filter to delete one Transcription
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + TranscriptionWhereUniqueInput + + Yes +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

update

+

Update one Transcription

+
+
// Update one Transcription
+const transcription = await prisma.transcription.update({
+  where: {
+    // ... provide filter here
+  },
+  data: {
+    // ... provide data here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + TranscriptionUpdateInput | TranscriptionUncheckedUpdateInput + + Yes +
+ where + + TranscriptionWhereUniqueInput + + Yes +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

deleteMany

+

Delete zero or more Transcription

+
+
// Delete a few Transcription
+const { count } = await prisma.transcription.deleteMany({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + TranscriptionWhereInput + + No +
+ limit + + Int + + No +
+

Output

+ +
Required: + Yes
+
List: + No
+
+
+
+

updateMany

+

Update zero or one Transcription

+
+
const { count } = await prisma.transcription.updateMany({
+  where: {
+    // ... provide filter here
+  },
+  data: {
+    // ... provide data here
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + TranscriptionUpdateManyMutationInput | TranscriptionUncheckedUpdateManyInput + + Yes +
+ where + + TranscriptionWhereInput + + No +
+ limit + + Int + + No +
+

Output

+ +
Required: + Yes
+
List: + No
+
+
+
+

upsert

+

Create or update one Transcription

+
+
// Update or create a Transcription
+const transcription = await prisma.transcription.upsert({
+  create: {
+    // ... data to create a Transcription
+  },
+  update: {
+    // ... in case it already exists, update
+  },
+  where: {
+    // ... the filter for the Transcription we want to update
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + TranscriptionWhereUniqueInput + + Yes +
+ create + + TranscriptionCreateInput | TranscriptionUncheckedCreateInput + + Yes +
+ update + + TranscriptionUpdateInput | TranscriptionUncheckedUpdateInput + + Yes +
+

Output

+ +
Required: + Yes
+
List: + No
+
+ +
+
+
+
+
+

TranscriptionSegment

+ + +
+

Fields

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesRequiredComment
+ id + + String + +
    +
  • @id
  • @default(ulid())
  • +
+
+ Yes + + - +
+ index + + Int + +
    +
  • -
  • +
+
+ Yes + + - +
+ start + + Float + +
    +
  • -
  • +
+
+ Yes + + - +
+ end + + Float + +
    +
  • -
  • +
+
+ Yes + + - +
+ text + + String + +
    +
  • -
  • +
+
+ Yes + + - +
+ confidence + + Float? + +
    +
  • -
  • +
+
+ No + + - +
+ transcriptionId + + String + +
    +
  • -
  • +
+
+ Yes + + - +
+ transcription + + Transcription + +
    +
  • -
  • +
+
+ Yes + + - +
+
+
+
+
+

Operations

+
+ +
+

findUnique

+

Find zero or one TranscriptionSegment

+
+
// Get one TranscriptionSegment
+const transcriptionSegment = await prisma.transcriptionSegment.findUnique({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + TranscriptionSegmentWhereUniqueInput + + Yes +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

findFirst

+

Find first TranscriptionSegment

+
+
// Get one TranscriptionSegment
+const transcriptionSegment = await prisma.transcriptionSegment.findFirst({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + TranscriptionSegmentWhereInput + + No +
+ orderBy + + TranscriptionSegmentOrderByWithRelationInput[] | TranscriptionSegmentOrderByWithRelationInput + + No +
+ cursor + + TranscriptionSegmentWhereUniqueInput + + No +
+ take + + Int + + No +
+ skip + + Int + + No +
+ distinct + + TranscriptionSegmentScalarFieldEnum | TranscriptionSegmentScalarFieldEnum[] + + No +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

findMany

+

Find zero or more TranscriptionSegment

+
+
// Get all TranscriptionSegment
+const TranscriptionSegment = await prisma.transcriptionSegment.findMany()
+// Get first 10 TranscriptionSegment
+const TranscriptionSegment = await prisma.transcriptionSegment.findMany({ take: 10 })
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + TranscriptionSegmentWhereInput + + No +
+ orderBy + + TranscriptionSegmentOrderByWithRelationInput[] | TranscriptionSegmentOrderByWithRelationInput + + No +
+ cursor + + TranscriptionSegmentWhereUniqueInput + + No +
+ take + + Int + + No +
+ skip + + Int + + No +
+ distinct + + TranscriptionSegmentScalarFieldEnum | TranscriptionSegmentScalarFieldEnum[] + + No +
+

Output

+ +
Required: + Yes
+
List: + Yes
+
+
+
+

create

+

Create one TranscriptionSegment

+
+
// Create one TranscriptionSegment
+const TranscriptionSegment = await prisma.transcriptionSegment.create({
+  data: {
+    // ... data to create a TranscriptionSegment
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + TranscriptionSegmentCreateInput | TranscriptionSegmentUncheckedCreateInput + + Yes +
+

Output

+ +
Required: + Yes
+
List: + No
+
+
+
+

delete

+

Delete one TranscriptionSegment

+
+
// Delete one TranscriptionSegment
+const TranscriptionSegment = await prisma.transcriptionSegment.delete({
+  where: {
+    // ... filter to delete one TranscriptionSegment
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + TranscriptionSegmentWhereUniqueInput + + Yes +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

update

+

Update one TranscriptionSegment

+
+
// Update one TranscriptionSegment
+const transcriptionSegment = await prisma.transcriptionSegment.update({
+  where: {
+    // ... provide filter here
+  },
+  data: {
+    // ... provide data here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + TranscriptionSegmentUpdateInput | TranscriptionSegmentUncheckedUpdateInput + + Yes +
+ where + + TranscriptionSegmentWhereUniqueInput + + Yes +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

deleteMany

+

Delete zero or more TranscriptionSegment

+
+
// Delete a few TranscriptionSegment
+const { count } = await prisma.transcriptionSegment.deleteMany({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + TranscriptionSegmentWhereInput + + No +
+ limit + + Int + + No +
+

Output

+ +
Required: + Yes
+
List: + No
+
+
+
+

updateMany

+

Update zero or one TranscriptionSegment

+
+
const { count } = await prisma.transcriptionSegment.updateMany({
+  where: {
+    // ... provide filter here
+  },
+  data: {
+    // ... provide data here
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + TranscriptionSegmentUpdateManyMutationInput | TranscriptionSegmentUncheckedUpdateManyInput + + Yes +
+ where + + TranscriptionSegmentWhereInput + + No +
+ limit + + Int + + No +
+

Output

+ +
Required: + Yes
+
List: + No
+
+
+
+

upsert

+

Create or update one TranscriptionSegment

+
+
// Update or create a TranscriptionSegment
+const transcriptionSegment = await prisma.transcriptionSegment.upsert({
+  create: {
+    // ... data to create a TranscriptionSegment
+  },
+  update: {
+    // ... in case it already exists, update
+  },
+  where: {
+    // ... the filter for the TranscriptionSegment we want to update
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + TranscriptionSegmentWhereUniqueInput + + Yes +
+ create + + TranscriptionSegmentCreateInput | TranscriptionSegmentUncheckedCreateInput + + Yes +
+ update + + TranscriptionSegmentUpdateInput | TranscriptionSegmentUncheckedUpdateInput + + Yes +
+

Output

+ +
Required: + Yes
+
List: + No
+
+ +
+
+
+
+
+

TranscriptionJob

+ + +
+

Fields

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesRequiredComment
+ id + + String + +
    +
  • @id
  • @default(ulid())
  • +
+
+ Yes + + - +
+ status + + String + +
    +
  • -
  • +
+
+ Yes + + - +
+ priority + + Int + +
    +
  • @default(0)
  • +
+
+ Yes + + - +
+ model + + String + +
    +
  • -
  • +
+
+ Yes + + - +
+ language + + String? + +
    +
  • -
  • +
+
+ No + + - +
+ error + + String? + +
    +
  • -
  • +
+
+ No + + - +
+ createdAt + + DateTime + +
    +
  • @default(now())
  • +
+
+ Yes + + - +
+ updatedAt + + DateTime + +
    +
  • @updatedAt
  • +
+
+ Yes + + - +
+ audioFileId + + String + +
    +
  • -
  • +
+
+ Yes + + - +
+ meetingRecordId + + String? + +
    +
  • -
  • +
+
+ No + + - +
+ transcriptionId + + String? + +
    +
  • -
  • +
+
+ No + + - +
+
+
+
+
+

Operations

+
+ +
+

findUnique

+

Find zero or one TranscriptionJob

+
+
// Get one TranscriptionJob
+const transcriptionJob = await prisma.transcriptionJob.findUnique({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + TranscriptionJobWhereUniqueInput + + Yes +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

findFirst

+

Find first TranscriptionJob

+
+
// Get one TranscriptionJob
+const transcriptionJob = await prisma.transcriptionJob.findFirst({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + TranscriptionJobWhereInput + + No +
+ orderBy + + TranscriptionJobOrderByWithRelationInput[] | TranscriptionJobOrderByWithRelationInput + + No +
+ cursor + + TranscriptionJobWhereUniqueInput + + No +
+ take + + Int + + No +
+ skip + + Int + + No +
+ distinct + + TranscriptionJobScalarFieldEnum | TranscriptionJobScalarFieldEnum[] + + No +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

findMany

+

Find zero or more TranscriptionJob

+
+
// Get all TranscriptionJob
+const TranscriptionJob = await prisma.transcriptionJob.findMany()
+// Get first 10 TranscriptionJob
+const TranscriptionJob = await prisma.transcriptionJob.findMany({ take: 10 })
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + TranscriptionJobWhereInput + + No +
+ orderBy + + TranscriptionJobOrderByWithRelationInput[] | TranscriptionJobOrderByWithRelationInput + + No +
+ cursor + + TranscriptionJobWhereUniqueInput + + No +
+ take + + Int + + No +
+ skip + + Int + + No +
+ distinct + + TranscriptionJobScalarFieldEnum | TranscriptionJobScalarFieldEnum[] + + No +
+

Output

+ +
Required: + Yes
+
List: + Yes
+
+
+
+

create

+

Create one TranscriptionJob

+
+
// Create one TranscriptionJob
+const TranscriptionJob = await prisma.transcriptionJob.create({
+  data: {
+    // ... data to create a TranscriptionJob
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + TranscriptionJobCreateInput | TranscriptionJobUncheckedCreateInput + + Yes +
+

Output

+ +
Required: + Yes
+
List: + No
+
+
+
+

delete

+

Delete one TranscriptionJob

+
+
// Delete one TranscriptionJob
+const TranscriptionJob = await prisma.transcriptionJob.delete({
+  where: {
+    // ... filter to delete one TranscriptionJob
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + TranscriptionJobWhereUniqueInput + + Yes +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

update

+

Update one TranscriptionJob

+
+
// Update one TranscriptionJob
+const transcriptionJob = await prisma.transcriptionJob.update({
+  where: {
+    // ... provide filter here
+  },
+  data: {
+    // ... provide data here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + TranscriptionJobUpdateInput | TranscriptionJobUncheckedUpdateInput + + Yes +
+ where + + TranscriptionJobWhereUniqueInput + + Yes +
+

Output

+ +
Required: + No
+
List: + No
+
+
+
+

deleteMany

+

Delete zero or more TranscriptionJob

+
+
// Delete a few TranscriptionJob
+const { count } = await prisma.transcriptionJob.deleteMany({
+  where: {
+    // ... provide filter here
+  }
+})
+
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + TranscriptionJobWhereInput + + No +
+ limit + + Int + + No +
+

Output

+ +
Required: + Yes
+
List: + No
+
+
+
+

updateMany

+

Update zero or one TranscriptionJob

+
+
const { count } = await prisma.transcriptionJob.updateMany({
+  where: {
+    // ... provide filter here
+  },
+  data: {
+    // ... provide data here
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ data + + TranscriptionJobUpdateManyMutationInput | TranscriptionJobUncheckedUpdateManyInput + + Yes +
+ where + + TranscriptionJobWhereInput + + No +
+ limit + + Int + + No +
+

Output

+ +
Required: + Yes
+
List: + No
+
+
+
+

upsert

+

Create or update one TranscriptionJob

+
+
// Update or create a TranscriptionJob
+const transcriptionJob = await prisma.transcriptionJob.upsert({
+  create: {
+    // ... data to create a TranscriptionJob
+  },
+  update: {
+    // ... in case it already exists, update
+  },
+  where: {
+    // ... the filter for the TranscriptionJob we want to update
+  }
+})
+
+

Input

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequired
+ where + + TranscriptionJobWhereUniqueInput + + Yes +
+ create + + TranscriptionJobCreateInput | TranscriptionJobUncheckedCreateInput + + Yes +
+ update + + TranscriptionJobUpdateInput | TranscriptionJobUncheckedUpdateInput + + Yes +
+

Output

+ +
Required: + Yes
+
List: + No
+
+ +
+
+
+ +
+ +
+

Types

+
+
+

Input Types

+
+ +
+

TranscriptionWhereInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ AND + TranscriptionWhereInput | TranscriptionWhereInput[] + + No +
+ OR + TranscriptionWhereInput[] + + No +
+ NOT + TranscriptionWhereInput | TranscriptionWhereInput[] + + No +
+ id + StringFilter | String + + No +
+ text + StringFilter | String + + No +
+ language + StringNullableFilter | String | Null + + Yes +
+ model + StringFilter | String + + No +
+ confidence + FloatNullableFilter | Float | Null + + Yes +
+ processingTime + IntNullableFilter | Int | Null + + Yes +
+ status + StringFilter | String + + No +
+ error + StringNullableFilter | String | Null + + Yes +
+ createdAt + DateTimeFilter | DateTime + + No +
+ updatedAt + DateTimeFilter | DateTime + + No +
+ audioFileId + StringFilter | String + + No +
+ meetingRecordId + StringNullableFilter | String | Null + + Yes +
+ segments + TranscriptionSegmentListRelationFilter + + No +
+
+
+
+

TranscriptionOrderByWithRelationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ text + SortOrder + + No +
+ language + SortOrder | SortOrderInput + + No +
+ model + SortOrder + + No +
+ confidence + SortOrder | SortOrderInput + + No +
+ processingTime + SortOrder | SortOrderInput + + No +
+ status + SortOrder + + No +
+ error + SortOrder | SortOrderInput + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ audioFileId + SortOrder + + No +
+ meetingRecordId + SortOrder | SortOrderInput + + No +
+ segments + TranscriptionSegmentOrderByRelationAggregateInput + + No +
+
+
+
+

TranscriptionWhereUniqueInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ AND + TranscriptionWhereInput | TranscriptionWhereInput[] + + No +
+ OR + TranscriptionWhereInput[] + + No +
+ NOT + TranscriptionWhereInput | TranscriptionWhereInput[] + + No +
+ text + StringFilter | String + + No +
+ language + StringNullableFilter | String | Null + + Yes +
+ model + StringFilter | String + + No +
+ confidence + FloatNullableFilter | Float | Null + + Yes +
+ processingTime + IntNullableFilter | Int | Null + + Yes +
+ status + StringFilter | String + + No +
+ error + StringNullableFilter | String | Null + + Yes +
+ createdAt + DateTimeFilter | DateTime + + No +
+ updatedAt + DateTimeFilter | DateTime + + No +
+ audioFileId + StringFilter | String + + No +
+ meetingRecordId + StringNullableFilter | String | Null + + Yes +
+ segments + TranscriptionSegmentListRelationFilter + + No +
+
+
+
+

TranscriptionOrderByWithAggregationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ text + SortOrder + + No +
+ language + SortOrder | SortOrderInput + + No +
+ model + SortOrder + + No +
+ confidence + SortOrder | SortOrderInput + + No +
+ processingTime + SortOrder | SortOrderInput + + No +
+ status + SortOrder + + No +
+ error + SortOrder | SortOrderInput + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ audioFileId + SortOrder + + No +
+ meetingRecordId + SortOrder | SortOrderInput + + No +
+ _count + TranscriptionCountOrderByAggregateInput + + No +
+ _avg + TranscriptionAvgOrderByAggregateInput + + No +
+ _max + TranscriptionMaxOrderByAggregateInput + + No +
+ _min + TranscriptionMinOrderByAggregateInput + + No +
+ _sum + TranscriptionSumOrderByAggregateInput + + No +
+
+
+
+

TranscriptionScalarWhereWithAggregatesInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ AND + TranscriptionScalarWhereWithAggregatesInput | TranscriptionScalarWhereWithAggregatesInput[] + + No +
+ OR + TranscriptionScalarWhereWithAggregatesInput[] + + No +
+ NOT + TranscriptionScalarWhereWithAggregatesInput | TranscriptionScalarWhereWithAggregatesInput[] + + No +
+ id + StringWithAggregatesFilter | String + + No +
+ text + StringWithAggregatesFilter | String + + No +
+ language + StringNullableWithAggregatesFilter | String | Null + + Yes +
+ model + StringWithAggregatesFilter | String + + No +
+ confidence + FloatNullableWithAggregatesFilter | Float | Null + + Yes +
+ processingTime + IntNullableWithAggregatesFilter | Int | Null + + Yes +
+ status + StringWithAggregatesFilter | String + + No +
+ error + StringNullableWithAggregatesFilter | String | Null + + Yes +
+ createdAt + DateTimeWithAggregatesFilter | DateTime + + No +
+ updatedAt + DateTimeWithAggregatesFilter | DateTime + + No +
+ audioFileId + StringWithAggregatesFilter | String + + No +
+ meetingRecordId + StringNullableWithAggregatesFilter | String | Null + + Yes +
+
+
+
+

TranscriptionSegmentWhereInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ AND + TranscriptionSegmentWhereInput | TranscriptionSegmentWhereInput[] + + No +
+ OR + TranscriptionSegmentWhereInput[] + + No +
+ NOT + TranscriptionSegmentWhereInput | TranscriptionSegmentWhereInput[] + + No +
+ id + StringFilter | String + + No +
+ index + IntFilter | Int + + No +
+ start + FloatFilter | Float + + No +
+ end + FloatFilter | Float + + No +
+ text + StringFilter | String + + No +
+ confidence + FloatNullableFilter | Float | Null + + Yes +
+ transcriptionId + StringFilter | String + + No +
+ transcription + TranscriptionScalarRelationFilter | TranscriptionWhereInput + + No +
+
+
+
+

TranscriptionSegmentOrderByWithRelationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ index + SortOrder + + No +
+ start + SortOrder + + No +
+ end + SortOrder + + No +
+ text + SortOrder + + No +
+ confidence + SortOrder | SortOrderInput + + No +
+ transcriptionId + SortOrder + + No +
+ transcription + TranscriptionOrderByWithRelationInput + + No +
+
+
+
+

TranscriptionSegmentWhereUniqueInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ AND + TranscriptionSegmentWhereInput | TranscriptionSegmentWhereInput[] + + No +
+ OR + TranscriptionSegmentWhereInput[] + + No +
+ NOT + TranscriptionSegmentWhereInput | TranscriptionSegmentWhereInput[] + + No +
+ index + IntFilter | Int + + No +
+ start + FloatFilter | Float + + No +
+ end + FloatFilter | Float + + No +
+ text + StringFilter | String + + No +
+ confidence + FloatNullableFilter | Float | Null + + Yes +
+ transcriptionId + StringFilter | String + + No +
+ transcription + TranscriptionScalarRelationFilter | TranscriptionWhereInput + + No +
+
+
+
+

TranscriptionSegmentOrderByWithAggregationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ index + SortOrder + + No +
+ start + SortOrder + + No +
+ end + SortOrder + + No +
+ text + SortOrder + + No +
+ confidence + SortOrder | SortOrderInput + + No +
+ transcriptionId + SortOrder + + No +
+ _count + TranscriptionSegmentCountOrderByAggregateInput + + No +
+ _avg + TranscriptionSegmentAvgOrderByAggregateInput + + No +
+ _max + TranscriptionSegmentMaxOrderByAggregateInput + + No +
+ _min + TranscriptionSegmentMinOrderByAggregateInput + + No +
+ _sum + TranscriptionSegmentSumOrderByAggregateInput + + No +
+
+
+
+

TranscriptionSegmentScalarWhereWithAggregatesInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ AND + TranscriptionSegmentScalarWhereWithAggregatesInput | TranscriptionSegmentScalarWhereWithAggregatesInput[] + + No +
+ OR + TranscriptionSegmentScalarWhereWithAggregatesInput[] + + No +
+ NOT + TranscriptionSegmentScalarWhereWithAggregatesInput | TranscriptionSegmentScalarWhereWithAggregatesInput[] + + No +
+ id + StringWithAggregatesFilter | String + + No +
+ index + IntWithAggregatesFilter | Int + + No +
+ start + FloatWithAggregatesFilter | Float + + No +
+ end + FloatWithAggregatesFilter | Float + + No +
+ text + StringWithAggregatesFilter | String + + No +
+ confidence + FloatNullableWithAggregatesFilter | Float | Null + + Yes +
+ transcriptionId + StringWithAggregatesFilter | String + + No +
+
+
+
+

TranscriptionJobWhereInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ AND + TranscriptionJobWhereInput | TranscriptionJobWhereInput[] + + No +
+ OR + TranscriptionJobWhereInput[] + + No +
+ NOT + TranscriptionJobWhereInput | TranscriptionJobWhereInput[] + + No +
+ id + StringFilter | String + + No +
+ status + StringFilter | String + + No +
+ priority + IntFilter | Int + + No +
+ model + StringFilter | String + + No +
+ language + StringNullableFilter | String | Null + + Yes +
+ error + StringNullableFilter | String | Null + + Yes +
+ createdAt + DateTimeFilter | DateTime + + No +
+ updatedAt + DateTimeFilter | DateTime + + No +
+ audioFileId + StringFilter | String + + No +
+ meetingRecordId + StringNullableFilter | String | Null + + Yes +
+ transcriptionId + StringNullableFilter | String | Null + + Yes +
+
+
+
+

TranscriptionJobOrderByWithRelationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ status + SortOrder + + No +
+ priority + SortOrder + + No +
+ model + SortOrder + + No +
+ language + SortOrder | SortOrderInput + + No +
+ error + SortOrder | SortOrderInput + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ audioFileId + SortOrder + + No +
+ meetingRecordId + SortOrder | SortOrderInput + + No +
+ transcriptionId + SortOrder | SortOrderInput + + No +
+
+
+
+

TranscriptionJobWhereUniqueInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ AND + TranscriptionJobWhereInput | TranscriptionJobWhereInput[] + + No +
+ OR + TranscriptionJobWhereInput[] + + No +
+ NOT + TranscriptionJobWhereInput | TranscriptionJobWhereInput[] + + No +
+ status + StringFilter | String + + No +
+ priority + IntFilter | Int + + No +
+ model + StringFilter | String + + No +
+ language + StringNullableFilter | String | Null + + Yes +
+ error + StringNullableFilter | String | Null + + Yes +
+ createdAt + DateTimeFilter | DateTime + + No +
+ updatedAt + DateTimeFilter | DateTime + + No +
+ audioFileId + StringFilter | String + + No +
+ meetingRecordId + StringNullableFilter | String | Null + + Yes +
+ transcriptionId + StringNullableFilter | String | Null + + Yes +
+
+
+
+

TranscriptionJobOrderByWithAggregationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ status + SortOrder + + No +
+ priority + SortOrder + + No +
+ model + SortOrder + + No +
+ language + SortOrder | SortOrderInput + + No +
+ error + SortOrder | SortOrderInput + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ audioFileId + SortOrder + + No +
+ meetingRecordId + SortOrder | SortOrderInput + + No +
+ transcriptionId + SortOrder | SortOrderInput + + No +
+ _count + TranscriptionJobCountOrderByAggregateInput + + No +
+ _avg + TranscriptionJobAvgOrderByAggregateInput + + No +
+ _max + TranscriptionJobMaxOrderByAggregateInput + + No +
+ _min + TranscriptionJobMinOrderByAggregateInput + + No +
+ _sum + TranscriptionJobSumOrderByAggregateInput + + No +
+
+
+
+

TranscriptionJobScalarWhereWithAggregatesInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ AND + TranscriptionJobScalarWhereWithAggregatesInput | TranscriptionJobScalarWhereWithAggregatesInput[] + + No +
+ OR + TranscriptionJobScalarWhereWithAggregatesInput[] + + No +
+ NOT + TranscriptionJobScalarWhereWithAggregatesInput | TranscriptionJobScalarWhereWithAggregatesInput[] + + No +
+ id + StringWithAggregatesFilter | String + + No +
+ status + StringWithAggregatesFilter | String + + No +
+ priority + IntWithAggregatesFilter | Int + + No +
+ model + StringWithAggregatesFilter | String + + No +
+ language + StringNullableWithAggregatesFilter | String | Null + + Yes +
+ error + StringNullableWithAggregatesFilter | String | Null + + Yes +
+ createdAt + DateTimeWithAggregatesFilter | DateTime + + No +
+ updatedAt + DateTimeWithAggregatesFilter | DateTime + + No +
+ audioFileId + StringWithAggregatesFilter | String + + No +
+ meetingRecordId + StringNullableWithAggregatesFilter | String | Null + + Yes +
+ transcriptionId + StringNullableWithAggregatesFilter | String | Null + + Yes +
+
+
+
+

TranscriptionCreateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ text + String + + No +
+ language + String | Null + + Yes +
+ model + String + + No +
+ confidence + Float | Null + + Yes +
+ processingTime + Int | Null + + Yes +
+ status + String + + No +
+ error + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ audioFileId + String + + No +
+ meetingRecordId + String | Null + + Yes +
+ segments + TranscriptionSegmentCreateNestedManyWithoutTranscriptionInput + + No +
+
+
+
+

TranscriptionUncheckedCreateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ text + String + + No +
+ language + String | Null + + Yes +
+ model + String + + No +
+ confidence + Float | Null + + Yes +
+ processingTime + Int | Null + + Yes +
+ status + String + + No +
+ error + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ audioFileId + String + + No +
+ meetingRecordId + String | Null + + Yes +
+ segments + TranscriptionSegmentUncheckedCreateNestedManyWithoutTranscriptionInput + + No +
+
+
+
+

TranscriptionUpdateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ text + String | StringFieldUpdateOperationsInput + + No +
+ language + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ model + String | StringFieldUpdateOperationsInput + + No +
+ confidence + Float | NullableFloatFieldUpdateOperationsInput | Null + + Yes +
+ processingTime + Int | NullableIntFieldUpdateOperationsInput | Null + + Yes +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ error + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ audioFileId + String | StringFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ segments + TranscriptionSegmentUpdateManyWithoutTranscriptionNestedInput + + No +
+
+
+
+

TranscriptionUncheckedUpdateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ text + String | StringFieldUpdateOperationsInput + + No +
+ language + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ model + String | StringFieldUpdateOperationsInput + + No +
+ confidence + Float | NullableFloatFieldUpdateOperationsInput | Null + + Yes +
+ processingTime + Int | NullableIntFieldUpdateOperationsInput | Null + + Yes +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ error + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ audioFileId + String | StringFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ segments + TranscriptionSegmentUncheckedUpdateManyWithoutTranscriptionNestedInput + + No +
+
+
+
+

TranscriptionCreateManyInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ text + String + + No +
+ language + String | Null + + Yes +
+ model + String + + No +
+ confidence + Float | Null + + Yes +
+ processingTime + Int | Null + + Yes +
+ status + String + + No +
+ error + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ audioFileId + String + + No +
+ meetingRecordId + String | Null + + Yes +
+
+
+
+

TranscriptionUpdateManyMutationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ text + String | StringFieldUpdateOperationsInput + + No +
+ language + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ model + String | StringFieldUpdateOperationsInput + + No +
+ confidence + Float | NullableFloatFieldUpdateOperationsInput | Null + + Yes +
+ processingTime + Int | NullableIntFieldUpdateOperationsInput | Null + + Yes +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ error + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ audioFileId + String | StringFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

TranscriptionUncheckedUpdateManyInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ text + String | StringFieldUpdateOperationsInput + + No +
+ language + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ model + String | StringFieldUpdateOperationsInput + + No +
+ confidence + Float | NullableFloatFieldUpdateOperationsInput | Null + + Yes +
+ processingTime + Int | NullableIntFieldUpdateOperationsInput | Null + + Yes +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ error + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ audioFileId + String | StringFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

TranscriptionSegmentCreateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ index + Int + + No +
+ start + Float + + No +
+ end + Float + + No +
+ text + String + + No +
+ confidence + Float | Null + + Yes +
+ transcription + TranscriptionCreateNestedOneWithoutSegmentsInput + + No +
+
+
+
+

TranscriptionSegmentUncheckedCreateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ index + Int + + No +
+ start + Float + + No +
+ end + Float + + No +
+ text + String + + No +
+ confidence + Float | Null + + Yes +
+ transcriptionId + String + + No +
+
+
+
+

TranscriptionSegmentUpdateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ index + Int | IntFieldUpdateOperationsInput + + No +
+ start + Float | FloatFieldUpdateOperationsInput + + No +
+ end + Float | FloatFieldUpdateOperationsInput + + No +
+ text + String | StringFieldUpdateOperationsInput + + No +
+ confidence + Float | NullableFloatFieldUpdateOperationsInput | Null + + Yes +
+ transcription + TranscriptionUpdateOneRequiredWithoutSegmentsNestedInput + + No +
+
+
+
+

TranscriptionSegmentUncheckedUpdateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ index + Int | IntFieldUpdateOperationsInput + + No +
+ start + Float | FloatFieldUpdateOperationsInput + + No +
+ end + Float | FloatFieldUpdateOperationsInput + + No +
+ text + String | StringFieldUpdateOperationsInput + + No +
+ confidence + Float | NullableFloatFieldUpdateOperationsInput | Null + + Yes +
+ transcriptionId + String | StringFieldUpdateOperationsInput + + No +
+
+
+
+

TranscriptionSegmentCreateManyInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ index + Int + + No +
+ start + Float + + No +
+ end + Float + + No +
+ text + String + + No +
+ confidence + Float | Null + + Yes +
+ transcriptionId + String + + No +
+
+
+
+

TranscriptionSegmentUpdateManyMutationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ index + Int | IntFieldUpdateOperationsInput + + No +
+ start + Float | FloatFieldUpdateOperationsInput + + No +
+ end + Float | FloatFieldUpdateOperationsInput + + No +
+ text + String | StringFieldUpdateOperationsInput + + No +
+ confidence + Float | NullableFloatFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

TranscriptionSegmentUncheckedUpdateManyInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ index + Int | IntFieldUpdateOperationsInput + + No +
+ start + Float | FloatFieldUpdateOperationsInput + + No +
+ end + Float | FloatFieldUpdateOperationsInput + + No +
+ text + String | StringFieldUpdateOperationsInput + + No +
+ confidence + Float | NullableFloatFieldUpdateOperationsInput | Null + + Yes +
+ transcriptionId + String | StringFieldUpdateOperationsInput + + No +
+
+
+
+

TranscriptionJobCreateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ status + String + + No +
+ priority + Int + + No +
+ model + String + + No +
+ language + String | Null + + Yes +
+ error + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ audioFileId + String + + No +
+ meetingRecordId + String | Null + + Yes +
+ transcriptionId + String | Null + + Yes +
+
+
+
+

TranscriptionJobUncheckedCreateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ status + String + + No +
+ priority + Int + + No +
+ model + String + + No +
+ language + String | Null + + Yes +
+ error + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ audioFileId + String + + No +
+ meetingRecordId + String | Null + + Yes +
+ transcriptionId + String | Null + + Yes +
+
+
+
+

TranscriptionJobUpdateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ priority + Int | IntFieldUpdateOperationsInput + + No +
+ model + String | StringFieldUpdateOperationsInput + + No +
+ language + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ error + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ audioFileId + String | StringFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ transcriptionId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

TranscriptionJobUncheckedUpdateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ priority + Int | IntFieldUpdateOperationsInput + + No +
+ model + String | StringFieldUpdateOperationsInput + + No +
+ language + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ error + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ audioFileId + String | StringFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ transcriptionId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

TranscriptionJobCreateManyInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ status + String + + No +
+ priority + Int + + No +
+ model + String + + No +
+ language + String | Null + + Yes +
+ error + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ audioFileId + String + + No +
+ meetingRecordId + String | Null + + Yes +
+ transcriptionId + String | Null + + Yes +
+
+
+
+

TranscriptionJobUpdateManyMutationInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ priority + Int | IntFieldUpdateOperationsInput + + No +
+ model + String | StringFieldUpdateOperationsInput + + No +
+ language + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ error + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ audioFileId + String | StringFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ transcriptionId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

TranscriptionJobUncheckedUpdateManyInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ priority + Int | IntFieldUpdateOperationsInput + + No +
+ model + String | StringFieldUpdateOperationsInput + + No +
+ language + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ error + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ audioFileId + String | StringFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ transcriptionId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

StringFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput + + No +
+ in + String | ListStringFieldRefInput + + No +
+ notIn + String | ListStringFieldRefInput + + No +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ mode + QueryMode + + No +
+ not + String | NestedStringFilter + + No +
+
+
+
+

StringNullableFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput | Null + + Yes +
+ in + String | ListStringFieldRefInput | Null + + Yes +
+ notIn + String | ListStringFieldRefInput | Null + + Yes +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ mode + QueryMode + + No +
+ not + String | NestedStringNullableFilter | Null + + Yes +
+
+
+
+

FloatNullableFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Float | FloatFieldRefInput | Null + + Yes +
+ in + Float | ListFloatFieldRefInput | Null + + Yes +
+ notIn + Float | ListFloatFieldRefInput | Null + + Yes +
+ lt + Float | FloatFieldRefInput + + No +
+ lte + Float | FloatFieldRefInput + + No +
+ gt + Float | FloatFieldRefInput + + No +
+ gte + Float | FloatFieldRefInput + + No +
+ not + Float | NestedFloatNullableFilter | Null + + Yes +
+
+
+
+

IntNullableFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Int | IntFieldRefInput | Null + + Yes +
+ in + Int | ListIntFieldRefInput | Null + + Yes +
+ notIn + Int | ListIntFieldRefInput | Null + + Yes +
+ lt + Int | IntFieldRefInput + + No +
+ lte + Int | IntFieldRefInput + + No +
+ gt + Int | IntFieldRefInput + + No +
+ gte + Int | IntFieldRefInput + + No +
+ not + Int | NestedIntNullableFilter | Null + + Yes +
+
+
+
+

DateTimeFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + DateTime | DateTimeFieldRefInput + + No +
+ in + DateTime | ListDateTimeFieldRefInput + + No +
+ notIn + DateTime | ListDateTimeFieldRefInput + + No +
+ lt + DateTime | DateTimeFieldRefInput + + No +
+ lte + DateTime | DateTimeFieldRefInput + + No +
+ gt + DateTime | DateTimeFieldRefInput + + No +
+ gte + DateTime | DateTimeFieldRefInput + + No +
+ not + DateTime | NestedDateTimeFilter + + No +
+
+
+
+

TranscriptionSegmentListRelationFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ every + TranscriptionSegmentWhereInput + + No +
+ some + TranscriptionSegmentWhereInput + + No +
+ none + TranscriptionSegmentWhereInput + + No +
+
+
+
+

SortOrderInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ sort + SortOrder + + No +
+ nulls + NullsOrder + + No +
+
+
+
+

TranscriptionSegmentOrderByRelationAggregateInput

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ _count + SortOrder + + No +
+
+
+
+

TranscriptionCountOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ text + SortOrder + + No +
+ language + SortOrder + + No +
+ model + SortOrder + + No +
+ confidence + SortOrder + + No +
+ processingTime + SortOrder + + No +
+ status + SortOrder + + No +
+ error + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ audioFileId + SortOrder + + No +
+ meetingRecordId + SortOrder + + No +
+
+
+
+

TranscriptionAvgOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ confidence + SortOrder + + No +
+ processingTime + SortOrder + + No +
+
+
+
+

TranscriptionMaxOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ text + SortOrder + + No +
+ language + SortOrder + + No +
+ model + SortOrder + + No +
+ confidence + SortOrder + + No +
+ processingTime + SortOrder + + No +
+ status + SortOrder + + No +
+ error + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ audioFileId + SortOrder + + No +
+ meetingRecordId + SortOrder + + No +
+
+
+
+

TranscriptionMinOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ text + SortOrder + + No +
+ language + SortOrder + + No +
+ model + SortOrder + + No +
+ confidence + SortOrder + + No +
+ processingTime + SortOrder + + No +
+ status + SortOrder + + No +
+ error + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ audioFileId + SortOrder + + No +
+ meetingRecordId + SortOrder + + No +
+
+
+
+

TranscriptionSumOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ confidence + SortOrder + + No +
+ processingTime + SortOrder + + No +
+
+
+
+

StringWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput + + No +
+ in + String | ListStringFieldRefInput + + No +
+ notIn + String | ListStringFieldRefInput + + No +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ mode + QueryMode + + No +
+ not + String | NestedStringWithAggregatesFilter + + No +
+ _count + NestedIntFilter + + No +
+ _min + NestedStringFilter + + No +
+ _max + NestedStringFilter + + No +
+
+
+
+

StringNullableWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput | Null + + Yes +
+ in + String | ListStringFieldRefInput | Null + + Yes +
+ notIn + String | ListStringFieldRefInput | Null + + Yes +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ mode + QueryMode + + No +
+ not + String | NestedStringNullableWithAggregatesFilter | Null + + Yes +
+ _count + NestedIntNullableFilter + + No +
+ _min + NestedStringNullableFilter + + No +
+ _max + NestedStringNullableFilter + + No +
+
+
+
+

FloatNullableWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Float | FloatFieldRefInput | Null + + Yes +
+ in + Float | ListFloatFieldRefInput | Null + + Yes +
+ notIn + Float | ListFloatFieldRefInput | Null + + Yes +
+ lt + Float | FloatFieldRefInput + + No +
+ lte + Float | FloatFieldRefInput + + No +
+ gt + Float | FloatFieldRefInput + + No +
+ gte + Float | FloatFieldRefInput + + No +
+ not + Float | NestedFloatNullableWithAggregatesFilter | Null + + Yes +
+ _count + NestedIntNullableFilter + + No +
+ _avg + NestedFloatNullableFilter + + No +
+ _sum + NestedFloatNullableFilter + + No +
+ _min + NestedFloatNullableFilter + + No +
+ _max + NestedFloatNullableFilter + + No +
+
+
+
+

IntNullableWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Int | IntFieldRefInput | Null + + Yes +
+ in + Int | ListIntFieldRefInput | Null + + Yes +
+ notIn + Int | ListIntFieldRefInput | Null + + Yes +
+ lt + Int | IntFieldRefInput + + No +
+ lte + Int | IntFieldRefInput + + No +
+ gt + Int | IntFieldRefInput + + No +
+ gte + Int | IntFieldRefInput + + No +
+ not + Int | NestedIntNullableWithAggregatesFilter | Null + + Yes +
+ _count + NestedIntNullableFilter + + No +
+ _avg + NestedFloatNullableFilter + + No +
+ _sum + NestedIntNullableFilter + + No +
+ _min + NestedIntNullableFilter + + No +
+ _max + NestedIntNullableFilter + + No +
+
+
+
+

DateTimeWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + DateTime | DateTimeFieldRefInput + + No +
+ in + DateTime | ListDateTimeFieldRefInput + + No +
+ notIn + DateTime | ListDateTimeFieldRefInput + + No +
+ lt + DateTime | DateTimeFieldRefInput + + No +
+ lte + DateTime | DateTimeFieldRefInput + + No +
+ gt + DateTime | DateTimeFieldRefInput + + No +
+ gte + DateTime | DateTimeFieldRefInput + + No +
+ not + DateTime | NestedDateTimeWithAggregatesFilter + + No +
+ _count + NestedIntFilter + + No +
+ _min + NestedDateTimeFilter + + No +
+ _max + NestedDateTimeFilter + + No +
+
+
+
+

IntFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Int | IntFieldRefInput + + No +
+ in + Int | ListIntFieldRefInput + + No +
+ notIn + Int | ListIntFieldRefInput + + No +
+ lt + Int | IntFieldRefInput + + No +
+ lte + Int | IntFieldRefInput + + No +
+ gt + Int | IntFieldRefInput + + No +
+ gte + Int | IntFieldRefInput + + No +
+ not + Int | NestedIntFilter + + No +
+
+
+
+

FloatFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Float | FloatFieldRefInput + + No +
+ in + Float | ListFloatFieldRefInput + + No +
+ notIn + Float | ListFloatFieldRefInput + + No +
+ lt + Float | FloatFieldRefInput + + No +
+ lte + Float | FloatFieldRefInput + + No +
+ gt + Float | FloatFieldRefInput + + No +
+ gte + Float | FloatFieldRefInput + + No +
+ not + Float | NestedFloatFilter + + No +
+
+
+
+

TranscriptionScalarRelationFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ is + TranscriptionWhereInput + + No +
+ isNot + TranscriptionWhereInput + + No +
+
+
+
+

TranscriptionSegmentCountOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ index + SortOrder + + No +
+ start + SortOrder + + No +
+ end + SortOrder + + No +
+ text + SortOrder + + No +
+ confidence + SortOrder + + No +
+ transcriptionId + SortOrder + + No +
+
+
+
+

TranscriptionSegmentAvgOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ index + SortOrder + + No +
+ start + SortOrder + + No +
+ end + SortOrder + + No +
+ confidence + SortOrder + + No +
+
+
+
+

TranscriptionSegmentMaxOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ index + SortOrder + + No +
+ start + SortOrder + + No +
+ end + SortOrder + + No +
+ text + SortOrder + + No +
+ confidence + SortOrder + + No +
+ transcriptionId + SortOrder + + No +
+
+
+
+

TranscriptionSegmentMinOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ index + SortOrder + + No +
+ start + SortOrder + + No +
+ end + SortOrder + + No +
+ text + SortOrder + + No +
+ confidence + SortOrder + + No +
+ transcriptionId + SortOrder + + No +
+
+
+
+

TranscriptionSegmentSumOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ index + SortOrder + + No +
+ start + SortOrder + + No +
+ end + SortOrder + + No +
+ confidence + SortOrder + + No +
+
+
+
+

IntWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Int | IntFieldRefInput + + No +
+ in + Int | ListIntFieldRefInput + + No +
+ notIn + Int | ListIntFieldRefInput + + No +
+ lt + Int | IntFieldRefInput + + No +
+ lte + Int | IntFieldRefInput + + No +
+ gt + Int | IntFieldRefInput + + No +
+ gte + Int | IntFieldRefInput + + No +
+ not + Int | NestedIntWithAggregatesFilter + + No +
+ _count + NestedIntFilter + + No +
+ _avg + NestedFloatFilter + + No +
+ _sum + NestedIntFilter + + No +
+ _min + NestedIntFilter + + No +
+ _max + NestedIntFilter + + No +
+
+
+
+

FloatWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Float | FloatFieldRefInput + + No +
+ in + Float | ListFloatFieldRefInput + + No +
+ notIn + Float | ListFloatFieldRefInput + + No +
+ lt + Float | FloatFieldRefInput + + No +
+ lte + Float | FloatFieldRefInput + + No +
+ gt + Float | FloatFieldRefInput + + No +
+ gte + Float | FloatFieldRefInput + + No +
+ not + Float | NestedFloatWithAggregatesFilter + + No +
+ _count + NestedIntFilter + + No +
+ _avg + NestedFloatFilter + + No +
+ _sum + NestedFloatFilter + + No +
+ _min + NestedFloatFilter + + No +
+ _max + NestedFloatFilter + + No +
+
+
+
+

TranscriptionJobCountOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ status + SortOrder + + No +
+ priority + SortOrder + + No +
+ model + SortOrder + + No +
+ language + SortOrder + + No +
+ error + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ audioFileId + SortOrder + + No +
+ meetingRecordId + SortOrder + + No +
+ transcriptionId + SortOrder + + No +
+
+
+
+

TranscriptionJobAvgOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ priority + SortOrder + + No +
+
+
+
+

TranscriptionJobMaxOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ status + SortOrder + + No +
+ priority + SortOrder + + No +
+ model + SortOrder + + No +
+ language + SortOrder + + No +
+ error + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ audioFileId + SortOrder + + No +
+ meetingRecordId + SortOrder + + No +
+ transcriptionId + SortOrder + + No +
+
+
+
+

TranscriptionJobMinOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + SortOrder + + No +
+ status + SortOrder + + No +
+ priority + SortOrder + + No +
+ model + SortOrder + + No +
+ language + SortOrder + + No +
+ error + SortOrder + + No +
+ createdAt + SortOrder + + No +
+ updatedAt + SortOrder + + No +
+ audioFileId + SortOrder + + No +
+ meetingRecordId + SortOrder + + No +
+ transcriptionId + SortOrder + + No +
+
+
+
+

TranscriptionJobSumOrderByAggregateInput

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ priority + SortOrder + + No +
+
+
+ +
+ +
+
+

StringFieldUpdateOperationsInput

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ set + String + + No +
+
+
+
+

NullableStringFieldUpdateOperationsInput

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ set + String | Null + + Yes +
+
+
+
+

NullableFloatFieldUpdateOperationsInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ set + Float | Null + + Yes +
+ increment + Float + + No +
+ decrement + Float + + No +
+ multiply + Float + + No +
+ divide + Float + + No +
+
+
+
+

NullableIntFieldUpdateOperationsInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ set + Int | Null + + Yes +
+ increment + Int + + No +
+ decrement + Int + + No +
+ multiply + Int + + No +
+ divide + Int + + No +
+
+
+
+

DateTimeFieldUpdateOperationsInput

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ set + DateTime + + No +
+
+
+
+

TranscriptionSegmentUpdateManyWithoutTranscriptionNestedInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + TranscriptionSegmentCreateWithoutTranscriptionInput | TranscriptionSegmentCreateWithoutTranscriptionInput[] | TranscriptionSegmentUncheckedCreateWithoutTranscriptionInput | TranscriptionSegmentUncheckedCreateWithoutTranscriptionInput[] + + No +
+ connectOrCreate + TranscriptionSegmentCreateOrConnectWithoutTranscriptionInput | TranscriptionSegmentCreateOrConnectWithoutTranscriptionInput[] + + No +
+ upsert + TranscriptionSegmentUpsertWithWhereUniqueWithoutTranscriptionInput | TranscriptionSegmentUpsertWithWhereUniqueWithoutTranscriptionInput[] + + No +
+ createMany + TranscriptionSegmentCreateManyTranscriptionInputEnvelope + + No +
+ set + TranscriptionSegmentWhereUniqueInput | TranscriptionSegmentWhereUniqueInput[] + + No +
+ disconnect + TranscriptionSegmentWhereUniqueInput | TranscriptionSegmentWhereUniqueInput[] + + No +
+ delete + TranscriptionSegmentWhereUniqueInput | TranscriptionSegmentWhereUniqueInput[] + + No +
+ connect + TranscriptionSegmentWhereUniqueInput | TranscriptionSegmentWhereUniqueInput[] + + No +
+ update + TranscriptionSegmentUpdateWithWhereUniqueWithoutTranscriptionInput | TranscriptionSegmentUpdateWithWhereUniqueWithoutTranscriptionInput[] + + No +
+ updateMany + TranscriptionSegmentUpdateManyWithWhereWithoutTranscriptionInput | TranscriptionSegmentUpdateManyWithWhereWithoutTranscriptionInput[] + + No +
+ deleteMany + TranscriptionSegmentScalarWhereInput | TranscriptionSegmentScalarWhereInput[] + + No +
+
+
+
+

TranscriptionSegmentUncheckedUpdateManyWithoutTranscriptionNestedInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + TranscriptionSegmentCreateWithoutTranscriptionInput | TranscriptionSegmentCreateWithoutTranscriptionInput[] | TranscriptionSegmentUncheckedCreateWithoutTranscriptionInput | TranscriptionSegmentUncheckedCreateWithoutTranscriptionInput[] + + No +
+ connectOrCreate + TranscriptionSegmentCreateOrConnectWithoutTranscriptionInput | TranscriptionSegmentCreateOrConnectWithoutTranscriptionInput[] + + No +
+ upsert + TranscriptionSegmentUpsertWithWhereUniqueWithoutTranscriptionInput | TranscriptionSegmentUpsertWithWhereUniqueWithoutTranscriptionInput[] + + No +
+ createMany + TranscriptionSegmentCreateManyTranscriptionInputEnvelope + + No +
+ set + TranscriptionSegmentWhereUniqueInput | TranscriptionSegmentWhereUniqueInput[] + + No +
+ disconnect + TranscriptionSegmentWhereUniqueInput | TranscriptionSegmentWhereUniqueInput[] + + No +
+ delete + TranscriptionSegmentWhereUniqueInput | TranscriptionSegmentWhereUniqueInput[] + + No +
+ connect + TranscriptionSegmentWhereUniqueInput | TranscriptionSegmentWhereUniqueInput[] + + No +
+ update + TranscriptionSegmentUpdateWithWhereUniqueWithoutTranscriptionInput | TranscriptionSegmentUpdateWithWhereUniqueWithoutTranscriptionInput[] + + No +
+ updateMany + TranscriptionSegmentUpdateManyWithWhereWithoutTranscriptionInput | TranscriptionSegmentUpdateManyWithWhereWithoutTranscriptionInput[] + + No +
+ deleteMany + TranscriptionSegmentScalarWhereInput | TranscriptionSegmentScalarWhereInput[] + + No +
+
+
+
+

TranscriptionCreateNestedOneWithoutSegmentsInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + TranscriptionCreateWithoutSegmentsInput | TranscriptionUncheckedCreateWithoutSegmentsInput + + No +
+ connectOrCreate + TranscriptionCreateOrConnectWithoutSegmentsInput + + No +
+ connect + TranscriptionWhereUniqueInput + + No +
+
+
+
+

IntFieldUpdateOperationsInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ set + Int + + No +
+ increment + Int + + No +
+ decrement + Int + + No +
+ multiply + Int + + No +
+ divide + Int + + No +
+
+
+
+

FloatFieldUpdateOperationsInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ set + Float + + No +
+ increment + Float + + No +
+ decrement + Float + + No +
+ multiply + Float + + No +
+ divide + Float + + No +
+
+
+
+

TranscriptionUpdateOneRequiredWithoutSegmentsNestedInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ create + TranscriptionCreateWithoutSegmentsInput | TranscriptionUncheckedCreateWithoutSegmentsInput + + No +
+ connectOrCreate + TranscriptionCreateOrConnectWithoutSegmentsInput + + No +
+ upsert + TranscriptionUpsertWithoutSegmentsInput + + No +
+ connect + TranscriptionWhereUniqueInput + + No +
+ update + TranscriptionUpdateToOneWithWhereWithoutSegmentsInput | TranscriptionUpdateWithoutSegmentsInput | TranscriptionUncheckedUpdateWithoutSegmentsInput + + No +
+
+
+
+

NestedStringFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput + + No +
+ in + String | ListStringFieldRefInput + + No +
+ notIn + String | ListStringFieldRefInput + + No +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ not + String | NestedStringFilter + + No +
+
+
+
+

NestedStringNullableFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput | Null + + Yes +
+ in + String | ListStringFieldRefInput | Null + + Yes +
+ notIn + String | ListStringFieldRefInput | Null + + Yes +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ not + String | NestedStringNullableFilter | Null + + Yes +
+
+
+
+

NestedFloatNullableFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Float | FloatFieldRefInput | Null + + Yes +
+ in + Float | ListFloatFieldRefInput | Null + + Yes +
+ notIn + Float | ListFloatFieldRefInput | Null + + Yes +
+ lt + Float | FloatFieldRefInput + + No +
+ lte + Float | FloatFieldRefInput + + No +
+ gt + Float | FloatFieldRefInput + + No +
+ gte + Float | FloatFieldRefInput + + No +
+ not + Float | NestedFloatNullableFilter | Null + + Yes +
+
+
+
+

NestedIntNullableFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Int | IntFieldRefInput | Null + + Yes +
+ in + Int | ListIntFieldRefInput | Null + + Yes +
+ notIn + Int | ListIntFieldRefInput | Null + + Yes +
+ lt + Int | IntFieldRefInput + + No +
+ lte + Int | IntFieldRefInput + + No +
+ gt + Int | IntFieldRefInput + + No +
+ gte + Int | IntFieldRefInput + + No +
+ not + Int | NestedIntNullableFilter | Null + + Yes +
+
+
+
+

NestedDateTimeFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + DateTime | DateTimeFieldRefInput + + No +
+ in + DateTime | ListDateTimeFieldRefInput + + No +
+ notIn + DateTime | ListDateTimeFieldRefInput + + No +
+ lt + DateTime | DateTimeFieldRefInput + + No +
+ lte + DateTime | DateTimeFieldRefInput + + No +
+ gt + DateTime | DateTimeFieldRefInput + + No +
+ gte + DateTime | DateTimeFieldRefInput + + No +
+ not + DateTime | NestedDateTimeFilter + + No +
+
+
+
+

NestedStringWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput + + No +
+ in + String | ListStringFieldRefInput + + No +
+ notIn + String | ListStringFieldRefInput + + No +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ not + String | NestedStringWithAggregatesFilter + + No +
+ _count + NestedIntFilter + + No +
+ _min + NestedStringFilter + + No +
+ _max + NestedStringFilter + + No +
+
+
+
+

NestedIntFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Int | IntFieldRefInput + + No +
+ in + Int | ListIntFieldRefInput + + No +
+ notIn + Int | ListIntFieldRefInput + + No +
+ lt + Int | IntFieldRefInput + + No +
+ lte + Int | IntFieldRefInput + + No +
+ gt + Int | IntFieldRefInput + + No +
+ gte + Int | IntFieldRefInput + + No +
+ not + Int | NestedIntFilter + + No +
+
+
+
+

NestedStringNullableWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + String | StringFieldRefInput | Null + + Yes +
+ in + String | ListStringFieldRefInput | Null + + Yes +
+ notIn + String | ListStringFieldRefInput | Null + + Yes +
+ lt + String | StringFieldRefInput + + No +
+ lte + String | StringFieldRefInput + + No +
+ gt + String | StringFieldRefInput + + No +
+ gte + String | StringFieldRefInput + + No +
+ contains + String | StringFieldRefInput + + No +
+ startsWith + String | StringFieldRefInput + + No +
+ endsWith + String | StringFieldRefInput + + No +
+ not + String | NestedStringNullableWithAggregatesFilter | Null + + Yes +
+ _count + NestedIntNullableFilter + + No +
+ _min + NestedStringNullableFilter + + No +
+ _max + NestedStringNullableFilter + + No +
+
+
+
+

NestedFloatNullableWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Float | FloatFieldRefInput | Null + + Yes +
+ in + Float | ListFloatFieldRefInput | Null + + Yes +
+ notIn + Float | ListFloatFieldRefInput | Null + + Yes +
+ lt + Float | FloatFieldRefInput + + No +
+ lte + Float | FloatFieldRefInput + + No +
+ gt + Float | FloatFieldRefInput + + No +
+ gte + Float | FloatFieldRefInput + + No +
+ not + Float | NestedFloatNullableWithAggregatesFilter | Null + + Yes +
+ _count + NestedIntNullableFilter + + No +
+ _avg + NestedFloatNullableFilter + + No +
+ _sum + NestedFloatNullableFilter + + No +
+ _min + NestedFloatNullableFilter + + No +
+ _max + NestedFloatNullableFilter + + No +
+
+
+
+

NestedIntNullableWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Int | IntFieldRefInput | Null + + Yes +
+ in + Int | ListIntFieldRefInput | Null + + Yes +
+ notIn + Int | ListIntFieldRefInput | Null + + Yes +
+ lt + Int | IntFieldRefInput + + No +
+ lte + Int | IntFieldRefInput + + No +
+ gt + Int | IntFieldRefInput + + No +
+ gte + Int | IntFieldRefInput + + No +
+ not + Int | NestedIntNullableWithAggregatesFilter | Null + + Yes +
+ _count + NestedIntNullableFilter + + No +
+ _avg + NestedFloatNullableFilter + + No +
+ _sum + NestedIntNullableFilter + + No +
+ _min + NestedIntNullableFilter + + No +
+ _max + NestedIntNullableFilter + + No +
+
+
+
+

NestedDateTimeWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + DateTime | DateTimeFieldRefInput + + No +
+ in + DateTime | ListDateTimeFieldRefInput + + No +
+ notIn + DateTime | ListDateTimeFieldRefInput + + No +
+ lt + DateTime | DateTimeFieldRefInput + + No +
+ lte + DateTime | DateTimeFieldRefInput + + No +
+ gt + DateTime | DateTimeFieldRefInput + + No +
+ gte + DateTime | DateTimeFieldRefInput + + No +
+ not + DateTime | NestedDateTimeWithAggregatesFilter + + No +
+ _count + NestedIntFilter + + No +
+ _min + NestedDateTimeFilter + + No +
+ _max + NestedDateTimeFilter + + No +
+
+
+
+

NestedFloatFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Float | FloatFieldRefInput + + No +
+ in + Float | ListFloatFieldRefInput + + No +
+ notIn + Float | ListFloatFieldRefInput + + No +
+ lt + Float | FloatFieldRefInput + + No +
+ lte + Float | FloatFieldRefInput + + No +
+ gt + Float | FloatFieldRefInput + + No +
+ gte + Float | FloatFieldRefInput + + No +
+ not + Float | NestedFloatFilter + + No +
+
+
+
+

NestedIntWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Int | IntFieldRefInput + + No +
+ in + Int | ListIntFieldRefInput + + No +
+ notIn + Int | ListIntFieldRefInput + + No +
+ lt + Int | IntFieldRefInput + + No +
+ lte + Int | IntFieldRefInput + + No +
+ gt + Int | IntFieldRefInput + + No +
+ gte + Int | IntFieldRefInput + + No +
+ not + Int | NestedIntWithAggregatesFilter + + No +
+ _count + NestedIntFilter + + No +
+ _avg + NestedFloatFilter + + No +
+ _sum + NestedIntFilter + + No +
+ _min + NestedIntFilter + + No +
+ _max + NestedIntFilter + + No +
+
+
+
+

NestedFloatWithAggregatesFilter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ equals + Float | FloatFieldRefInput + + No +
+ in + Float | ListFloatFieldRefInput + + No +
+ notIn + Float | ListFloatFieldRefInput + + No +
+ lt + Float | FloatFieldRefInput + + No +
+ lte + Float | FloatFieldRefInput + + No +
+ gt + Float | FloatFieldRefInput + + No +
+ gte + Float | FloatFieldRefInput + + No +
+ not + Float | NestedFloatWithAggregatesFilter + + No +
+ _count + NestedIntFilter + + No +
+ _avg + NestedFloatFilter + + No +
+ _sum + NestedFloatFilter + + No +
+ _min + NestedFloatFilter + + No +
+ _max + NestedFloatFilter + + No +
+
+
+
+

TranscriptionSegmentCreateWithoutTranscriptionInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ index + Int + + No +
+ start + Float + + No +
+ end + Float + + No +
+ text + String + + No +
+ confidence + Float | Null + + Yes +
+
+
+
+

TranscriptionSegmentUncheckedCreateWithoutTranscriptionInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ index + Int + + No +
+ start + Float + + No +
+ end + Float + + No +
+ text + String + + No +
+ confidence + Float | Null + + Yes +
+
+
+
+

TranscriptionSegmentCreateOrConnectWithoutTranscriptionInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + TranscriptionSegmentWhereUniqueInput + + No +
+ create + TranscriptionSegmentCreateWithoutTranscriptionInput | TranscriptionSegmentUncheckedCreateWithoutTranscriptionInput + + No +
+
+
+
+

TranscriptionSegmentCreateManyTranscriptionInputEnvelope

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ data + TranscriptionSegmentCreateManyTranscriptionInput | TranscriptionSegmentCreateManyTranscriptionInput[] + + No +
+ skipDuplicates + Boolean + + No +
+
+
+
+

TranscriptionSegmentUpsertWithWhereUniqueWithoutTranscriptionInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + TranscriptionSegmentWhereUniqueInput + + No +
+ update + TranscriptionSegmentUpdateWithoutTranscriptionInput | TranscriptionSegmentUncheckedUpdateWithoutTranscriptionInput + + No +
+ create + TranscriptionSegmentCreateWithoutTranscriptionInput | TranscriptionSegmentUncheckedCreateWithoutTranscriptionInput + + No +
+
+
+
+

TranscriptionSegmentUpdateWithWhereUniqueWithoutTranscriptionInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + TranscriptionSegmentWhereUniqueInput + + No +
+ data + TranscriptionSegmentUpdateWithoutTranscriptionInput | TranscriptionSegmentUncheckedUpdateWithoutTranscriptionInput + + No +
+
+
+
+

TranscriptionSegmentUpdateManyWithWhereWithoutTranscriptionInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + TranscriptionSegmentScalarWhereInput + + No +
+ data + TranscriptionSegmentUpdateManyMutationInput | TranscriptionSegmentUncheckedUpdateManyWithoutTranscriptionInput + + No +
+
+
+
+

TranscriptionSegmentScalarWhereInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ AND + TranscriptionSegmentScalarWhereInput | TranscriptionSegmentScalarWhereInput[] + + No +
+ OR + TranscriptionSegmentScalarWhereInput[] + + No +
+ NOT + TranscriptionSegmentScalarWhereInput | TranscriptionSegmentScalarWhereInput[] + + No +
+ id + StringFilter | String + + No +
+ index + IntFilter | Int + + No +
+ start + FloatFilter | Float + + No +
+ end + FloatFilter | Float + + No +
+ text + StringFilter | String + + No +
+ confidence + FloatNullableFilter | Float | Null + + Yes +
+ transcriptionId + StringFilter | String + + No +
+
+
+
+

TranscriptionCreateWithoutSegmentsInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ text + String + + No +
+ language + String | Null + + Yes +
+ model + String + + No +
+ confidence + Float | Null + + Yes +
+ processingTime + Int | Null + + Yes +
+ status + String + + No +
+ error + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ audioFileId + String + + No +
+ meetingRecordId + String | Null + + Yes +
+
+
+
+

TranscriptionUncheckedCreateWithoutSegmentsInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ text + String + + No +
+ language + String | Null + + Yes +
+ model + String + + No +
+ confidence + Float | Null + + Yes +
+ processingTime + Int | Null + + Yes +
+ status + String + + No +
+ error + String | Null + + Yes +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ audioFileId + String + + No +
+ meetingRecordId + String | Null + + Yes +
+
+
+
+

TranscriptionCreateOrConnectWithoutSegmentsInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + TranscriptionWhereUniqueInput + + No +
+ create + TranscriptionCreateWithoutSegmentsInput | TranscriptionUncheckedCreateWithoutSegmentsInput + + No +
+
+
+
+

TranscriptionUpsertWithoutSegmentsInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ update + TranscriptionUpdateWithoutSegmentsInput | TranscriptionUncheckedUpdateWithoutSegmentsInput + + No +
+ create + TranscriptionCreateWithoutSegmentsInput | TranscriptionUncheckedCreateWithoutSegmentsInput + + No +
+ where + TranscriptionWhereInput + + No +
+
+
+
+

TranscriptionUpdateToOneWithWhereWithoutSegmentsInput

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ where + TranscriptionWhereInput + + No +
+ data + TranscriptionUpdateWithoutSegmentsInput | TranscriptionUncheckedUpdateWithoutSegmentsInput + + No +
+
+
+
+

TranscriptionUpdateWithoutSegmentsInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ text + String | StringFieldUpdateOperationsInput + + No +
+ language + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ model + String | StringFieldUpdateOperationsInput + + No +
+ confidence + Float | NullableFloatFieldUpdateOperationsInput | Null + + Yes +
+ processingTime + Int | NullableIntFieldUpdateOperationsInput | Null + + Yes +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ error + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ audioFileId + String | StringFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

TranscriptionUncheckedUpdateWithoutSegmentsInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ text + String | StringFieldUpdateOperationsInput + + No +
+ language + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ model + String | StringFieldUpdateOperationsInput + + No +
+ confidence + Float | NullableFloatFieldUpdateOperationsInput | Null + + Yes +
+ processingTime + Int | NullableIntFieldUpdateOperationsInput | Null + + Yes +
+ status + String | StringFieldUpdateOperationsInput + + No +
+ error + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+ createdAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ updatedAt + DateTime | DateTimeFieldUpdateOperationsInput + + No +
+ audioFileId + String | StringFieldUpdateOperationsInput + + No +
+ meetingRecordId + String | NullableStringFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

TranscriptionSegmentCreateManyTranscriptionInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ index + Int + + No +
+ start + Float + + No +
+ end + Float + + No +
+ text + String + + No +
+ confidence + Float | Null + + Yes +
+
+
+
+

TranscriptionSegmentUpdateWithoutTranscriptionInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ index + Int | IntFieldUpdateOperationsInput + + No +
+ start + Float | FloatFieldUpdateOperationsInput + + No +
+ end + Float | FloatFieldUpdateOperationsInput + + No +
+ text + String | StringFieldUpdateOperationsInput + + No +
+ confidence + Float | NullableFloatFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

TranscriptionSegmentUncheckedUpdateWithoutTranscriptionInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ index + Int | IntFieldUpdateOperationsInput + + No +
+ start + Float | FloatFieldUpdateOperationsInput + + No +
+ end + Float | FloatFieldUpdateOperationsInput + + No +
+ text + String | StringFieldUpdateOperationsInput + + No +
+ confidence + Float | NullableFloatFieldUpdateOperationsInput | Null + + Yes +
+
+
+
+

TranscriptionSegmentUncheckedUpdateManyWithoutTranscriptionInput

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String | StringFieldUpdateOperationsInput + + No +
+ index + Int | IntFieldUpdateOperationsInput + + No +
+ start + Float | FloatFieldUpdateOperationsInput + + No +
+ end + Float | FloatFieldUpdateOperationsInput + + No +
+ text + String | StringFieldUpdateOperationsInput + + No +
+ confidence + Float | NullableFloatFieldUpdateOperationsInput | Null + + Yes +
+
+ +
+
+
+

Output Types

+
+ +
+

Transcription

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ text + String + + Yes +
+ language + String + + No +
+ model + String + + Yes +
+ confidence + Float + + No +
+ processingTime + Int + + No +
+ status + String + + Yes +
+ error + String + + No +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ audioFileId + String + + Yes +
+ meetingRecordId + String + + No +
+ segments + TranscriptionSegment[] + + No +
+ _count + TranscriptionCountOutputType + + Yes +
+
+
+
+

TranscriptionSegment

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ index + Int + + Yes +
+ start + Float + + Yes +
+ end + Float + + Yes +
+ text + String + + Yes +
+ confidence + Float + + No +
+ transcriptionId + String + + Yes +
+ transcription + Transcription + + Yes +
+
+
+
+

TranscriptionJob

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ status + String + + Yes +
+ priority + Int + + Yes +
+ model + String + + Yes +
+ language + String + + No +
+ error + String + + No +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ audioFileId + String + + Yes +
+ meetingRecordId + String + + No +
+ transcriptionId + String + + No +
+
+
+
+

CreateManyTranscriptionAndReturnOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ text + String + + Yes +
+ language + String + + No +
+ model + String + + Yes +
+ confidence + Float + + No +
+ processingTime + Int + + No +
+ status + String + + Yes +
+ error + String + + No +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ audioFileId + String + + Yes +
+ meetingRecordId + String + + No +
+
+
+
+

UpdateManyTranscriptionAndReturnOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ text + String + + Yes +
+ language + String + + No +
+ model + String + + Yes +
+ confidence + Float + + No +
+ processingTime + Int + + No +
+ status + String + + Yes +
+ error + String + + No +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ audioFileId + String + + Yes +
+ meetingRecordId + String + + No +
+
+
+
+

CreateManyTranscriptionSegmentAndReturnOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ index + Int + + Yes +
+ start + Float + + Yes +
+ end + Float + + Yes +
+ text + String + + Yes +
+ confidence + Float + + No +
+ transcriptionId + String + + Yes +
+ transcription + Transcription + + Yes +
+
+
+
+

UpdateManyTranscriptionSegmentAndReturnOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ index + Int + + Yes +
+ start + Float + + Yes +
+ end + Float + + Yes +
+ text + String + + Yes +
+ confidence + Float + + No +
+ transcriptionId + String + + Yes +
+ transcription + Transcription + + Yes +
+
+
+
+

CreateManyTranscriptionJobAndReturnOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ status + String + + Yes +
+ priority + Int + + Yes +
+ model + String + + Yes +
+ language + String + + No +
+ error + String + + No +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ audioFileId + String + + Yes +
+ meetingRecordId + String + + No +
+ transcriptionId + String + + No +
+
+
+
+

UpdateManyTranscriptionJobAndReturnOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ status + String + + Yes +
+ priority + Int + + Yes +
+ model + String + + Yes +
+ language + String + + No +
+ error + String + + No +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ audioFileId + String + + Yes +
+ meetingRecordId + String + + No +
+ transcriptionId + String + + No +
+
+
+
+

AggregateTranscription

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ _count + TranscriptionCountAggregateOutputType + + No +
+ _avg + TranscriptionAvgAggregateOutputType + + No +
+ _sum + TranscriptionSumAggregateOutputType + + No +
+ _min + TranscriptionMinAggregateOutputType + + No +
+ _max + TranscriptionMaxAggregateOutputType + + No +
+
+
+
+

TranscriptionGroupByOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ text + String + + Yes +
+ language + String + + No +
+ model + String + + Yes +
+ confidence + Float + + No +
+ processingTime + Int + + No +
+ status + String + + Yes +
+ error + String + + No +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ audioFileId + String + + Yes +
+ meetingRecordId + String + + No +
+ _count + TranscriptionCountAggregateOutputType + + No +
+ _avg + TranscriptionAvgAggregateOutputType + + No +
+ _sum + TranscriptionSumAggregateOutputType + + No +
+ _min + TranscriptionMinAggregateOutputType + + No +
+ _max + TranscriptionMaxAggregateOutputType + + No +
+
+
+
+

AggregateTranscriptionSegment

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ _count + TranscriptionSegmentCountAggregateOutputType + + No +
+ _avg + TranscriptionSegmentAvgAggregateOutputType + + No +
+ _sum + TranscriptionSegmentSumAggregateOutputType + + No +
+ _min + TranscriptionSegmentMinAggregateOutputType + + No +
+ _max + TranscriptionSegmentMaxAggregateOutputType + + No +
+
+
+
+

TranscriptionSegmentGroupByOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ index + Int + + Yes +
+ start + Float + + Yes +
+ end + Float + + Yes +
+ text + String + + Yes +
+ confidence + Float + + No +
+ transcriptionId + String + + Yes +
+ _count + TranscriptionSegmentCountAggregateOutputType + + No +
+ _avg + TranscriptionSegmentAvgAggregateOutputType + + No +
+ _sum + TranscriptionSegmentSumAggregateOutputType + + No +
+ _min + TranscriptionSegmentMinAggregateOutputType + + No +
+ _max + TranscriptionSegmentMaxAggregateOutputType + + No +
+
+
+
+

AggregateTranscriptionJob

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ _count + TranscriptionJobCountAggregateOutputType + + No +
+ _avg + TranscriptionJobAvgAggregateOutputType + + No +
+ _sum + TranscriptionJobSumAggregateOutputType + + No +
+ _min + TranscriptionJobMinAggregateOutputType + + No +
+ _max + TranscriptionJobMaxAggregateOutputType + + No +
+
+
+
+

TranscriptionJobGroupByOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + Yes +
+ status + String + + Yes +
+ priority + Int + + Yes +
+ model + String + + Yes +
+ language + String + + No +
+ error + String + + No +
+ createdAt + DateTime + + Yes +
+ updatedAt + DateTime + + Yes +
+ audioFileId + String + + Yes +
+ meetingRecordId + String + + No +
+ transcriptionId + String + + No +
+ _count + TranscriptionJobCountAggregateOutputType + + No +
+ _avg + TranscriptionJobAvgAggregateOutputType + + No +
+ _sum + TranscriptionJobSumAggregateOutputType + + No +
+ _min + TranscriptionJobMinAggregateOutputType + + No +
+ _max + TranscriptionJobMaxAggregateOutputType + + No +
+
+
+
+

AffectedRowsOutput

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ count + Int + + Yes +
+
+
+
+

TranscriptionCountOutputType

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ segments + Int + + Yes +
+
+
+
+

TranscriptionCountAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + Int + + Yes +
+ text + Int + + Yes +
+ language + Int + + Yes +
+ model + Int + + Yes +
+ confidence + Int + + Yes +
+ processingTime + Int + + Yes +
+ status + Int + + Yes +
+ error + Int + + Yes +
+ createdAt + Int + + Yes +
+ updatedAt + Int + + Yes +
+ audioFileId + Int + + Yes +
+ meetingRecordId + Int + + Yes +
+ _all + Int + + Yes +
+
+
+
+

TranscriptionAvgAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ confidence + Float + + No +
+ processingTime + Float + + No +
+
+
+
+

TranscriptionSumAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ confidence + Float + + No +
+ processingTime + Int + + No +
+
+
+
+

TranscriptionMinAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ text + String + + No +
+ language + String + + No +
+ model + String + + No +
+ confidence + Float + + No +
+ processingTime + Int + + No +
+ status + String + + No +
+ error + String + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ audioFileId + String + + No +
+ meetingRecordId + String + + No +
+
+
+
+

TranscriptionMaxAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ text + String + + No +
+ language + String + + No +
+ model + String + + No +
+ confidence + Float + + No +
+ processingTime + Int + + No +
+ status + String + + No +
+ error + String + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ audioFileId + String + + No +
+ meetingRecordId + String + + No +
+
+
+
+

TranscriptionSegmentCountAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + Int + + Yes +
+ index + Int + + Yes +
+ start + Int + + Yes +
+ end + Int + + Yes +
+ text + Int + + Yes +
+ confidence + Int + + Yes +
+ transcriptionId + Int + + Yes +
+ _all + Int + + Yes +
+
+
+
+

TranscriptionSegmentAvgAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ index + Float + + No +
+ start + Float + + No +
+ end + Float + + No +
+ confidence + Float + + No +
+
+
+
+

TranscriptionSegmentSumAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ index + Int + + No +
+ start + Float + + No +
+ end + Float + + No +
+ confidence + Float + + No +
+
+
+
+

TranscriptionSegmentMinAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ index + Int + + No +
+ start + Float + + No +
+ end + Float + + No +
+ text + String + + No +
+ confidence + Float + + No +
+ transcriptionId + String + + No +
+
+
+
+

TranscriptionSegmentMaxAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ index + Int + + No +
+ start + Float + + No +
+ end + Float + + No +
+ text + String + + No +
+ confidence + Float + + No +
+ transcriptionId + String + + No +
+
+
+
+

TranscriptionJobCountAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + Int + + Yes +
+ status + Int + + Yes +
+ priority + Int + + Yes +
+ model + Int + + Yes +
+ language + Int + + Yes +
+ error + Int + + Yes +
+ createdAt + Int + + Yes +
+ updatedAt + Int + + Yes +
+ audioFileId + Int + + Yes +
+ meetingRecordId + Int + + Yes +
+ transcriptionId + Int + + Yes +
+ _all + Int + + Yes +
+
+
+
+

TranscriptionJobAvgAggregateOutputType

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ priority + Float + + No +
+
+
+
+

TranscriptionJobSumAggregateOutputType

+ + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ priority + Int + + No +
+
+
+
+

TranscriptionJobMinAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ status + String + + No +
+ priority + Int + + No +
+ model + String + + No +
+ language + String + + No +
+ error + String + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ audioFileId + String + + No +
+ meetingRecordId + String + + No +
+ transcriptionId + String + + No +
+
+
+
+

TranscriptionJobMaxAggregateOutputType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeNullable
+ id + String + + No +
+ status + String + + No +
+ priority + Int + + No +
+ model + String + + No +
+ language + String + + No +
+ error + String + + No +
+ createdAt + DateTime + + No +
+ updatedAt + DateTime + + No +
+ audioFileId + String + + No +
+ meetingRecordId + String + + No +
+ transcriptionId + String + + No +
+
+ +
+
+
+
+ +
+
+
+
+ + diff --git a/services/transcription/db/docs/styles/main.css b/services/transcription/db/docs/styles/main.css new file mode 100644 index 0000000..78f97c8 --- /dev/null +++ b/services/transcription/db/docs/styles/main.css @@ -0,0 +1 @@ +/*! tailwindcss v3.2.6 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}html{-webkit-text-size-adjust:100%;font-feature-settings:normal;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]{display:none}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.sticky{position:sticky}.top-0{top:0}.my-16{margin-bottom:4rem;margin-top:4rem}.my-4{margin-bottom:1rem;margin-top:1rem}.my-8{margin-bottom:2rem;margin-top:2rem}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-4{margin-left:1rem}.mr-4{margin-right:1rem}.mt-1{margin-top:.25rem}.mt-12{margin-top:3rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.flex{display:flex}.table{display:table}.h-screen{height:100vh}.min-h-screen{min-height:100vh}.w-1\/5{width:20%}.w-full{width:100%}.flex-shrink-0{flex-shrink:0}.table-auto{table-layout:auto}.overflow-auto{overflow:auto}.overflow-x-hidden{overflow-x:hidden}.border{border-width:1px}.border-l-2{border-left-width:2px}.border-gray-400{--tw-border-opacity:1;border-color:rgb(156 163 175/var(--tw-border-opacity))}.bg-gray-200{--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.p-4{padding:1rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.pl-3{padding-left:.75rem}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-lg{font-size:1.125rem}.text-lg,.text-xl{line-height:1.75rem}.text-xl{font-size:1.25rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity))}.text-gray-800{--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity))}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}body{--code-inner-color:#718096;--code-token1-color:#d5408c;--code-token2-color:#805ad5;--code-token3-color:#319795;--code-token4-color:#dd6b21;--code-token5-color:#690;--code-token6-color:#9a6e3a;--code-token7-color:#e90;--code-linenum-color:#cbd5e0;--code-added-color:#47bb78;--code-added-bg-color:#d9f4e6;--code-deleted-color:#e53e3e;--code-deleted-bg-color:#f5e4e7;--code-highlight-color:#a0aec0;--code-highlight-bg-color:#e2e8f0;--code-result-bg-color:#e7edf3;--main-font-color:#1a202c;--border-color:#e2e8f0;--code-bgd-color:#f6f8fa}code[class*=language-],pre[class*=language-],pre[class*=language-] code{word-wrap:normal;border-radius:8px;color:var(--main-font-color)!important;display:block;font-family:Roboto Mono,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:14px;font-variant:no-common-ligatures no-discretionary-ligatures no-historical-ligatures no-contextual;grid-template-rows:max-content;-webkit-hyphens:none;hyphens:none;line-height:1.5;overflow:auto;-moz-tab-size:4;-o-tab-size:4;tab-size:4;text-align:left;white-space:pre;width:100%;word-break:normal;word-spacing:normal}pre[class*=language-]{border-radius:1em;margin:0;overflow:auto;padding:1em}:not(pre)>code[class*=language-],pre[class*=language-]{background:var(--code-bgd-color)!important}:not(pre)>code[class*=language-]{border-radius:.3em;padding:.1em;white-space:normal}.inline-code,code.inline-code{font-feature-settings:"clig" 0,"calt" 0;background:var(--code-inline-bgd-color);border-radius:5px;color:var(--main-font-color);display:inline;font-family:Roboto Mono;font-size:14px;font-style:normal;font-variant:no-common-ligatures no-discretionary-ligatures no-historical-ligatures no-contextual;font-weight:500;line-height:24px;padding:.05em .3em .2em;vertical-align:baseline}.inline-code{background-color:var(--border-color)}.top-section h1 inlinecode{font-size:2rem}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:var(--code-inner-color)!important;font-style:normal!important}.token.namespace{opacity:.7}.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag,.token.type-args{color:var(--code-token4-color)!important}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:var(--code-token5-color)!important}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:var(--code-token6-color)!important}.token.atrule,.token.attr-value,.token.keyword{color:var(--code-token1-color)!important}.token.boolean,.token.class-name,.token.function,.token[class*=class-name]{color:var(--code-token2-color)!important}.token.important,.token.regex,.token.variable{color:var(--code-token7-color)!important}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.annotation{color:var(--code-token3-color)!important} \ No newline at end of file diff --git a/documents/data/index.ts b/services/transcription/db/index.ts similarity index 52% rename from documents/data/index.ts rename to services/transcription/db/index.ts index 282b3b9..4adb9a1 100644 --- a/documents/data/index.ts +++ b/services/transcription/db/index.ts @@ -1,17 +1,13 @@ +import { PrismaClient } from "@prisma/client/transcription/index.js"; + import { SQLDatabase } from "encore.dev/storage/sqldb"; -import { PrismaClient } from "@prisma/client/documents/index.js"; -import { Bucket } from "encore.dev/storage/objects"; + +export type { Prisma } from "@prisma/client/transcription/index.js"; // Define the database connection -const psql = new SQLDatabase("documents", { +const psql = new SQLDatabase("transcription", { migrations: { path: "./migrations", source: "prisma" }, }); // Initialize Prisma client with the Encore-managed connection string export const db = new PrismaClient({ datasourceUrl: psql.connectionString }); - -// Create documents bucket -export const agendas = new Bucket("agendas", { - versioned: false, - public: true, -}); diff --git a/services/transcription/db/migrations/20250312094957_init/migration.sql b/services/transcription/db/migrations/20250312094957_init/migration.sql new file mode 100644 index 0000000..f1582e8 --- /dev/null +++ b/services/transcription/db/migrations/20250312094957_init/migration.sql @@ -0,0 +1,50 @@ +-- CreateTable +CREATE TABLE "Transcription" ( + "id" TEXT NOT NULL, + "text" TEXT NOT NULL, + "language" TEXT, + "model" TEXT NOT NULL, + "confidence" DOUBLE PRECISION, + "processingTime" INTEGER, + "status" TEXT NOT NULL, + "error" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + "audioFileId" TEXT NOT NULL, + "meetingRecordId" TEXT, + + CONSTRAINT "Transcription_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "TranscriptionSegment" ( + "id" TEXT NOT NULL, + "index" INTEGER NOT NULL, + "start" DOUBLE PRECISION NOT NULL, + "end" DOUBLE PRECISION NOT NULL, + "text" TEXT NOT NULL, + "confidence" DOUBLE PRECISION, + "transcriptionId" TEXT NOT NULL, + + CONSTRAINT "TranscriptionSegment_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "TranscriptionJob" ( + "id" TEXT NOT NULL, + "status" TEXT NOT NULL, + "priority" INTEGER NOT NULL DEFAULT 0, + "model" TEXT NOT NULL, + "language" TEXT, + "error" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + "audioFileId" TEXT NOT NULL, + "meetingRecordId" TEXT, + "transcriptionId" TEXT, + + CONSTRAINT "TranscriptionJob_pkey" PRIMARY KEY ("id") +); + +-- AddForeignKey +ALTER TABLE "TranscriptionSegment" ADD CONSTRAINT "TranscriptionSegment_transcriptionId_fkey" FOREIGN KEY ("transcriptionId") REFERENCES "Transcription"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/services/transcription/db/migrations/migration_lock.toml b/services/transcription/db/migrations/migration_lock.toml new file mode 100644 index 0000000..51afaec --- /dev/null +++ b/services/transcription/db/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# This file is automatically generated by Prisma. +# Manual changes to this file will be lost when running Prisma migrations. +provider = "postgresql" \ No newline at end of file diff --git a/services/transcription/db/models/db.ts b/services/transcription/db/models/db.ts new file mode 100644 index 0000000..2777916 --- /dev/null +++ b/services/transcription/db/models/db.ts @@ -0,0 +1,42 @@ +// DO NOT EDIT — Auto-generated file; see https://github.com/mogzol/prisma-generator-typescript-interfaces + +export type TranscriptionModel = { + id: string; + text: string; + language: string | null; + model: string; + confidence: number | null; + processingTime: number | null; + status: string; + error: string | null; + createdAt: Date; + updatedAt: Date; + audioFileId: string; + meetingRecordId: string | null; + segments?: TranscriptionSegmentModel[]; +}; + +export type TranscriptionSegmentModel = { + id: string; + index: number; + start: number; + end: number; + text: string; + confidence: number | null; + transcriptionId: string; + transcription?: TranscriptionModel; +}; + +export type TranscriptionJobModel = { + id: string; + status: string; + priority: number; + model: string; + language: string | null; + error: string | null; + createdAt: Date; + updatedAt: Date; + audioFileId: string; + meetingRecordId: string | null; + transcriptionId: string | null; +}; diff --git a/services/transcription/db/models/dto.ts b/services/transcription/db/models/dto.ts new file mode 100644 index 0000000..a0d6e30 --- /dev/null +++ b/services/transcription/db/models/dto.ts @@ -0,0 +1,42 @@ +// DO NOT EDIT — Auto-generated file; see https://github.com/mogzol/prisma-generator-typescript-interfaces + +export type TranscriptionDto = { + id: string; + text: string; + language: string | null; + model: string; + confidence: number | null; + processingTime: number | null; + status: string; + error: string | null; + createdAt: string; + updatedAt: string; + audioFileId: string; + meetingRecordId: string | null; + segments?: TranscriptionSegmentDto[]; +}; + +export type TranscriptionSegmentDto = { + id: string; + index: number; + start: number; + end: number; + text: string; + confidence: number | null; + transcriptionId: string; + transcription?: TranscriptionDto; +}; + +export type TranscriptionJobDto = { + id: string; + status: string; + priority: number; + model: string; + language: string | null; + error: string | null; + createdAt: string; + updatedAt: string; + audioFileId: string; + meetingRecordId: string | null; + transcriptionId: string | null; +}; diff --git a/services/transcription/db/models/json.ts b/services/transcription/db/models/json.ts new file mode 100644 index 0000000..e69de29 diff --git a/services/transcription/db/schema.prisma b/services/transcription/db/schema.prisma new file mode 100644 index 0000000..9b79465 --- /dev/null +++ b/services/transcription/db/schema.prisma @@ -0,0 +1,106 @@ +// This is your Prisma schema file for this service, +// learn more about it in the docs: https://pris.ly/d/prisma-schema + +generator client { + provider = "prisma-client-js" + previewFeatures = ["driverAdapters", "metrics"] + binaryTargets = ["native", "debian-openssl-3.0.x"] + output = "../../node_modules/@prisma/client/transcription" +} + +generator json { + provider = "prisma-json-types-generator" + engineType = "library" + clientOutput = "../../../node_modules/@prisma/client/transcription" +} + +generator docs { + provider = "node node_modules/prisma-docs-generator" + output = "./docs" +} + +generator markdown { + provider = "prisma-markdown" + output = "./docs/README.md" + title = "Transcription Service Database Schema" +} + +generator typescriptInterfaces { + provider = "prisma-generator-typescript-interfaces" + modelType = "type" + enumType = "object" + headerComment = "DO NOT EDIT — Auto-generated file; see https://github.com/mogzol/prisma-generator-typescript-interfaces" + modelSuffix = "Model" + output = "./models/db.ts" + prettier = true +} + +generator typescriptInterfacesJson { + provider = "prisma-generator-typescript-interfaces" + modelType = "type" + enumType = "stringUnion" + enumPrefix = "$" + headerComment = "DO NOT EDIT — Auto-generated file; see https://github.com/mogzol/prisma-generator-typescript-interfaces" + output = "./models/dto.ts" + modelSuffix = "Dto" + dateType = "string" + bigIntType = "string" + decimalType = "string" + bytesType = "ArrayObject" + prettier = true +} + +datasource db { + provider = "postgresql" + url = env("TRANSCRIPTION_DATABASE_URL") +} + +// Models related to transcription processing + +model Transcription { + id String @id @default(ulid()) + text String + language String? // Detected or specified language + model String // The model used for transcription (e.g., "whisper-1") + confidence Float? // Confidence score of the transcription (0-1) + processingTime Int? // Time taken to process in seconds + status String // queued, processing, completed, failed + error String? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + // References to related records + audioFileId String // Reference to MediaFile in media service + meetingRecordId String? // Reference to MeetingRecord in TGov service + + // Segments for time-aligned transcription + segments TranscriptionSegment[] +} + +model TranscriptionSegment { + id String @id @default(ulid()) + index Int // Segment index in the transcription + start Float // Start time in seconds + end Float // End time in seconds + text String // Text content of this segment + confidence Float? // Confidence score for this segment + + transcriptionId String + transcription Transcription @relation(fields: [transcriptionId], references: [id], onDelete: Cascade) +} + +model TranscriptionJob { + id String @id @default(ulid()) + status String // queued, processing, completed, failed + priority Int @default(0) + model String // The model to use (e.g., "whisper-1") + language String? // Optional language hint + error String? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + // References + audioFileId String // Reference to MediaFile in media service + meetingRecordId String? // Reference to MeetingRecord in TGov service + transcriptionId String? // Reference to resulting Transcription +} diff --git a/services/transcription/encore.service.ts b/services/transcription/encore.service.ts new file mode 100644 index 0000000..3ade607 --- /dev/null +++ b/services/transcription/encore.service.ts @@ -0,0 +1,11 @@ +import { Service } from "encore.dev/service"; + +/** + * Transcription service for converting audio to text + * + * This service is responsible for: + * - Converting audio files to text using the Whisper API + * - Storing and retrieving transcriptions + * - Managing the transcription workflow + */ +export default new Service("transcription"); \ No newline at end of file diff --git a/services/transcription/index.ts b/services/transcription/index.ts new file mode 100644 index 0000000..a47b246 --- /dev/null +++ b/services/transcription/index.ts @@ -0,0 +1,551 @@ +import fs from "fs"; +import os from "os"; +import path from "path"; +import { Readable } from "stream"; + +import env from "../../env"; +import { JobStatus } from "../enums"; +import { db } from "./db"; +import { WhisperClient } from "./whisperClient"; + +import { media } from "~encore/clients"; + +import { api, APIError } from "encore.dev/api"; +import { CronJob } from "encore.dev/cron"; +import log from "encore.dev/log"; + +/** Represents a time-aligned segment in a transcription */ +export interface TranscriptionSegment { + /** * Segment index in the transcription */ + index: number; + /** * Start time in seconds */ + start: number; + /** * End time in seconds */ + end: number; + /** * Text content of this segment */ + text: string; + /** + * Confidence score for this segment (0-1) + */ + confidence?: number; +} + +/** Complete transcription result with metadata */ +export interface TranscriptionResult { + /** * Unique identifier for the transcription */ + id: string; + /** * Complete transcribed text */ + text: string; + /** * Detected or specified language */ + language?: string; + /** * The model used for transcription (e.g., "whisper-1") */ + model: string; + /** * Overall confidence score of the transcription (0-1) */ + confidence?: number; + /** * Time taken to process in seconds */ + processingTime?: number; + /** * Current status of the transcription */ + status: string; + /** * Error message if the transcription failed */ + error?: string; + /** * When the transcription was created */ + createdAt: Date; + /** * When the transcription was last updated */ + updatedAt: Date; + /** * ID of the audio file that was transcribed */ + audioFileId: string; + /** * ID of the meeting record this transcription belongs to */ + meetingRecordId?: string; + /** + * Time-aligned segments of the transcription + */ + segments?: TranscriptionSegment[]; +} + +/** Request parameters for creating a new transcription */ +export interface TranscriptionRequest { + /** * ID of the audio file to transcribe */ + audioFileId: string; + /** * Optional ID of the meeting record this transcription belongs to */ + meetingRecordId?: string; + /** * The model to use for transcription (default: "whisper-1") */ + model?: string; + /** * Optional language hint for the transcription */ + language?: string; + /** + * Optional priority for job processing (higher values = higher priority) + */ + priority?: number; +} + +/** Response from transcription job operations */ +export interface TranscriptionResponse { + /** * Unique identifier for the job */ + jobId: string; + /** * Current status of the job */ + status: string; + /** * ID of the resulting transcription (available when completed) */ + transcriptionId?: string; + /** + * Error message if the job failed + */ + error?: string; +} + +// Initialize the Whisper client +const whisperClient = new WhisperClient({ + apiKey: env.OPENAI_API_KEY, + defaultModel: "whisper-1", +}); + +/** API to request a transcription for an audio file */ +export const transcribe = api( + { + method: "POST", + path: "/transcribe", + expose: true, + }, + async (req: TranscriptionRequest): Promise => { + const { audioFileId, meetingRecordId, model, language, priority } = req; + + // Validate that the audio file exists + try { + const audioFile = await media.getMediaInfo({ mediaFileId: audioFileId }); + if (!audioFile) { + throw APIError.notFound(`Audio file ${audioFileId} not found`); + } + } catch (error) { + log.error("Failed to verify audio file existence", { + audioFileId, + error: error instanceof Error ? error.message : String(error), + }); + throw APIError.internal("Failed to verify audio file existence"); + } + + // Create a transcription job in the database + try { + const job = await db.transcriptionJob.create({ + data: { + status: JobStatus.QUEUED, + priority: priority || 0, + model: model || "whisper-1", + language, + audioFileId, + meetingRecordId, + }, + }); + + // Start processing the job asynchronously + processJob(job.id).catch((error) => { + log.error(`Error processing job ${job.id}:`, { + jobId: job.id, + error: error instanceof Error ? error.message : String(error), + }); + }); + + log.info("Created transcription job", { + jobId: job.id, + audioFileId, + meetingRecordId, + model: model || "whisper-1", + }); + + return { + jobId: job.id, + status: JobStatus.QUEUED, + }; + } catch (error) { + log.error("Failed to create transcription job", { + audioFileId, + error: error instanceof Error ? error.message : String(error), + }); + throw APIError.internal("Failed to create transcription job"); + } + }, +); + +/** API to get the status of a transcription job */ +export const getJobStatus = api( + { + method: "GET", + path: "/jobs/:jobId", + expose: true, + }, + async (req: { jobId: string }): Promise => { + const { jobId } = req; + + try { + const job = await db.transcriptionJob.findUnique({ + where: { id: jobId }, + }); + + if (!job) { + throw APIError.notFound(`Job ${jobId} not found`); + } + + return { + jobId: job.id, + status: job.status as JobStatus, + transcriptionId: job.transcriptionId || undefined, + error: job.error || undefined, + }; + } catch (error) { + if (error instanceof APIError) { + throw error; + } + log.error("Failed to get job status", { + jobId, + error: error instanceof Error ? error.message : String(error), + }); + throw APIError.internal("Failed to get job status"); + } + }, +); + +/** API to get a transcription by ID */ +export const getTranscription = api( + { + method: "GET", + path: "/transcriptions/:transcriptionId", + expose: true, + }, + async (req: { transcriptionId: string }): Promise => { + const { transcriptionId } = req; + + try { + const transcription = await db.transcription.findUnique({ + where: { id: transcriptionId }, + include: { segments: true }, + }); + + if (!transcription) { + throw APIError.notFound(`Transcription ${transcriptionId} not found`); + } + + return { + id: transcription.id, + text: transcription.text, + language: transcription.language || undefined, + model: transcription.model, + confidence: transcription.confidence || undefined, + processingTime: transcription.processingTime || undefined, + status: transcription.status as JobStatus, + error: transcription.error || undefined, + createdAt: transcription.createdAt, + updatedAt: transcription.updatedAt, + audioFileId: transcription.audioFileId, + meetingRecordId: transcription.meetingRecordId || undefined, + segments: transcription.segments.map((segment) => ({ + index: segment.index, + start: segment.start, + end: segment.end, + text: segment.text, + confidence: segment.confidence || undefined, + })), + }; + } catch (error) { + if (error instanceof APIError) { + throw error; + } + log.error("Failed to get transcription", { + transcriptionId, + error: error instanceof Error ? error.message : String(error), + }); + throw APIError.internal("Failed to get transcription"); + } + }, +); + +/** API to get all transcriptions for a meeting */ +export const getMeetingTranscriptions = api( + { + method: "GET", + path: "/meetings/:meetingId/transcriptions", + expose: true, + }, + async (req: { + meetingId: string; + }): Promise<{ transcriptions: TranscriptionResult[] }> => { + const { meetingId } = req; + + try { + const transcriptions = await db.transcription.findMany({ + where: { meetingRecordId: meetingId }, + include: { segments: true }, + }); + + return { + transcriptions: transcriptions.map((transcription) => ({ + id: transcription.id, + text: transcription.text, + language: transcription.language || undefined, + model: transcription.model, + confidence: transcription.confidence || undefined, + processingTime: transcription.processingTime || undefined, + status: transcription.status as JobStatus, + error: transcription.error || undefined, + createdAt: transcription.createdAt, + updatedAt: transcription.updatedAt, + audioFileId: transcription.audioFileId, + meetingRecordId: transcription.meetingRecordId || undefined, + segments: transcription.segments.map((segment) => ({ + index: segment.index, + start: segment.start, + end: segment.end, + text: segment.text, + confidence: segment.confidence || undefined, + })), + })), + }; + } catch (error) { + log.error("Failed to get meeting transcriptions", { + meetingId, + error: error instanceof Error ? error.message : String(error), + }); + throw APIError.internal("Failed to get meeting transcriptions"); + } + }, +); + +/** + * Scheduled job to process any queued transcription jobs + * // TODO: TEST THIS + */ +export const processQueuedJobs = api( + { + method: "POST", + expose: false, + }, + async (): Promise<{ processed: number }> => { + const queuedJobs = await db.transcriptionJob.findMany({ + where: { + status: JobStatus.QUEUED, + }, + orderBy: [{ priority: "desc" }, { createdAt: "asc" }], + take: 10, // Process in batches to avoid overloading + }); + + log.info(`Found ${queuedJobs.length} queued jobs to process`); + + for (const job of queuedJobs) { + processJob(job.id).catch((error) => { + log.error(`Error processing job ${job.id}:`, { + jobId: job.id, + error: error instanceof Error ? error.message : String(error), + }); + }); + } + + return { processed: queuedJobs.length }; + }, +); + +/** + * Schedule job processing every 5 minutes + */ +export const jobProcessorCron = new CronJob("transcription-job-processor", { + title: "Process queued transcription jobs", + endpoint: processQueuedJobs, + every: "5m", +}); + +/** + * Process a transcription job + * This function is called asynchronously after a job is created + */ +async function processJob(jobId: string): Promise { + // Mark the job as processing + try { + await db.transcriptionJob.update({ + where: { id: jobId }, + data: { status: "processing" }, + }); + } catch (error) { + log.error(`Failed to update job ${jobId} status to processing`, { + jobId, + error: error instanceof Error ? error.message : String(error), + }); + return; + } + + let tempDir: string | null = null; + + try { + // Get the job details + const job = await db.transcriptionJob.findUnique({ + where: { id: jobId }, + }); + + if (!job) { + throw new Error(`Job ${jobId} not found`); + } + + // Get the audio file details from the media service + const audioFile = await media.getMediaInfo({ + mediaFileId: job.audioFileId, + }); + + if (!audioFile || !audioFile.url) { + throw new Error(`Audio file ${job.audioFileId} not found or has no URL`); + } + + // Create a temporary directory for the audio file + tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "transcription-")); + const audioPath = path.join(tempDir, "audio.mp3"); + + // Download the audio file + await downloadFile(audioFile.url, audioPath); + log.info(`Downloaded audio file for job ${jobId}`, { + jobId, + audioFileId: job.audioFileId, + tempDir, + }); + + // Transcribe the audio file + const startTime = Date.now(); + const whisperResponse = await whisperClient.transcribeFile(audioPath, { + model: job.model, + language: job.language || undefined, + }); + const processingTime = Math.floor((Date.now() - startTime) / 1000); + + log.info(`Successfully transcribed audio for job ${jobId}`, { + jobId, + processingTime, + textLength: whisperResponse.text.length, + segmentsCount: whisperResponse.segments?.length || 0, + }); + + // Calculate average confidence if segments available + const averageConfidence = + whisperResponse.segments && whisperResponse.segments.length > 0 ? + whisperResponse.segments.reduce( + (sum, seg) => sum + (seg.confidence || 0), + 0, + ) / whisperResponse.segments.length + : undefined; + + // Create the transcription record + const transcription = await db.transcription.create({ + include: { segments: true }, + data: { + text: whisperResponse.text, + language: whisperResponse.language, + model: job.model, + confidence: averageConfidence, + processingTime, + status: JobStatus.COMPLETED, + audioFileId: job.audioFileId, + meetingRecordId: job.meetingRecordId, + segments: { + create: + whisperResponse.segments?.map((segment) => ({ + index: segment.index, + start: segment.start, + end: segment.end, + text: segment.text, + confidence: segment.confidence, + })) || [], + }, + }, + }); + + // Update the job with the transcription ID + await db.transcriptionJob.update({ + where: { id: jobId }, + data: { + status: JobStatus.COMPLETED, + transcriptionId: transcription.id, + }, + }); + + log.info(`Completed transcription job ${jobId}`, { + jobId, + transcriptionId: transcription.id, + segments: transcription.segments.length > 0 ? "created" : "none", + }); + } catch (error) { + const errorMessage = error instanceof Error ? error.message : String(error); + log.error(`Error processing job ${jobId}:`, { + jobId, + error: errorMessage, + }); + + // Update the job with the error + await db.transcriptionJob.update({ + where: { id: jobId }, + data: { + status: JobStatus.FAILED, + error: errorMessage, + }, + }); + } finally { + // Clean up temporary files + if (tempDir) { + try { + fs.rmSync(tempDir, { recursive: true, force: true }); + log.debug(`Cleaned up temporary directory for job ${jobId}`, { + jobId, + tempDir, + }); + } catch (error) { + log.error(`Failed to clean up temporary directory for job ${jobId}:`, { + jobId, + tempDir, + error: error instanceof Error ? error.message : String(error), + }); + } + } + } +} + +/** + * Utility function to download a file + */ +async function downloadFile(url: string, destination: string): Promise { + log.debug(`Downloading file from ${url} to ${destination}`); + + try { + const response = await fetch(url); + + if (!response.ok) { + throw new Error( + `Failed to download file: ${response.status} ${response.statusText}`, + ); + } + + const fileStream = fs.createWriteStream(destination); + + return new Promise((resolve, reject) => { + if (!response.body) { + reject(new Error("Response body is null")); + return; + } + + // Convert Web ReadableStream to Node Readable stream + const readableStream = Readable.fromWeb( + response.body as import("stream/web").ReadableStream, + ); + const writableStream = fs.createWriteStream(destination); + + readableStream.pipe(writableStream); + + writableStream.on("finish", () => { + resolve(); + }); + + writableStream.on("error", (err) => { + fs.unlink(destination, () => { + reject(err); + }); + }); + }); + } catch (error) { + log.error(`Error downloading file from ${url}`, { + url, + destination, + error: error instanceof Error ? error.message : String(error), + }); + throw error; + } +} diff --git a/services/transcription/whisperClient.ts b/services/transcription/whisperClient.ts new file mode 100644 index 0000000..e26ed47 --- /dev/null +++ b/services/transcription/whisperClient.ts @@ -0,0 +1,402 @@ +import { exec as execCallback } from "child_process"; +import fs from "fs"; +import path from "path"; +import { promisify } from "util"; + +import { TranscriptionSegment } from "./index"; + +import logger from "encore.dev/log"; + +import OpenAI from "openai/index.js"; + +const exec = promisify(execCallback); + +export interface WhisperClientOptions { + apiKey: string; + defaultModel?: string; +} + +export interface WhisperTranscriptionOptions { + model?: string; + language?: string; + responseFormat?: "json" | "text" | "srt" | "verbose_json" | "vtt"; + prompt?: string; + temperature?: number; +} + +export interface WhisperResponse { + text: string; + language?: string; + segments?: TranscriptionSegment[]; + duration?: number; +} + +// Size in bytes (25MB - 1MB buffer to be safe) +const MAX_FILE_SIZE = 24 * 1024 * 1024; +// Default chunk duration in seconds (10 minutes) +const DEFAULT_CHUNK_DURATION = 10 * 60; + +/** + * Client for interacting with OpenAI's Whisper API for audio transcription + */ +export class WhisperClient { + #client: OpenAI; + #defaultModel: string; + + /** + * Create a new WhisperClient instance + * + * @param options Configuration options for the client + */ + constructor(options: WhisperClientOptions) { + if (!options.apiKey) { + throw new Error("OpenAI API key is required"); + } + + this.#client = new OpenAI({ + apiKey: options.apiKey, + }); + this.#defaultModel = options.defaultModel || "whisper-1"; + + logger.info("WhisperClient initialized", { + model: this.#defaultModel, + }); + } + + /** + * Transcribe an audio file using the OpenAI Whisper API + * If file size exceeds the maximum allowed, it will be chunked + * + * @param audioFilePath Path to the audio file + * @param options Transcription options + * @returns Transcription result + */ + async transcribeFile( + audioFilePath: string, + options: WhisperTranscriptionOptions = {}, + ): Promise { + const startTime = Date.now(); + + if (!fs.existsSync(audioFilePath)) { + throw new Error(`Audio file not found: ${audioFilePath}`); + } + + const fileSize = fs.statSync(audioFilePath).size; + logger.info("Starting transcription", { + audioFilePath, + fileSize, + model: options.model || this.#defaultModel, + language: options.language, + }); + + // If file is smaller than the maximum size, transcribe directly + if (fileSize <= MAX_FILE_SIZE) { + return this.#transcribeChunk(audioFilePath, options); + } + + // For larger files, split into chunks and process sequentially + logger.info("File exceeds maximum size, splitting into chunks", { + audioFilePath, + fileSize, + maxSize: MAX_FILE_SIZE, + }); + + return this.#transcribeWithChunking(audioFilePath, options); + } + + /** + * Transcribe a single chunk of audio + * + * @param chunkPath Path to the audio chunk + * @param options Transcription options + * @returns Transcription result + */ + async #transcribeChunk( + chunkPath: string, + options: WhisperTranscriptionOptions = {}, + ): Promise { + const fileStream = fs.createReadStream(chunkPath); + + try { + const response = await this.#client.audio.transcriptions.create({ + file: fileStream, + model: options.model || this.#defaultModel, + language: options.language, + response_format: options.responseFormat || "verbose_json", + prompt: options.prompt, + temperature: options.temperature, + }); + + if ( + options.responseFormat === "verbose_json" || + options.responseFormat === undefined + ) { + // Cast to any since the OpenAI types don't include the verbose_json format + const verboseResponse = response as any; + return { + text: verboseResponse.text, + language: verboseResponse.language, + duration: verboseResponse.duration, + segments: verboseResponse.segments.map( + (segment: any, index: number) => ({ + index, + start: segment.start, + end: segment.end, + text: segment.text, + confidence: segment.confidence, + }), + ), + }; + } + + return { + text: response.text, + }; + } catch (error) { + const errorMessage = + error instanceof Error ? error.message : String(error); + logger.error("Error transcribing chunk", { + chunkPath, + error: errorMessage, + model: options.model || this.#defaultModel, + }); + throw error; + } finally { + fileStream.destroy(); + } + } + + /** + * Split an audio file into smaller chunks and transcribe them sequentially + * + * @param audioFilePath Path to the audio file + * @param options Transcription options + * @returns Combined transcription result + */ + async #transcribeWithChunking( + audioFilePath: string, + options: WhisperTranscriptionOptions = {}, + ): Promise { + const startTime = Date.now(); + const tempDir = path.dirname(audioFilePath); + const fileName = path.basename(audioFilePath, path.extname(audioFilePath)); + + // Get audio duration using ffprobe + const { audioDuration, audioInfo } = + await this.#getAudioInfo(audioFilePath); + + logger.info("Audio file information", { + audioDuration, + audioInfo, + }); + + // Calculate optimal chunk size based on file size and duration + const chunkDuration = this.#calculateChunkDuration( + audioFilePath, + audioDuration, + ); + const totalChunks = Math.ceil(audioDuration / chunkDuration); + + logger.info("Splitting audio into chunks", { + totalChunks, + chunkDuration, + audioDuration, + }); + + // Create chunks + const chunkFiles: string[] = []; + for (let i = 0; i < totalChunks; i++) { + const startOffset = i * chunkDuration; + const chunkPath = path.join(tempDir, `${fileName}_chunk${i + 1}.mp3`); + chunkFiles.push(chunkPath); + + await this.#extractAudioChunk( + audioFilePath, + chunkPath, + startOffset, + chunkDuration, + ); + + logger.info(`Created chunk ${i + 1}/${totalChunks}`, { + chunkPath, + startOffset, + duration: chunkDuration, + }); + } + + // Process each chunk sequentially with context from previous chunk + let combinedResult: WhisperResponse = { + text: "", + segments: [], + duration: 0, + }; + + let previousText = ""; + + try { + for (let i = 0; i < chunkFiles.length; i++) { + logger.info(`Processing chunk ${i + 1}/${chunkFiles.length}`); + + // Add context from previous chunk to improve continuity + const chunkOptions = { ...options }; + if (i > 0 && previousText) { + // Use last few sentences from previous chunk as prompt for context + const contextText = this.#extractContextFromText(previousText); + chunkOptions.prompt = contextText; + logger.debug("Using context for chunk", { + contextLength: contextText.length, + }); + } + + // Transcribe the current chunk + const chunkResult = await this.#transcribeChunk( + chunkFiles[i], + chunkOptions, + ); + previousText = chunkResult.text; + + // Adjust segment timings for subsequent chunks + const timeOffset = i * chunkDuration; + if (chunkResult.segments && chunkResult.segments.length > 0) { + chunkResult.segments.forEach((segment) => { + segment.start += timeOffset; + segment.end += timeOffset; + }); + } + + // Merge results + combinedResult.text += (i > 0 ? " " : "") + chunkResult.text; + combinedResult.language = + chunkResult.language || combinedResult.language; + combinedResult.duration = + (combinedResult.duration || 0) + (chunkResult.duration || 0); + + if (chunkResult.segments && chunkResult.segments.length > 0) { + const baseIndex = combinedResult.segments?.length || 0; + const adjustedSegments = chunkResult.segments.map((segment, idx) => ({ + ...segment, + index: baseIndex + idx, + })); + + combinedResult.segments = [ + ...(combinedResult.segments || []), + ...adjustedSegments, + ]; + } + } + + const processingTime = (Date.now() - startTime) / 1000; + logger.info("Chunked transcription completed", { + processingTime, + chunks: chunkFiles.length, + totalText: combinedResult.text.length, + totalSegments: combinedResult.segments?.length || 0, + }); + + return combinedResult; + } finally { + // Clean up chunk files + for (const chunkFile of chunkFiles) { + try { + fs.unlinkSync(chunkFile); + } catch (error) { + logger.warn(`Failed to delete chunk file: ${chunkFile}`, { error }); + } + } + } + } + + /** + * Get audio file duration and information using ffprobe + */ + async #getAudioInfo( + filePath: string, + ): Promise<{ audioDuration: number; audioInfo: string }> { + try { + const { stdout } = await exec( + `ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "${filePath}"`, + ); + + const audioDuration = parseFloat(stdout.trim()); + + // Get more detailed info for debugging + const { stdout: infoStdout } = await exec( + `ffprobe -v error -show_entries format=size,duration,bit_rate -show_entries stream=codec_name,sample_rate,channels -of default=noprint_wrappers=1 "${filePath}"`, + ); + + return { + audioDuration: isNaN(audioDuration) ? 0 : audioDuration, + audioInfo: infoStdout.trim(), + }; + } catch (error) { + logger.error("Failed to get audio duration", { error }); + return { audioDuration: 0, audioInfo: "Unknown" }; + } + } + + /** + * Calculate optimal chunk duration based on file size and duration + */ + #calculateChunkDuration(filePath: string, totalDuration: number): number { + if (totalDuration <= 0) return DEFAULT_CHUNK_DURATION; + + const fileSize = fs.statSync(filePath).size; + const bytesPerSecond = fileSize / totalDuration; + + // Calculate how many seconds fit into MAX_FILE_SIZE with a 10% safety margin + const maxChunkDuration = Math.floor((MAX_FILE_SIZE * 0.9) / bytesPerSecond); + + // Ensure reasonable chunk size between 5-15 minutes + return Math.max(5 * 60, Math.min(15 * 60, maxChunkDuration)); + } + + /** + * Extract a chunk of audio from the source file using ffmpeg + */ + async #extractAudioChunk( + sourcePath: string, + outputPath: string, + startOffset: number, + duration: number, + ): Promise { + try { + await exec( + `ffmpeg -y -i "${sourcePath}" -ss ${startOffset} -t ${duration} -c:a libmp3lame -q:a 4 "${outputPath}"`, + ); + } catch (error) { + logger.error("Failed to extract audio chunk", { + sourcePath, + outputPath, + startOffset, + duration, + error: error instanceof Error ? error.message : String(error), + }); + throw error; + } + } + + /** + * Extract context from previous chunk's text + * Gets the last few sentences to provide context for the next chunk + */ + #extractContextFromText(text: string): string { + // Get approximately the last 100-200 words as context + const words = text.split(/\s+/); + const contextWords = words.slice(Math.max(0, words.length - 150)); + + // Try to find sentence boundaries for cleaner context + const contextText = contextWords.join(" "); + + // Find the first capital letter after a period to start at a sentence boundary if possible + const sentenceBoundaryMatch = contextText.match(/\.\s+[A-Z]/); + if ( + sentenceBoundaryMatch && + sentenceBoundaryMatch.index && + sentenceBoundaryMatch.index > 20 + ) { + return contextText.substring(sentenceBoundaryMatch.index + 2); + } + + return contextText; + } +} diff --git a/tests/e2e.test.ts b/tests/e2e.test.ts new file mode 100644 index 0000000..5dcab73 --- /dev/null +++ b/tests/e2e.test.ts @@ -0,0 +1,368 @@ +import { randomUUID } from "crypto"; +import fs from "fs/promises"; +import os from "os"; +import path from "path"; + +import { db as mediaDb } from "../services/media/db"; +import { db as transcriptionDb } from "../services/transcription/db"; +import { db as tgovDb } from "../tgov/db"; +// Optional: Import test config +import * as testConfig from "./test.config"; + +// Import Encore clients +import { media, tgov, transcription } from "~encore/clients"; + +import { afterAll, beforeAll, describe, expect, test } from "vitest"; + +// Constants for testing +const TEST_MEETING_INDEX = 0; // First meeting in the list +const TEST_TIMEOUT = 1200000; // 20 minutes - in case it's a long video +const AUTO_UPDATE_CONFIG = false; // Whether to update test.config.ts with results + +// Helper function to update test config with new values (for development) +async function updateTestConfig(updates: Record) { + if (!AUTO_UPDATE_CONFIG) return; + + try { + // Read current config file + const configPath = path.join(__dirname, "test.config.ts"); + const content = await fs.readFile(configPath, "utf-8"); + + // Update each value + let updatedContent = content; + for (const [key, value] of Object.entries(updates)) { + const regex = new RegExp(`export const ${key} = ".*";`, "g"); + updatedContent = updatedContent.replace( + regex, + `export const ${key} = "${value}";`, + ); + } + + // Write back to file + await fs.writeFile(configPath, updatedContent); + console.log("Updated test.config.ts with new values"); + } catch (err) { + console.error("Failed to update test config:", err); + } +} + +describe("End-to-end transcription flow", () => { + let tempDir: string; + let meetingId: string; + let videoUrl: string; + let batchId: string; + let videoId: string; + let audioId: string; + let jobId: string; + let transcriptionId: string; + + // Create temp directory for test artifacts + beforeAll(async () => { + tempDir = path.join(os.tmpdir(), `tulsa-transcribe-test-${randomUUID()}`); + await fs.mkdir(tempDir, { recursive: true }); + + // Optionally load values from test config + meetingId = testConfig.TEST_MEETING_ID || ""; + videoId = testConfig.TEST_VIDEO_ID || ""; + audioId = testConfig.TEST_AUDIO_ID || ""; + jobId = testConfig.TEST_JOB_ID || ""; + transcriptionId = testConfig.TEST_TRANSCRIPTION_ID || ""; + }); + + // Clean up after tests + afterAll(async () => { + try { + await fs.rm(tempDir, { recursive: true, force: true }); + + // Update test config with new IDs for future test runs + if (meetingId && videoId && audioId && jobId && transcriptionId) { + await updateTestConfig({ + TEST_MEETING_ID: meetingId, + TEST_VIDEO_ID: videoId, + TEST_AUDIO_ID: audioId, + TEST_JOB_ID: jobId, + TEST_TRANSCRIPTION_ID: transcriptionId, + }); + } + } catch (err) { + console.error("Error cleaning up temp directory:", err); + } + }); + + test( + "Scrape TGov website", + async () => { + // Skip if meeting ID is already provided + if (meetingId) { + console.log(`Using existing meeting ID: ${meetingId}`); + return; + } + + // Trigger a scrape of the TGov website + const result = await tgov.scrape(); + expect(result.success).toBe(true); + }, + TEST_TIMEOUT, + ); + + test( + "Get meeting list and extract video URL", + async () => { + // Skip if both meeting ID and video URL are already available + if (meetingId && testConfig.REAL_VIDEO_URL) { + console.log(`Using existing meeting ID: ${meetingId} and video URL`); + videoUrl = testConfig.REAL_VIDEO_URL; + return; + } + + // Get list of meetings + const result = await tgov.listMeetings({ limit: 10 }); + expect(result.meetings.length).toBeGreaterThan(0); + + // Get a meeting with a video URL for testing + const meetingsWithVideo = result.meetings.filter((m) => m.videoViewUrl); + expect(meetingsWithVideo.length).toBeGreaterThan(0); + + // Save the first meeting with a video for further testing + const meeting = meetingsWithVideo[TEST_MEETING_INDEX]; + meetingId = meeting.id; + expect(meetingId).toBeTruthy(); + + // Extract video URL from meeting view URL + if (meeting.videoViewUrl) { + const extractResult = await tgov.extractVideoUrl({ + viewerUrl: meeting.videoViewUrl, + }); + videoUrl = extractResult.videoUrl; + expect(videoUrl).toBeTruthy(); + expect(videoUrl).toMatch(/^https?:\/\//); + } else { + throw new Error("No meeting with video URL found"); + } + }, + TEST_TIMEOUT, + ); + + test( + "Queue video for download and processing", + async () => { + // Skip if we already have video and audio IDs + if (videoId && audioId) { + console.log( + `Using existing video ID: ${videoId} and audio ID: ${audioId}`, + ); + return; + } + + // Queue a video batch with our test video + const queueResult = await media.queueVideoBatch({ + viewerUrls: [videoUrl], + meetingRecordIds: [meetingId], + extractAudio: true, + }); + + batchId = queueResult.batchId; + expect(batchId).toBeTruthy(); + expect(queueResult.totalVideos).toBe(1); + expect(queueResult.status).toBe("queued"); + }, + TEST_TIMEOUT, + ); + + test( + "Process the video batch", + async () => { + // Skip if we already have video and audio IDs + if (videoId && audioId) { + console.log( + `Using existing video ID: ${videoId} and audio ID: ${audioId}`, + ); + return; + } + + // Process the queued batch + const processResult = await media.processNextBatch({ batchSize: 1 }); + expect(processResult?.processed).toBe(1); + + // Wait for batch to complete and check status + let batchComplete = false; + + console.log("Waiting for batch processing to complete..."); + while (!batchComplete) { + const statusResult = await media.getBatchStatus({ batchId }); + + if ( + statusResult.status === "completed" || + statusResult.completedTasks === statusResult.totalTasks + ) { + batchComplete = true; + + // Get the processed media IDs + const task = statusResult.tasks[0]; + expect(task).toBeTruthy(); + videoId = task.videoId!; + audioId = task.audioId!; + + expect(videoId).toBeTruthy(); + expect(audioId).toBeTruthy(); + + console.log( + `Video processing complete. Video ID: ${videoId}, Audio ID: ${audioId}`, + ); + } else if (statusResult.status === "failed") { + throw new Error( + `Batch processing failed: ${JSON.stringify(statusResult)}`, + ); + } else { + // Show progress + console.log( + `Batch status: ${statusResult.status}, Completed: ${statusResult.completedTasks}/${statusResult.totalTasks}`, + ); + + // Wait before checking again + await new Promise((resolve) => setTimeout(resolve, 30 * 1000)); // check every 30 seconds + } + } + + expect(batchComplete).toBe(true); + }, + TEST_TIMEOUT, + ); + + test( + "Submit audio for transcription", + async () => { + // Skip if we already have a job ID or transcription ID + if (jobId || transcriptionId) { + console.log( + `Using existing job ID: ${jobId} or transcription ID: ${transcriptionId}`, + ); + return; + } + + // Submit audio for transcription + const transcriptionRequest = await transcription.transcribe({ + audioFileId: audioId, + meetingRecordId: meetingId, + model: "whisper-1", + }); + + jobId = transcriptionRequest.jobId; + expect(jobId).toBeTruthy(); + expect(transcriptionRequest.status).toBe("queued"); + + console.log(`Submitted transcription job with ID: ${jobId}`); + }, + TEST_TIMEOUT, + ); + + test( + "Wait for transcription to complete", + async () => { + // Skip if we already have a transcription ID + if (transcriptionId) { + console.log(`Using existing transcription ID: ${transcriptionId}`); + return; + } + + // If no job ID, try to get one from test config + if (!jobId && testConfig.TEST_JOB_ID) { + jobId = testConfig.TEST_JOB_ID; + console.log(`Using job ID from config: ${jobId}`); + } + + expect(jobId).toBeTruthy(); + + // Check transcription job status until complete + let transcriptionComplete = false; + let attempts = 0; + const maxAttempts = 120; // More attempts for transcription (10 minutes with 5-second checks) + + console.log("Waiting for transcription to complete..."); + while (!transcriptionComplete && attempts < maxAttempts) { + attempts++; + const jobStatus = await transcription.getJobStatus({ jobId }); + + if (jobStatus.status === "completed") { + transcriptionComplete = true; + expect(jobStatus.transcriptionId).toBeTruthy(); + transcriptionId = jobStatus.transcriptionId!; + + console.log( + `Transcription complete. Transcription ID: ${transcriptionId}`, + ); + + // Get the transcription details + const transcriptionDetails = await transcription.getTranscription({ + transcriptionId: transcriptionId, + }); + + expect(transcriptionDetails).toBeTruthy(); + expect(transcriptionDetails.text).toBeTruthy(); + expect(transcriptionDetails.text.length).toBeGreaterThan(0); + expect(transcriptionDetails.segments?.length || 0).toBeGreaterThan(0); + } else if (jobStatus.status === "failed") { + throw new Error(`Transcription failed: ${JSON.stringify(jobStatus)}`); + } else { + // Show progress + if (attempts % 12 === 0) { + // Log every minute + console.log( + `Transcription status: ${jobStatus.status}, attempt ${attempts}/${maxAttempts}`, + ); + } + + // Wait before checking again + await new Promise((resolve) => setTimeout(resolve, 5000)); + } + } + + if (!transcriptionComplete) { + throw new Error( + `Transcription did not complete after ${maxAttempts} attempts`, + ); + } + + expect(transcriptionComplete).toBe(true); + }, + TEST_TIMEOUT, + ); + + test( + "Verify database records for meeting", + async () => { + // Check that meeting record has been updated with media and transcription info + const meeting = await tgovDb.meetingRecord.findUnique({ + where: { id: meetingId }, + }); + + expect(meeting).toBeTruthy(); + + // Check that media files exist in database + const video = await mediaDb.mediaFile.findUnique({ + where: { id: meeting?.videoId || videoId }, + }); + expect(video).toBeTruthy(); + expect(video?.meetingRecordId).toBe(meetingId); + + const audio = await mediaDb.mediaFile.findUnique({ + where: { id: audioId }, + }); + expect(audio).toBeTruthy(); + expect(audio?.meetingRecordId).toBe(meetingId); + + // Check that transcription is linked to the meeting + const transcriptions = await transcriptionDb.transcription.findMany({ + where: { meetingRecordId: meetingId }, + }); + expect(transcriptions.length).toBeGreaterThan(0); + + // At least one transcription should be linked to our audio file + const matchingTranscription = transcriptions.find( + (t) => t.audioFileId === audioId, + ); + expect(matchingTranscription).toBeTruthy(); + }, + TEST_TIMEOUT, + ); +}); diff --git a/tests/media.test.ts b/tests/media.test.ts new file mode 100644 index 0000000..79d9214 --- /dev/null +++ b/tests/media.test.ts @@ -0,0 +1,143 @@ +import { randomUUID } from "crypto"; +import fs from "fs/promises"; +import os from "os"; +import path from "path"; + +import { db as mediaDb } from "../services/media/db"; + +import { media } from "~encore/clients"; + +import { afterAll, beforeAll, describe, expect, test, vi } from "vitest"; + +describe("Media Service Tests", () => { + const TEST_TIMEOUT = 300000; // 5 minutes for download tests + + // Mock data + const MOCK_MEETING_ID = "mock-meeting-id-123"; + let REAL_VIDEO_URL = ""; // Will be populated from config if available + + // For tests that need real file operations + let tempDir: string; + + // Create temp directory for test artifacts + beforeAll(async () => { + tempDir = path.join(os.tmpdir(), `media-test-${randomUUID()}`); + await fs.mkdir(tempDir, { recursive: true }); + + // You could load a real video URL from env vars or a test config file + try { + const testConfig = await import("./test.config.js").catch(() => null); + REAL_VIDEO_URL = testConfig?.REAL_VIDEO_URL || ""; + } catch (err) { + console.warn("No test config found, some tests may be skipped"); + } + }); + + // Clean up after tests + afterAll(async () => { + try { + await fs.rm(tempDir, { recursive: true, force: true }); + } catch (err) { + console.error("Error cleaning up temp directory:", err); + } + }); + + describe("Video Queue Management", () => { + test("Queue a video batch", async () => { + // Skip if no real video URL is available + if (!REAL_VIDEO_URL) { + console.warn("No real video URL available, using mock URL"); + } + + const videoUrl = REAL_VIDEO_URL || "https://example.com/mock-video.mp4"; + + const queueResult = await media.queueVideoBatch({ + viewerUrls: [videoUrl], + meetingRecordIds: [MOCK_MEETING_ID], + extractAudio: true, + }); + + expect(queueResult.batchId).toBeTruthy(); + expect(queueResult.totalVideos).toBe(1); + expect(queueResult.status).toBe("queued"); + + // Store batch ID for potential use in other tests + process.env.LAST_TEST_BATCH_ID = queueResult.batchId; + }); + + test("Get batch status", async () => { + // Skip if no batch ID from previous test + const batchId = process.env.LAST_TEST_BATCH_ID; + if (!batchId) { + console.warn("No batch ID available, skipping test"); + return; + } + + const statusResult = await media.getBatchStatus({ batchId }); + expect(statusResult).toBeTruthy(); + expect(statusResult.tasks.length).toBeGreaterThan(0); + }); + }); + + describe("Video Processing", () => { + test( + "Process a video batch", + async () => { + const processResult = await media.processNextBatch({ batchSize: 1 }); + + // If there are no batches to process, this is fine for a unit test + if (!processResult) { + console.log("No batches to process"); + return; + } + + expect(processResult.processed).toBeGreaterThanOrEqual(0); + }, + TEST_TIMEOUT, + ); + + test("Check if video file exists in database", async () => { + // This can be run independently with a known video ID + const videoId = process.env.TEST_VIDEO_ID; + if (!videoId) { + console.warn("No test video ID available, skipping test"); + return; + } + + const video = await mediaDb.mediaFile.findUnique({ + where: { id: videoId }, + }); + + expect(video).toBeTruthy(); + expect(video?.mimetype).toMatch(/^video/); + }); + + test("Check if audio file exists in database", async () => { + const audioId = process.env.TEST_AUDIO_ID; + if (!audioId) { + console.warn("No test audio ID available, skipping test"); + return; + } + + const audio = await mediaDb.mediaFile.findUnique({ + where: { id: audioId }, + }); + + expect(audio).toBeTruthy(); + expect(audio?.mimetype).toMatch(/^audio/); + }); + }); + + // This test can be used to download a single video for testing purposes + // It's marked as "skip" by default to avoid unexpected downloads + describe.skip("Standalone Download Tests", () => { + test( + "Download a specific video directly", + async () => { + // You can implement a direct download test for debugging + // This would bypass the queue system and test the downloader directly + }, + TEST_TIMEOUT, + ); + }); +}); diff --git a/tests/test.config.ts b/tests/test.config.ts new file mode 100644 index 0000000..b1af56a --- /dev/null +++ b/tests/test.config.ts @@ -0,0 +1,24 @@ +/** + * Test configuration file + * + * This file stores persistent configuration and test data IDs + * that can be used across test runs. + * + * Add real values for these fields to test specific parts of the system + * without having to run through the entire end-to-end flow. + */ + +// URLs +export const REAL_VIDEO_URL = ""; // Add a known working video URL here + +// TGov data +export const TEST_MEETING_ID = ""; // Set to a real meeting ID + +// Media service data +export const TEST_BATCH_ID = ""; // Set to a real batch ID from a previous run +export const TEST_VIDEO_ID = ""; // Set to a real video ID from a previous run +export const TEST_AUDIO_ID = ""; // Set to a real audio ID from a previous run + +// Transcription service data +export const TEST_JOB_ID = ""; // Set to a real job ID from a previous run +export const TEST_TRANSCRIPTION_ID = ""; // Set to a real transcription ID \ No newline at end of file diff --git a/tests/tgov.test.ts b/tests/tgov.test.ts new file mode 100644 index 0000000..6b08465 --- /dev/null +++ b/tests/tgov.test.ts @@ -0,0 +1,87 @@ +import { db as tgovDb } from "../tgov/db"; + +import { tgov } from "~encore/clients"; + +import { afterAll, beforeAll, describe, expect, test, vi } from "vitest"; + +// Mock data +const MOCK_MEETING_ID = "mock-meeting-id-123"; +const MOCK_VIDEO_URL = "https://example.com/video/12345.mp4"; +const MOCK_VIEWER_URL = "https://tgov.example.com/viewer/12345"; + +// Tests for TGov service +describe("TGov Service Tests", () => { + // Test specific timeout + const TEST_TIMEOUT = 30000; // 30 seconds + + describe("Scraping Functionality", () => { + test( + "Scrape TGov website", + async () => { + // Trigger a scrape of the TGov website + const result = await tgov.scrape(); + expect(result.success).toBe(true); + }, + TEST_TIMEOUT, + ); + }); + + describe("Meeting Management", () => { + test( + "List meetings", + async () => { + const result = await tgov.listMeetings({ limit: 5 }); + expect(result.meetings.length).toBeGreaterThan(0); + + // Validate meeting structure + const meeting = result.meetings[0]; + expect(meeting).toHaveProperty("id"); + expect(meeting).toHaveProperty("title"); + expect(meeting).toHaveProperty("body"); + }, + TEST_TIMEOUT, + ); + + test( + "Find meetings with videos", + async () => { + const result = await tgov.listMeetings({ limit: 10 }); + const meetingsWithVideo = result.meetings.filter((m) => m.videoViewUrl); + expect(meetingsWithVideo.length).toBeGreaterThan(0); + }, + TEST_TIMEOUT, + ); + }); + + describe("Video URL Extraction", () => { + test( + "Extract video URL from viewer URL", + async () => { + // Get a meeting with a video URL for testing + const result = await tgov.listMeetings({ limit: 10 }); + const meetingsWithVideo = result.meetings.filter((m) => m.videoViewUrl); + + if (meetingsWithVideo.length === 0) { + console.warn("No meetings with video URLs found, skipping test"); + return; + } + + const meeting = meetingsWithVideo[0]; + + // Extract video URL + const extractResult = await tgov.extractVideoUrl({ + viewerUrl: meeting.videoViewUrl!, + }); + + expect(extractResult.videoUrl).toBeTruthy(); + expect(extractResult.videoUrl).toMatch(/^https?:\/\//); + }, + TEST_TIMEOUT, + ); + + // Optional: Test with a mock viewer URL if real ones are unavailable + test.skip("Extract video URL with mock viewer URL", async () => { + // This would use a mocked implementation of tgov.extractVideoUrl + }); + }); +}); diff --git a/tests/transcription.test.ts b/tests/transcription.test.ts new file mode 100644 index 0000000..446232e --- /dev/null +++ b/tests/transcription.test.ts @@ -0,0 +1,92 @@ +import { db as transcriptionDb } from "../services/transcription/db"; + +import { transcription } from "~encore/clients"; + +import { describe, expect, test, vi } from "vitest"; + +describe("Transcription Service Tests", () => { + const TEST_TIMEOUT = 300000; // 5 minutes for longer tests + + // Test audio file ID for transcription tests + const TEST_AUDIO_ID = process.env.TEST_AUDIO_ID || ""; // Set this before running tests + const TEST_MEETING_ID = process.env.TEST_MEETING_ID || ""; + + describe("Transcription Job Management", () => { + test("Submit transcription job", async () => { + // Skip if no test audio ID is available + if (!TEST_AUDIO_ID) { + console.warn("No test audio ID available, skipping test"); + return; + } + + const transcribeResult = await transcription.transcribe({ + audioFileId: TEST_AUDIO_ID, + meetingRecordId: TEST_MEETING_ID || "test-meeting", + model: "whisper-1", + }); + + expect(transcribeResult.jobId).toBeTruthy(); + expect(transcribeResult.status).toBe("queued"); + + // Store job ID for other tests + process.env.LAST_TEST_JOB_ID = transcribeResult.jobId; + }); + + test("Get job status", async () => { + const jobId = process.env.LAST_TEST_JOB_ID; + if (!jobId) { + console.warn("No job ID available, skipping test"); + return; + } + + const jobStatus = await transcription.getJobStatus({ jobId }); + expect(jobStatus).toBeTruthy(); + expect(jobStatus.status).toMatch( + /^(queued|processing|completed|failed)$/, + ); + }); + }); + + describe("Transcription Results", () => { + test("Get transcription details", async () => { + // You can use a known transcription ID for this test + const transcriptionId = process.env.TEST_TRANSCRIPTION_ID; + if (!transcriptionId) { + console.warn("No transcription ID available, skipping test"); + return; + } + + const details = await transcription.getTranscription({ + transcriptionId, + }); + + expect(details).toBeTruthy(); + expect(details.text).toBeTruthy(); + }); + + test("Check database for transcription record", async () => { + // You can use a meeting ID to find related transcriptions + const meetingId = process.env.TEST_MEETING_ID; + if (!meetingId) { + console.warn("No meeting ID available, skipping test"); + return; + } + + const transcriptions = await transcriptionDb.transcription.findMany({ + where: { meetingRecordId: meetingId }, + }); + + expect(transcriptions.length).toBeGreaterThanOrEqual(0); + }); + }); + + // Optional: Mock tests for faster development + describe("Mock Transcription Tests", () => { + // You can add tests with mocked transcription service responses here + // These tests would run faster and not depend on actual transcription jobs + + test.skip("Mock transcription job submission", async () => { + // Example of a test with a mocked transcription service + }); + }); +}); diff --git a/tgov/constants.ts b/tgov/constants.ts deleted file mode 100644 index a1612f2..0000000 --- a/tgov/constants.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Constants for the TGov service - */ -export const tgov_urls = { - TGOV_BASE_URL: "https://tulsa-ok.granicus.com", - TGOV_INDEX_PATHNAME: "/ViewPublisher.php", -}; diff --git a/tgov/data/migrations/migration_lock.toml b/tgov/data/migrations/migration_lock.toml deleted file mode 100644 index 648c57f..0000000 --- a/tgov/data/migrations/migration_lock.toml +++ /dev/null @@ -1,3 +0,0 @@ -# Please do not edit this file manually -# It should be added in your version-control system (e.g., Git) -provider = "postgresql" \ No newline at end of file diff --git a/tgov/data/schema.prisma b/tgov/data/schema.prisma deleted file mode 100644 index bdb38ce..0000000 --- a/tgov/data/schema.prisma +++ /dev/null @@ -1,51 +0,0 @@ -generator client { - provider = "prisma-client-js" - previewFeatures = ["driverAdapters", "metrics"] - binaryTargets = ["native", "debian-openssl-3.0.x"] - output = "../../node_modules/@prisma/client/tgov" -} - -generator json { - provider = "prisma-json-types-generator" - engineType = "library" - output = "./jsontypes.ts" -} - -datasource db { - provider = "postgresql" - url = env("TGOV_DATABASE_URL") -} - -// Models related to TGov meeting data - -model Committee { - id String @id @default(ulid()) - name String @unique - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - meetingRecords MeetingRecord[] -} - -model MeetingRecord { - id String @id @default(ulid()) - name String @unique - startedAt DateTime @db.Timestamptz(6) - endedAt DateTime @db.Timestamptz(6) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - committeeId String - videoViewUrl String? - agendaViewUrl String? - - ///[MeetingRawJSON] - rawJson Json - - // Foreign keys to link with other services - videoId String? - audioId String? - agendaId String? - - committee Committee @relation(fields: [committeeId], references: [id]) - - @@unique([committeeId, startedAt]) -} diff --git a/tgov/index.ts b/tgov/index.ts deleted file mode 100644 index f2bd57a..0000000 --- a/tgov/index.ts +++ /dev/null @@ -1,190 +0,0 @@ -import { CronJob } from "encore.dev/cron"; -import { api } from "encore.dev/api"; -import logger from 'encore.dev/log'; -import puppeteer from "puppeteer"; - -import { launchOptions } from "./browser"; -import { scrapeIndex } from "./scrape"; -import { db } from "./data"; - -/** - * Scrape the Tulsa Government (TGov) index page for new meeting information. - * This includes committee names, meeting names, dates, durations, agenda URLs, and video URLs. - * The scraped data is then stored in the database for further processing. - */ -export const scrape = api( - { - auth: false, - expose: true, - method: "GET", - path: "/scrape/tgov", - tags: ["mvp", "scraper", "tgov"], - }, - async (): Promise<{ success: boolean }> => { - const result = await scrapeIndex() - .then(() => { - logger.info("Scraped TGov index"); - return { success: true }; - }) - .catch((e) => { - logger.error(e); - return { success: false }; - }); - - return result; - } -); - -/** - * Scrapes the TGov index page daily at 12:01 AM. - */ -export const dailyTgovScrape = new CronJob("daily-tgov-scrape", { - endpoint: scrape, - title: "TGov Daily Scrape", - schedule: "1 0 * * *", -}); - -/** - * Extracts video URL from a TGov viewer page - * - * The TGov website doesn't provide direct video URLs. This endpoint accepts - * a viewer page URL and returns the actual video URL that can be downloaded. - */ -export const extractVideoUrl = api( - { - auth: false, - expose: true, - method: "POST", - path: "/tgov/extract-video-url", - }, - async (params: { viewerUrl: string }): Promise<{ videoUrl: string }> => { - const { viewerUrl } = params; - logger.info(`Extracting video URL from: ${viewerUrl}`); - - const browser = await puppeteer.launch(launchOptions); - try { - const page = await browser.newPage(); - await page.goto(viewerUrl.toString(), { waitUntil: "domcontentloaded" }); - - const videoUrl = await page.evaluate(() => { - // May be defined in the global scope of the page - var video_url: string | null | undefined; - - if (typeof video_url === "string") return video_url; - - const videoElement = document.querySelector("video > source"); - if (!videoElement) - throw new Error("No element found with selector 'video > source'"); - - video_url = videoElement.getAttribute("src"); - if (!video_url) throw new Error("No src attribute found on element"); - - return video_url; - }); - - await browser.close(); - logger.info(`Extracted video URL: ${videoUrl}`); - return { videoUrl }; - } catch (error) { - await browser.close(); - logger.error(`Failed to extract video URL: ${error}`); - throw error; - } - } -); - -/** - * Lists all meetings with optional filtering capabilities - */ -export const listMeetings = api( - { - auth: false, - expose: true, - method: "GET", - path: "/tgov/meetings", - }, - async (params: { - limit?: number; - offset?: number; - committeeId?: string; - }): Promise<{ - meetings: Array<{ - id: string; - name: string; - startedAt: Date; - endedAt: Date; - committee: { id: string; name: string }; - videoViewUrl?: string; - agendaViewUrl?: string; - videoId?: string; - audioId?: string; - agendaId?: string; - }>; - total: number; - }> => { - const { limit = 20, offset = 0, committeeId } = params; - - const where = committeeId ? { committeeId } : {}; - - const [meetings, total] = await Promise.all([ - db.meetingRecord.findMany({ - where, - include: { - committee: true, - }, - take: limit, - skip: offset, - orderBy: { startedAt: "desc" }, - }), - db.meetingRecord.count({ where }), - ]); - - return { - meetings: meetings.map(meeting => ({ - id: meeting.id, - name: meeting.name, - startedAt: meeting.startedAt, - endedAt: meeting.endedAt, - committee: { - id: meeting.committee.id, - name: meeting.committee.name, - }, - videoViewUrl: meeting.videoViewUrl || undefined, - agendaViewUrl: meeting.agendaViewUrl || undefined, - videoId: meeting.videoId || undefined, - audioId: meeting.audioId || undefined, - agendaId: meeting.agendaId || undefined, - })), - total, - }; - } -); - -/** - * Lists all committees - */ -export const listCommittees = api( - { - auth: false, - expose: true, - method: "GET", - path: "/tgov/committees", - }, - async (): Promise<{ - committees: Array<{ - id: string; - name: string; - }>; - }> => { - const committees = await db.committee.findMany({ - orderBy: { name: "asc" }, - }); - - return { - committees: committees.map(committee => ({ - id: committee.id, - name: committee.name, - })), - }; - } -); \ No newline at end of file diff --git a/tgov/scrape.ts b/tgov/scrape.ts deleted file mode 100644 index 9efbccf..0000000 --- a/tgov/scrape.ts +++ /dev/null @@ -1,143 +0,0 @@ -import logger from "encore.dev/log"; -import puppeteer from "puppeteer"; - -import { tgov_urls } from "./constants"; -import { normalizeDate, normalizeName } from "./util"; -import { db } from "./data"; -import { launchOptions } from "./browser"; - -/** - * Scrapes the TGov index page for meeting information - * - * This function is responsible for extracting committee names, - * meeting dates, durations, agenda URLs, and video URLs from - * the TGov website and storing them in the database. - * - * @returns {Promise} A promise that resolves when scraping is complete - */ -export async function scrapeIndex(): Promise { - // Specify the view ID for the TGov index page - const VIEW_ID = "4"; - - const url = new URL(tgov_urls.TGOV_INDEX_PATHNAME, tgov_urls.TGOV_BASE_URL); - url.searchParams.set("view_id", VIEW_ID); - - const browser = await puppeteer.launch(launchOptions); - const page = await browser.newPage(); - - await page.goto(url.href, { waitUntil: "networkidle0" }); - - const data = await page.evaluate(async () => { - const results = []; - - const yearsContent = Array.from( - document.querySelectorAll( - ".TabbedPanelsContentGroup .TabbedPanelsContent" - ) - ); - - for (const contentDiv of yearsContent) { - const collapsibles = Array.from( - contentDiv.querySelectorAll(".CollapsiblePanel") - ); - - for (const panel of collapsibles) { - const committee = - panel.querySelector(".CollapsiblePanelTab")?.textContent?.trim() || - "Unknown Committee"; - - if (committee === "Unknown Committee") { - logger.warn("Unknown Committee found", panel); - } - - const rows = Array.from( - panel.querySelectorAll(".listingTable tbody .listingRow") - ); - - for (const row of rows) { - const columns = row.querySelectorAll("td"); - const name = columns[0]?.textContent?.trim() || ""; - const date = - columns[1]?.textContent?.replace(/\s+/g, " ").trim() || ""; - - const duration = columns[2]?.textContent?.trim() || ""; - - const agendaEl = columns[3]?.querySelector("a"); - const videoEl = columns[4]?.querySelector("a"); - - /** - * This complex regex aims for a fully "correct" parsing of the `window.open` - * expression to extract the first parameter (the URL). It handles cases where: - * - * - The URL is wrapped in either single or double quotes - * - Escaped quotes are used within the URL - */ - const videoViewUrl = - /^window\.open\((?['"])(?.+?)(?.*\)$/.exec( - videoEl?.getAttribute("onclick") || "" - )?.groups?.url || - videoEl?.getAttribute("href") || - undefined; - const agendaViewUrl = agendaEl?.getAttribute("href") || undefined; - - results.push({ - viewId: VIEW_ID, - committee, - name, - date, - duration, - agendaViewUrl, - videoViewUrl, - }); - } - } - } - - return results; - }); - - await browser.close(); - - /* - Debugging inside the browser context is difficult, so we do minimal processing - in the browser context and do the rest here. - */ - const groups = Map.groupBy(data, ({ committee }) => normalizeName(committee)); - - for (const committeeName of groups.keys()) { - // Create or update the committee record - const committee = await db.committee.upsert({ - where: { name: committeeName }, - update: {}, - create: { name: committeeName }, - }); - - - //TODO There isn't much consistency or convention in no things are named - // Process each meeting for this committee - for (const rawJson of groups.get(committeeName) || []) { - const { startedAt, endedAt } = normalizeDate(rawJson); - const name = normalizeName(`${rawJson.name}__${rawJson.date}`); - - // Create or update the meeting record - await db.meetingRecord.upsert({ - where: { - committeeId_startedAt: { - committeeId: committee.id, - startedAt, - }, - }, - update: {}, - create: { - name, - rawJson, - startedAt, - endedAt, - videoViewUrl: rawJson.videoViewUrl, - agendaViewUrl: rawJson.agendaViewUrl, - committee: { connect: committee }, - }, - }); - } - } -} diff --git a/tgov/util.ts b/tgov/util.ts deleted file mode 100644 index 7203a8e..0000000 --- a/tgov/util.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { parse, addHours, addMinutes } from "date-fns"; -import { tz } from "@date-fns/tz"; - -/** - * Types for TGov-specific data - */ -export interface TGovDateInfo { - date: string; - duration: string; -} - -/** - * Normalize a scraped name into its canonical form (as used in the database). - * - Removes all non-word characters except for dashes "-" - * - Converts to lowercase - * - Replaces each group of contiguous spaces with a single dash - * @param name - The name to normalize (e.g. a committee name, meeting name, etc.) - */ -export function normalizeName(name: string): string { - return name - .trim() - .toLowerCase() - .replace(/[^\w\s-]/g, "") - .replace(/\s+/g, "-"); -} - -/** - * Extract startedAt and endedAt timestamps from raw TGov date info - * Times on TGov's website are implicitly in the America/Chicago timezone - * - * @param raw The raw date information from TGov - * @returns Object containing normalized startedAt and endedAt timestamps - */ -export function normalizeDate(raw: TGovDateInfo): { - startedAt: Date; - endedAt: Date; -} { - const timeZone = "America/Chicago"; - const durationFormat = /(?\d+?h)\s+?(?\d+?)m/; - - const start = parse( - raw.date, - "MMMM d, y - h:mm a", - new Intl.DateTimeFormat("en-US", { timeZone }).format(Date.now()), - { in: tz(timeZone) } - ); - - let end; - let { groups: duration } = raw.duration.match(durationFormat) || {}; - - if (!duration) console.warn("Failed to parse duration", raw.duration); - duration ??= { hours: "0h", minutes: "0m" }; - - // Extract just the number from "5h" -> 5 - const hours = parseInt(duration.hours); - const minutes = parseInt(duration.minutes); - - // Calculate the end time by adding the duration to the start time - end = new Date(start); - end = addHours(end, hours); - end = addMinutes(end, minutes); - - return { startedAt: start, endedAt: end }; -} diff --git a/tmp/.gitkeep b/tmp/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tsconfig.json b/tsconfig.json index ed6539e..1b4234a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,28 +2,30 @@ "$schema": "https://json.schemastore.org/tsconfig", "compilerOptions": { /* Basic Options */ - "lib": ["es2024", "DOM"], + "lib": [ + "es2024", + "DOM" + ], "target": "ESNext", "module": "preserve", - "types": ["node"], + "types": [ + "node" + ], "paths": { - "~encore/*": ["./encore.gen/*"] + "~encore/*": [ + "./encore.gen/*" + ] }, - /* Workspace Settings */ "composite": true, - /* Strict Type-Checking Options */ "strict": true, - /* Module Resolution Options */ "moduleResolution": "bundler", "allowSyntheticDefaultImports": true, "isolatedModules": true, "sourceMap": true, - "declaration": true, - /* Advanced Options */ "forceConsistentCasingInFileNames": true, "skipLibCheck": true diff --git a/archives/video/streamer.ts b/work_in_progress/streamer.ts similarity index 100% rename from archives/video/streamer.ts rename to work_in_progress/streamer.ts