{"_id":"@bernierllc/content-type-video","_rev":"7-14a31a2cbe2db8b78a76e69f19e47a65","name":"@bernierllc/content-type-video","dist-tags":{"latest":"1.5.0"},"versions":{"1.0.0":{"name":"@bernierllc/content-type-video","version":"1.0.0","keywords":["content-type","video","media","upload","streaming","storage","metadata","bernierllc"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","_id":"@bernierllc/content-type-video@1.0.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"87caeb1244e5c836d0ee43caf091fa4932e28dde","tarball":"https://registry.npmjs.org/@bernierllc/content-type-video/-/content-type-video-1.0.0.tgz","fileCount":36,"integrity":"sha512-o4hfTnlkSkPMUbCTKvBVaaay6r7dAO/CR1bXPQvKEnPKIwANLOMhXaGOFg3zxAsQsxxNoNTizJwZPE8M7TM1bA==","signatures":[{"sig":"MEUCIQDPSsnJVeVimaxOkF2dCb0mi1A1xc/Iu2OUtwAeoCKSCwIgeddrEWD4Lfntt4+XQDWi5qLnxkh9TTY1pCQ7E4oot40=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":80086},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"a2a0a7115181a9a7f7e1649f8003d2bf17c6b8a7","scripts":{"lint":"eslint src --ext .ts","test":"jest --watch","build":"tsc","clean":"rm -rf dist","test:run":"jest","test:coverage":"jest --coverage"},"_npmUser":{"name":"mkbernier","email":"mkbernier@gmail.com"},"bernierllc":{"integration":{"logger":"planned","neverhub":"optional","neveradmin":"not-applicable"}},"_npmVersion":"11.6.0","description":"Base video content type with file upload, local storage, and streaming URL generation","directories":{},"_nodeVersion":"24.10.0","dependencies":{"zod":"^3.22.0","@bernierllc/content-type-registry":"^1.0.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.0.0","eslint":"^8.0.0","ts-jest":"^29.0.0","typescript":"^5.0.0","@types/jest":"^29.0.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.0.0","@typescript-eslint/eslint-plugin":"^6.0.0"},"peerDependencies":{"@bernierllc/neverhub-adapter":"^1.0.0"},"peerDependenciesMeta":{"@bernierllc/neverhub-adapter":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/content-type-video_1.0.0_1762309172820_0.20532098205478255","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@bernierllc/content-type-video","version":"1.0.1","keywords":["content-type","video","media","upload","streaming","storage","metadata","bernierllc"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","_id":"@bernierllc/content-type-video@1.0.1","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"e32e29e569ac19f8ca705e749dea74bca9241fdd","tarball":"https://registry.npmjs.org/@bernierllc/content-type-video/-/content-type-video-1.0.1.tgz","fileCount":37,"integrity":"sha512-LOYsUZO53vKCDPg7hMYXTHDd42RGEdOEFhex65AO/ZuEoAd0tNwF3GPZs30nMXjFnBknCMhZytear4NAzed+ow==","signatures":[{"sig":"MEUCIQDUwBOMpMl0cv6G9g84Kr+r+tnB8ZdmzPnRr9u5Jk5xdgIgDCL7tg3NvE20iK/+Sj9HEKmTB08XuyfcQll81rl5w/s=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":80476},"main":"dist/index.js","_from":"file:bernierllc-content-type-video-1.0.1.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint src --ext .ts","test":"jest --watch","build":"tsc","clean":"rm -rf dist","test:run":"jest","test:coverage":"jest --coverage"},"_npmUser":{"name":"mkbernier","email":"mkbernier@gmail.com"},"_resolved":"/tmp/67cb8dc255f57746ad6dcb72ca52c6bb/bernierllc-content-type-video-1.0.1.tgz","_integrity":"sha512-LOYsUZO53vKCDPg7hMYXTHDd42RGEdOEFhex65AO/ZuEoAd0tNwF3GPZs30nMXjFnBknCMhZytear4NAzed+ow==","bernierllc":{"integration":{"logger":"planned","neverhub":"optional","neveradmin":"not-applicable"}},"_npmVersion":"11.7.0","description":"Base video content type with file upload, local storage, and streaming URL generation","directories":{},"_nodeVersion":"20.19.6","dependencies":{"zod":"^3.22.0","@bernierllc/content-type-registry":"1.1.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.0.0","eslint":"^8.0.0","ts-jest":"^29.0.0","typescript":"^5.0.0","@types/jest":"^29.0.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.0.0","@typescript-eslint/eslint-plugin":"^6.0.0"},"peerDependencies":{"@bernierllc/neverhub-adapter":"^0.1.1"},"peerDependenciesMeta":{"@bernierllc/neverhub-adapter":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/content-type-video_1.0.1_1766087444133_0.3233680901621214","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@bernierllc/content-type-video","version":"1.2.0","keywords":["content-type","video","media","upload","streaming","storage","metadata","bernierllc"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","_id":"@bernierllc/content-type-video@1.2.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"2ab4c9b3cd276619cd15c5c25d473b6fa87a98d7","tarball":"https://registry.npmjs.org/@bernierllc/content-type-video/-/content-type-video-1.2.0.tgz","fileCount":37,"integrity":"sha512-NtpNrbMs3ro+H/Zg1Xr2VNVhEx/j5aSPew9oFX9Ni3gthkr/gkYDx3gikk8MDOZcaWudT3zCiVD1BPqE9I0hjQ==","signatures":[{"sig":"MEQCIFf4J6G7Ln//JO9B8U3xXZ+Tve4xYeILk5bVQefxhEN3AiApWqe1E2PC1rYEnntRPKdkOUUFj/bKEsqCaWGGLc6UTQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":83276},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"af7e74b3715d56d3a193e1bb6743b337c2b0df6d","scripts":{"lint":"eslint src --ext .ts","test":"jest --watch","build":"tsc","clean":"rm -rf dist","test:run":"jest","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:db925224-6359-4ee7-94df-158e6ad04060"}},"bernierllc":{"integration":{"logger":"planned","neverhub":"optional","neveradmin":"not-applicable"}},"_npmVersion":"lerna/9.0.3/node@v20.19.6+x64 (linux)","description":"Base video content type with file upload, local storage, and streaming URL generation","directories":{},"_nodeVersion":"20.19.6","dependencies":{"zod":"^3.22.0","@bernierllc/content-type-registry":"1.3.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.0.0","eslint":"^8.0.0","ts-jest":"^29.0.0","typescript":"^5.0.0","@types/jest":"^29.0.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.0.0","@typescript-eslint/eslint-plugin":"^6.0.0"},"peerDependencies":{"@bernierllc/neverhub-adapter":"^0.1.1"},"peerDependenciesMeta":{"@bernierllc/neverhub-adapter":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/content-type-video_1.2.0_1767642381944_0.31797727573632906","host":"s3://npm-registry-packages-npm-production"}},"1.2.1":{"name":"@bernierllc/content-type-video","version":"1.2.1","keywords":["content-type","video","media","upload","streaming","storage","metadata","bernierllc"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","_id":"@bernierllc/content-type-video@1.2.1","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"6f1e5d91e85e9ee774a4ce49d2c8cabae688ff65","tarball":"https://registry.npmjs.org/@bernierllc/content-type-video/-/content-type-video-1.2.1.tgz","fileCount":37,"integrity":"sha512-pL/KCaaCaKlBc4vfyPaMC5qyiUHce7BFzURbprlpwDP9vqplHSCX5YBKshGhO/RKlgVDP5BxMDiOkkuhV6uTZw==","signatures":[{"sig":"MEYCIQCDRdBQ1YVFILBcTppJMbFkLdHf2vx+7yd3p18iDvaZtgIhAKqMgbeIKkVLqu85c5JYYAzsvPT9PWfn4qU9jO6glE4/","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":83440},"main":"dist/index.js","_from":"file:bernierllc-content-type-video-1.2.1.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint src --ext .ts","test":"jest --watch","build":"tsc","clean":"rm -rf dist","test:run":"jest","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:db925224-6359-4ee7-94df-158e6ad04060"}},"_resolved":"/tmp/4927aa30775ad03e3bd2ac60d2f415bb/bernierllc-content-type-video-1.2.1.tgz","_integrity":"sha512-pL/KCaaCaKlBc4vfyPaMC5qyiUHce7BFzURbprlpwDP9vqplHSCX5YBKshGhO/RKlgVDP5BxMDiOkkuhV6uTZw==","bernierllc":{"integration":{"logger":"planned","neverhub":"optional","neveradmin":"not-applicable"}},"_npmVersion":"11.11.0","description":"Base video content type with file upload, local storage, and streaming URL generation","directories":{},"_nodeVersion":"20.20.0","dependencies":{"zod":"^3.22.0","@bernierllc/content-type-registry":"1.3.1"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.0.0","eslint":"^8.0.0","ts-jest":"^29.0.0","typescript":"^5.0.0","@types/jest":"^29.0.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.0.0","@typescript-eslint/eslint-plugin":"^6.0.0"},"peerDependencies":{"@bernierllc/neverhub-adapter":"^0.1.1"},"peerDependenciesMeta":{"@bernierllc/neverhub-adapter":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/content-type-video_1.2.1_1773078382794_0.6698855116399016","host":"s3://npm-registry-packages-npm-production"}},"1.2.2":{"name":"@bernierllc/content-type-video","version":"1.2.2","keywords":["content-type","video","media","upload","streaming","storage","metadata","bernierllc"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","_id":"@bernierllc/content-type-video@1.2.2","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"850e675ef98bd671ca80a581df311249455b3a35","tarball":"https://registry.npmjs.org/@bernierllc/content-type-video/-/content-type-video-1.2.2.tgz","fileCount":37,"integrity":"sha512-Xl6LZqEyA6OWH2D1hjuZVAgTk4JeMCfuROE/lfE30cHZO9RyX59GSnLZBR68rSaTL8WZdNs+YUfypduQXsm0uw==","signatures":[{"sig":"MEUCIDHRtV5/UHdl4DzfW7vPKYVapQNYIFnwirda5VQuxdIMAiEAhKylPjW3WFf0qg4PmPs3bX5dIxMRmaFQtUUcAuwtEcE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":83662},"main":"dist/index.js","_from":"file:bernierllc-content-type-video-1.2.2.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint src --ext .ts","test":"jest --watch","build":"tsc","clean":"rm -rf dist","test:run":"jest","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:db925224-6359-4ee7-94df-158e6ad04060"}},"_resolved":"/home/runner/work/tools/tools/packages/core/content-type-video/bernierllc-content-type-video-1.2.2.tgz","_integrity":"sha512-Xl6LZqEyA6OWH2D1hjuZVAgTk4JeMCfuROE/lfE30cHZO9RyX59GSnLZBR68rSaTL8WZdNs+YUfypduQXsm0uw==","bernierllc":{"integration":{"logger":"planned","neverhub":"optional","neveradmin":"not-applicable"}},"_npmVersion":"11.11.0","description":"Base video content type with file upload, local storage, and streaming URL generation","directories":{},"_nodeVersion":"20.20.0","dependencies":{"zod":"^3.22.0","@bernierllc/content-type-registry":"1.3.2"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.0.0","eslint":"^8.0.0","ts-jest":"^29.0.0","typescript":"^5.0.0","@types/jest":"^29.0.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.0.0","@typescript-eslint/eslint-plugin":"^6.0.0"},"peerDependencies":{"@bernierllc/neverhub-adapter":"^0.1.1"},"peerDependenciesMeta":{"@bernierllc/neverhub-adapter":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/content-type-video_1.2.2_1773163092772_0.7087792508967814","host":"s3://npm-registry-packages-npm-production"}},"1.4.0":{"name":"@bernierllc/content-type-video","version":"1.4.0","keywords":["content-type","video","media","upload","streaming","storage","metadata","bernierllc"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","_id":"@bernierllc/content-type-video@1.4.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"023a57a08784ec9355575dafa07666776ab79a2d","tarball":"https://registry.npmjs.org/@bernierllc/content-type-video/-/content-type-video-1.4.0.tgz","fileCount":30,"integrity":"sha512-SOzFTtgdPh9+ehyFzgoqqkDoHuoUKQy2E2300tGUCajATXyCrhLsZ385xEjFwYy/he05IAvGqV0VMXknjfmqcg==","signatures":[{"sig":"MEUCIHxx7WIRjJI+sSS+4qKYbFp2oJDEdN0S8C/bUnNP8vxmAiEA2ovAUpUjjFPis9FfAVrS5Uj8bdRISlZYnhG6h1ozEoM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":49567},"main":"dist/index.js","_from":"file:bernierllc-content-type-video-1.4.0.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint src --ext .ts","test":"jest --watch","build":"tsc","clean":"rm -rf dist","test:run":"jest","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:db925224-6359-4ee7-94df-158e6ad04060"}},"_resolved":"/home/runner/work/tools/tools/packages/core/content-type-video/bernierllc-content-type-video-1.4.0.tgz","_integrity":"sha512-SOzFTtgdPh9+ehyFzgoqqkDoHuoUKQy2E2300tGUCajATXyCrhLsZ385xEjFwYy/he05IAvGqV0VMXknjfmqcg==","bernierllc":{"integration":{"logger":"planned","neverhub":"optional","neveradmin":"not-applicable"}},"_npmVersion":"11.14.1","description":"Base video content type with file upload, local storage, and streaming URL generation","directories":{},"_nodeVersion":"20.20.2","dependencies":{"zod":"^3.22.0","@bernierllc/content-type-registry":"1.5.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.0.0","eslint":"^8.0.0","ts-jest":"^29.0.0","typescript":"^5.0.0","@types/jest":"^29.0.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.0.0","@typescript-eslint/eslint-plugin":"^6.0.0"},"peerDependencies":{"@bernierllc/neverhub-adapter":"^0.1.1"},"peerDependenciesMeta":{"@bernierllc/neverhub-adapter":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/content-type-video_1.4.0_1779241027371_0.011319330043999098","host":"s3://npm-registry-packages-npm-production"}},"1.5.0":{"name":"@bernierllc/content-type-video","version":"1.5.0","description":"Base video content type with file upload, local storage, and streaming URL generation","main":"dist/index.js","types":"dist/index.d.ts","keywords":["content-type","video","media","upload","streaming","storage","metadata","bernierllc"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","dependencies":{"zod":"^3.22.0","@bernierllc/content-type-registry":"1.6.0"},"devDependencies":{"@types/jest":"^29.0.0","@types/node":"^20.0.0","@typescript-eslint/eslint-plugin":"^6.0.0","@typescript-eslint/parser":"^6.0.0","eslint":"^8.0.0","jest":"^29.0.0","ts-jest":"^29.0.0","typescript":"^5.0.0"},"peerDependencies":{"@bernierllc/neverhub-adapter":"^0.1.1"},"peerDependenciesMeta":{"@bernierllc/neverhub-adapter":{"optional":true}},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"bernierllc":{"integration":{"neverhub":"optional","neveradmin":"not-applicable","logger":"planned"}},"scripts":{"build":"tsc","test":"jest --watch","test:run":"jest","test:coverage":"jest --coverage","lint":"eslint src --ext .ts","clean":"rm -rf dist"},"_id":"@bernierllc/content-type-video@1.5.0","_integrity":"sha512-kUCdmwWWrIevsELw0ob4yT1bAd9Yp5pEjWKbyH8Rz6T4NAjswHwdxO1l1aGgEcfDlDbXGghrwM5S0Ebhg6SC6g==","_resolved":"/home/runner/work/tools/tools/packages/core/content-type-video/bernierllc-content-type-video-1.5.0.tgz","_from":"file:bernierllc-content-type-video-1.5.0.tgz","_nodeVersion":"20.20.2","_npmVersion":"11.14.1","dist":{"integrity":"sha512-kUCdmwWWrIevsELw0ob4yT1bAd9Yp5pEjWKbyH8Rz6T4NAjswHwdxO1l1aGgEcfDlDbXGghrwM5S0Ebhg6SC6g==","shasum":"950095d4ff1125761c2ab8c479b75eeddbb2510a","tarball":"https://registry.npmjs.org/@bernierllc/content-type-video/-/content-type-video-1.5.0.tgz","fileCount":30,"unpackedSize":49567,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIH+VP9ey/gjv+lP/z0BFF2zRAPMWc+dtfMcnOf5SonLlAiAspTqtPKoXeOjKapxbfNjW7jEMOtDRxxNpSun3HRbNfw=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:db925224-6359-4ee7-94df-158e6ad04060"}},"directories":{},"maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/content-type-video_1.5.0_1779249766378_0.8429590841523866"},"_hasShrinkwrap":false}},"time":{"created":"2025-11-05T02:19:32.729Z","modified":"2026-05-20T04:02:46.632Z","1.0.0":"2025-11-05T02:19:33.018Z","1.0.1":"2025-12-18T19:50:44.294Z","1.2.0":"2026-01-05T19:46:22.073Z","1.2.1":"2026-03-09T17:46:22.935Z","1.2.2":"2026-03-10T17:18:12.915Z","1.4.0":"2026-05-20T01:37:07.503Z","1.5.0":"2026-05-20T04:02:46.506Z"},"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","keywords":["content-type","video","media","upload","streaming","storage","metadata","bernierllc"],"description":"Base video content type with file upload, local storage, and streaming URL generation","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"readme":"# @bernierllc/content-type-video\n\nBase video content type with file upload, local storage, and streaming URL generation for the BernierLLC Content Management Suite.\n\n## Installation\n\n```bash\nnpm install @bernierllc/content-type-video\n```\n\n## Features\n\n- ✅ **Video File Upload** - Upload video files with validation (format, size)\n- ✅ **Local File Storage** - Store videos in local file system with automatic directory creation\n- ✅ **Metadata Extraction** - Extract video metadata (duration, dimensions, fps, codec)\n- ✅ **Streaming URL Generation** - Generate streaming URLs for uploaded videos\n- ✅ **Configurable** - Environment variables and constructor options\n- ✅ **TypeScript** - Full type safety with strict mode\n- ✅ **Well Tested** - 100% statements, functions, and lines coverage\n\n## Usage\n\n### Basic Usage\n\n```typescript\nimport { VideoContentType } from '@bernierllc/content-type-video';\n\n// Create instance with defaults\nconst videoType = new VideoContentType();\n\n// Upload a video file\nconst result = await videoType.upload(\n  videoBuffer,  // Buffer or file path\n  'my-video.mp4',\n  'user-123'    // Optional: uploaded by\n);\n\nif (result.success) {\n  console.log('Video uploaded!');\n  console.log('File path:', result.data?.filePath);\n  console.log('Streaming URL:', result.data?.streamingUrl);\n  console.log('Metadata:', result.data?.metadata);\n}\n```\n\n### Custom Configuration\n\n```typescript\nconst videoType = new VideoContentType({\n  baseType: 'video',\n  editor: 'file-upload-with-player',\n  storage: 'file',\n  publishing: 'streaming-url',\n  uploadOptions: {\n    maxSizeBytes: 1024 * 1024 * 1024, // 1GB\n    allowedFormats: ['mp4', 'webm'],\n    generateThumbnail: true,\n    extractMetadata: true,\n    storageBasePath: './custom-storage/videos'\n  },\n  streamingBaseUrl: '/cdn/video/stream'\n});\n```\n\n### Environment Variables\n\n```bash\nVIDEO_MAX_SIZE_BYTES=524288000           # Maximum file size (500MB default)\nVIDEO_ALLOWED_FORMATS=mp4,webm,mov,avi  # Comma-separated allowed formats\nVIDEO_GENERATE_THUMBNAIL=true            # Generate thumbnail on upload\nVIDEO_EXTRACT_METADATA=true              # Extract metadata on upload\nVIDEO_STORAGE_BASE_PATH=./storage/videos # Base path for video file storage\nVIDEO_STREAMING_BASE_URL=/api/video/stream # Base URL for streaming endpoint\n```\n\n## API Reference\n\n### VideoContentType\n\nMain class for video content type operations.\n\n#### Constructor\n\n```typescript\nconstructor(config?: Partial<VideoContentTypeConfig>)\n```\n\n#### Methods\n\n##### `upload(file, filename, uploadedBy?)`\n\nUpload a video file and extract metadata.\n\n```typescript\nasync upload(\n  file: Buffer | string,\n  filename: string,\n  uploadedBy?: string\n): Promise<VideoContentResult<VideoContentData>>\n```\n\n**Parameters:**\n- `file`: Buffer or file path to the video file\n- `filename`: Original filename (used for extension detection)\n- `uploadedBy`: Optional user identifier who uploaded the video\n\n**Returns:** Result object with uploaded video data or error\n\n##### `validate(file, filename)`\n\nValidate video file before upload.\n\n```typescript\nasync validate(\n  file: Buffer | string,\n  filename: string\n): Promise<VideoContentResult<void>>\n```\n\n##### `get(localPath)`\n\nRetrieve video file from storage.\n\n```typescript\nasync get(localPath: string): Promise<Buffer | null>\n```\n\n##### `delete(localPath)`\n\nDelete video file from storage.\n\n```typescript\nasync delete(localPath: string): Promise<boolean>\n```\n\n##### `exists(localPath)`\n\nCheck if video file exists in storage.\n\n```typescript\nasync exists(localPath: string): Promise<boolean>\n```\n\n##### `getStreamingUrl(localPath)`\n\nGenerate streaming URL for video file.\n\n```typescript\ngetStreamingUrl(localPath: string): string\n```\n\n##### `validateContent(data)`\n\nValidate video content data structure.\n\n```typescript\nvalidateContent(data: VideoContentData): VideoContentResult<VideoContentData>\n```\n\n##### `register()`\n\nRegister video content type with content type registry.\n\n```typescript\nasync register(): Promise<void>\n```\n\n## Type Definitions\n\n### VideoMetadata\n\n```typescript\ninterface VideoMetadata {\n  filename: string;\n  mimeType: string;          // e.g., 'video/mp4'\n  size: number;              // File size in bytes\n  duration: number;          // Duration in seconds\n  width: number;             // Video width in pixels\n  height: number;            // Video height in pixels\n  fps: number;               // Frames per second\n  thumbnail?: string;        // Optional thumbnail URL\n  bitrate?: number;          // Optional bitrate\n  codec?: string;            // Optional codec information\n}\n```\n\n### VideoContentData\n\n```typescript\ninterface VideoContentData {\n  filePath: string;          // Local file path\n  streamingUrl: string;      // Generated streaming URL\n  metadata: VideoMetadata;   // Video metadata\n  uploadedAt: Date;          // Upload timestamp\n  uploadedBy?: string;       // Optional uploader identifier\n}\n```\n\n### VideoUploadOptions\n\n```typescript\ninterface VideoUploadOptions {\n  maxSizeBytes?: number;          // Default: 500MB\n  allowedFormats?: string[];      // Default: ['mp4', 'webm', 'mov', 'avi']\n  generateThumbnail?: boolean;    // Default: true\n  extractMetadata?: boolean;      // Default: true\n  storageBasePath?: string;       // Default: './storage/videos'\n}\n```\n\n## Examples\n\n### Upload from Buffer\n\n```typescript\nimport fs from 'fs';\nimport { VideoContentType } from '@bernierllc/content-type-video';\n\nconst videoType = new VideoContentType();\nconst videoBuffer = fs.readFileSync('./my-video.mp4');\n\nconst result = await videoType.upload(videoBuffer, 'my-video.mp4');\n\nif (result.success) {\n  console.log('Upload successful!');\n  console.log(`Streaming URL: ${result.data?.streamingUrl}`);\n  console.log(`Duration: ${result.data?.metadata.duration}s`);\n  console.log(`Resolution: ${result.data?.metadata.width}x${result.data?.metadata.height}`);\n}\n```\n\n### Upload from File Path\n\n```typescript\nconst result = await videoType.upload('/path/to/video.mp4', 'video.mp4', 'user-123');\n```\n\n### Validate Video Format\n\n```typescript\nconst result = await videoType.upload(buffer, 'video.avi');\n\nif (!result.success) {\n  console.error('Upload failed:', result.error);\n  // Error: File format avi not allowed. Allowed: mp4, webm, mov, avi\n}\n```\n\n### Custom Storage Location\n\n```typescript\nconst videoType = new VideoContentType({\n  uploadOptions: {\n    storageBasePath: '/data/videos'\n  }\n});\n```\n\n### Delete Uploaded Video\n\n```typescript\nconst uploadResult = await videoType.upload(buffer, 'video.mp4');\n\nif (uploadResult.success && uploadResult.data) {\n  const filePath = uploadResult.data.filePath;\n\n  // Later, delete the video\n  const deleted = await videoType.delete(filePath);\n\n  if (deleted) {\n    console.log('Video deleted successfully');\n  }\n}\n```\n\n## Integration\n\n### Logger Integration\n- **Status**: planned\n- **Usage**: Log upload operations, metadata extraction, and errors\n\n### NeverHub Integration\n- **Status**: optional\n- **Events Published**:\n  - `video.uploaded` - When video file is successfully uploaded\n  - `video.metadata-extracted` - When metadata extraction completes\n  - `video.validation-failed` - When video validation fails\n\n### Docs-Suite Compatibility\n- **Status**: ready\n- **Format**: typedoc\n- **Documentation**: Complete API documentation with TypeScript types\n\n## Platform-Specific Extensions\n\nThis base package is designed to be extended for platform-specific video content types:\n\n- `@bernierllc/content-type-youtube` - YouTube video integration\n- `@bernierllc/content-type-tiktok` - TikTok video integration\n- `@bernierllc/content-type-instagram-reels` - Instagram Reels integration\n\n## Dependencies\n\n- `@bernierllc/content-type-registry` (^1.0.3) - Content type registration\n- `zod` (^3.22.0) - Schema validation\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Run tests\nnpm test\n\n# Run tests with coverage\nnpm run test:coverage\n\n# Build package\nnpm run build\n\n# Lint code\nnpm run lint\n```\n\n## Quality Metrics\n\n- **Test Coverage**: 98.86% statements, 100% functions, 98.86% lines, 79.31% branches\n- **Tests**: 37 passing, 0 failing (100% pass rate)\n- **TypeScript**: Strict mode enabled, zero errors\n- **Linting**: Zero errors or warnings\n- **Build**: Successful compilation\n\n## License\n\nCopyright (c) 2025 Bernier LLC\n\nThis file is licensed to the client under a limited-use license.\nThe client may use and modify this code *only within the scope of the project it was delivered for*.\nRedistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.\n\n## Related Packages\n\n- [@bernierllc/content-type-registry](../content-type-registry) - Content type registration and base interfaces\n- [@bernierllc/content-management-suite](../../suite/content-management-suite) - Complete content management system\n\n## Part of Suite\n\n- [@bernierllc/content-management-suite](../../suite/content-management-suite) - Comprehensive content management solution\n\n## Contributing\n\nThis package is part of the BernierLLC monorepo and follows strict quality standards:\n\n- 90%+ test coverage (all metrics)\n- 100% test pass rate\n- TypeScript strict mode\n- Zero linting errors\n- License headers in all files\n\nFor more information, see [CLAUDE.md](../../../CLAUDE.md) in the repository root.\n","readmeFilename":"README.md"}