From 5b2f3ca3512faa6e80f027ecd7e0593c7cf1a1b9 Mon Sep 17 00:00:00 2001 From: Eric Martin Date: Wed, 29 Jul 2026 19:08:20 -0700 Subject: [PATCH] docs: add community health files and package metadata Adds the community and governance files Snyk's package health report flagged as missing, plus a LICENSE file the README already linked to. - LICENSE: MIT, crediting both the original youtube-transcript project and this fork. The file was absent entirely, so the README link was broken and the published npm tarball shipped no license text. - CONTRIBUTING.md: setup, dev commands, project layout, testing rules (nock only, no live YouTube calls), commit and PR conventions. - CODE_OF_CONDUCT.md: Contributor Covenant 2.1. - SECURITY.md: private disclosure via GitHub advisories, response expectations, and an explicit scope section clarifying that YouTube rate limiting and upstream API breakage are not vulnerabilities. - Issue forms for bug reports and feature requests, a PR template, and an ISSUE_TEMPLATE config routing security reports to private advisories. - package.json: expand keywords for discoverability, add sideEffects: false for bundler tree-shaking (the module graph is declaration-only, no top-level side effects). - README: link the new contributing and security docs. No functional or API changes. --- .github/ISSUE_TEMPLATE/bug_report.yml | 97 ++++++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 5 + .github/ISSUE_TEMPLATE/feature_request.yml | 44 +++++++ .github/PULL_REQUEST_TEMPLATE.md | 36 ++++++ CODE_OF_CONDUCT.md | 129 +++++++++++++++++++++ CONTRIBUTING.md | 103 ++++++++++++++++ LICENSE | 22 ++++ README.md | 13 ++- SECURITY.md | 76 ++++++++++++ package.json | 11 +- 10 files changed, 534 insertions(+), 2 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE create mode 100644 SECURITY.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..748abde --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,97 @@ +name: Bug report +description: Something is not working as documented +labels: ['bug'] +body: + - type: markdown + attributes: + value: | + Thanks for filing a bug. This library uses YouTube's unofficial Innertube + API, so behavior often varies by video, language, and region — the more + specific you can be, the faster this gets fixed. + + If this is a security vulnerability, please **do not** file it here. See + [SECURITY.md](https://github.com/ericmmartin/youtube-transcript-plus/blob/main/SECURITY.md). + + - type: textarea + id: what-happened + attributes: + label: What happened? + description: What did you expect to happen, and what happened instead? + validations: + required: true + + - type: input + id: video-id + attributes: + label: Video ID or URL + description: >- + If the video is public, this is the single most useful thing you can + provide. Leave blank if the video is private or unlisted. + placeholder: dQw4w9WgXcQ + validations: + required: false + + - type: textarea + id: repro + attributes: + label: Reproduction + description: A minimal code sample, including the config you passed. + render: javascript + placeholder: | + import { fetchTranscript } from 'youtube-transcript-plus'; + + await fetchTranscript('dQw4w9WgXcQ', { lang: 'en' }); + validations: + required: true + + - type: textarea + id: error + attributes: + label: Error output + description: The full error, including the error class name and stack trace. + render: shell + validations: + required: false + + - type: input + id: package-version + attributes: + label: youtube-transcript-plus version + placeholder: 2.0.1 + validations: + required: true + + - type: input + id: node-version + attributes: + label: Node.js version + placeholder: v22.11.0 + validations: + required: true + + - type: dropdown + id: environment + attributes: + label: Environment + options: + - Local development + - Server / container + - Serverless (Lambda, Vercel, Cloudflare, etc.) + - CI + - Other + validations: + required: false + + - type: checkboxes + id: checks + attributes: + label: Checks + options: + - label: I am using a supported Node.js version (>= 20) + required: true + - label: I searched existing issues for a duplicate + required: true + - label: >- + I confirmed the transcript is actually available for this video on + youtube.com (transcripts can be disabled by the uploader) + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..d55f703 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Report a security vulnerability + url: https://github.com/ericmmartin/youtube-transcript-plus/security/advisories/new + about: Please report vulnerabilities privately, not as a public issue. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..574e6dd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,44 @@ +name: Feature request +description: Suggest a new capability or improvement +labels: ['enhancement'] +body: + - type: textarea + id: problem + attributes: + label: What problem are you trying to solve? + description: >- + Describe the use case rather than the implementation. What are you + building, and where does the library get in your way today? + validations: + required: true + + - type: textarea + id: proposal + attributes: + label: Proposed solution + description: >- + If you have an API in mind, sketch it here — a config option, a new + exported function, a new formatter, etc. + render: typescript + validations: + required: false + + - type: textarea + id: alternatives + attributes: + label: Alternatives considered + description: >- + Have you worked around this already, for example with a custom + `transcriptFetch` or a custom `CacheStrategy`? + validations: + required: false + + - type: checkboxes + id: checks + attributes: + label: Checks + options: + - label: I searched existing issues for a duplicate + required: true + - label: I would be willing to open a pull request for this + required: false diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..6ff78d9 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,36 @@ + + +## What does this change? + + + +Closes # + +## Type of change + +- [ ] Bug fix (non-breaking change that fixes an issue) +- [ ] New feature (non-breaking change that adds functionality) +- [ ] Breaking change (fix or feature that changes existing public API) +- [ ] Documentation only +- [ ] Chore / dependencies / tooling + +## How was this tested? + + + +## Checklist + +- [ ] `npm run lint` passes +- [ ] `npm run typecheck` passes +- [ ] `npm run build` passes +- [ ] `npm test` passes +- [ ] Tests added or updated for this change +- [ ] README updated if public API or config options changed +- [ ] Commit messages follow [Conventional Commits](https://www.conventionalcommits.org/) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..0617363 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,129 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +- Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery, and sexual attention or advances of + any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, + without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official email address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +[eric@ericmmartin.com](mailto:eric@ericmmartin.com). + +All complaints will be reviewed and investigated promptly and fairly. All +community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][mozilla]. + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. + +[homepage]: https://www.contributor-covenant.org +[mozilla]: https://github.com/mozilla/diversity diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..4ec7fcf --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,103 @@ +# Contributing to youtube-transcript-plus + +Thanks for taking the time to contribute! This project is small and pull requests +are genuinely welcome — bug fixes, tests, docs, and new features all help. + +## Getting started + +Requires Node.js >= 20. + +```bash +git clone https://github.com/ericmmartin/youtube-transcript-plus.git +cd youtube-transcript-plus +npm ci +``` + +## Development workflow + +| Command | What it does | +| -------------------- | --------------------------- | +| `npm test` | Run the Vitest suite once | +| `npm run test:watch` | Run tests in watch mode | +| `npm run lint` | ESLint over the repo | +| `npm run typecheck` | `tsc --noEmit` | +| `npm run build` | Build `dist/` with Rollup | +| `npm run format` | Prettier over `src/**/*.ts` | + +Before opening a pull request, please make sure all four of these pass: + +```bash +npm run lint && npm run typecheck && npm run build && npm test +``` + +CI runs exactly these on Node 20.x, 22.x, and 24.x. + +## Project layout + +``` +src/ + index.ts # YoutubeTranscript class, fetchTranscript, listLanguages + types.ts # TranscriptConfig, TranscriptSegment, CacheStrategy + utils.ts # retrieveVideoId, defaultFetch + errors.ts # error classes + formatters.ts # toSRT, toVTT, toPlainText + constants.ts + cache/ # InMemoryCache, FsCache + __tests__/ # tests mirror the source layout +``` + +## Testing + +- Tests live in `src/__tests__/` and mirror the source layout. +- HTTP is mocked with [`nock`](https://github.com/nock/nock) — **tests must not make + real network calls to YouTube.** Add fixtures under `src/__tests__/fixtures/` + rather than hitting the live API. +- New features and bug fixes should come with tests. For a bug fix, a test that + fails before your change and passes after is ideal. + +## Code style + +Prettier and ESLint are enforced by a Husky pre-commit hook via lint-staged, so +formatting is handled for you on commit. The configured style is single quotes, +semicolons, 2-space indent, 100-character line width, and trailing commas. + +## Commit messages + +This project follows [Conventional Commits](https://www.conventionalcommits.org/): + +``` +feat: add support for auto-translated caption tracks +fix: handle empty captionTracks array +chore(deps): bump vitest to 4.1.10 +docs: clarify cache key format +test: cover FsCache TTL expiry +``` + +## Pull requests + +1. Branch from `main` (e.g. `fix/empty-caption-tracks`). +2. Keep the change focused — one logical change per PR. +3. Fill out the pull request template, including how you tested. +4. Update the README if you change public API or configuration options. + +## Reporting bugs + +Open an issue using the bug report template. Because this library depends on +YouTube's unofficial Innertube API, please include the video ID (if the video is +public), the config you passed, the full error, and your Node version — behavior +often differs by video and region. + +## Security issues + +Please **do not** open a public issue for a security vulnerability. See +[SECURITY.md](SECURITY.md) for private reporting instructions. + +## Code of Conduct + +Participation in this project is governed by the +[Code of Conduct](CODE_OF_CONDUCT.md). + +## License + +By contributing, you agree that your contributions will be licensed under the +[MIT License](LICENSE). diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..deadb82 --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2020 Sylvestre Bouchot (original youtube-transcript project) +Copyright (c) 2025 Eric Martin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index a0a2880..08f765c 100644 --- a/README.md +++ b/README.md @@ -396,7 +396,18 @@ The library throws the following errors: ## Feature Requests -Have a feature idea? [Open an issue](https://github.com/ericmmartin/youtube-transcript-plus/issues/new) and let us know! +Have a feature idea? [Open an issue](https://github.com/ericmmartin/youtube-transcript-plus/issues/new/choose) and let us know! + +## Contributing + +Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for development +setup, testing conventions, and pull request guidelines. Participation is governed +by our [Code of Conduct](CODE_OF_CONDUCT.md). + +## Security + +To report a security vulnerability, please follow the private disclosure process +in [SECURITY.md](SECURITY.md) rather than opening a public issue. ## License diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..70a45df --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,76 @@ +# Security Policy + +## Supported Versions + +Security fixes are applied to the latest published minor release. Older majors +are not backported. + +| Version | Supported | +| ------- | ------------------ | +| 2.x | :white_check_mark: | +| 1.x | :x: | + +## Reporting a Vulnerability + +**Please do not report security vulnerabilities through public GitHub issues.** + +Report privately using GitHub's +[private vulnerability reporting](https://github.com/ericmmartin/youtube-transcript-plus/security/advisories/new). +If that is unavailable to you, email +[eric@ericmmartin.com](mailto:eric@ericmmartin.com) with `SECURITY` in the +subject line. + +Please include: + +- A description of the vulnerability and its impact +- Steps to reproduce, ideally a minimal code sample +- The version of `youtube-transcript-plus` and Node.js you tested against +- Any suggested mitigation, if you have one + +### What to expect + +- **Acknowledgement** within 5 business days. +- **An assessment** — whether we consider it a vulnerability, and the severity — + within 10 business days. +- **A fix and published advisory** for confirmed vulnerabilities, coordinated + with you on timing. This is a single-maintainer project, so please allow up to + 90 days before public disclosure. + +We are happy to credit you in the advisory unless you prefer to remain anonymous. + +## Scope + +This library fetches data from YouTube's unofficial Innertube API and parses the +response. Issues that are in scope include, but are not limited to: + +- Code injection or prototype pollution reachable from library input (a video + ID, URL, or config value) or from a malicious/unexpected API response +- Denial of service via malformed transcript XML (for example, catastrophic + backtracking in parsing) +- Path traversal or unsafe file writes in `FsCache` cache keys +- Leakage of credentials, cookies, or proxy configuration supplied via custom + fetch functions +- Insecure defaults in the outbound requests the library makes + +### Out of scope + +- **YouTube blocking, rate limiting, or breaking changes.** This library depends + on an unofficial API; `YoutubeTranscriptTooManyRequestError` and similar + failures are expected operational behavior, not vulnerabilities. Please open a + regular issue. +- Vulnerabilities in a transitive dependency with no exploitable path through + this library's API — report those upstream, though we still welcome a heads-up. +- Anything requiring the attacker to already control the machine running the + library. +- Use of `disableHttps: true`, which is an explicitly documented opt-in. + +## Supply Chain + +Releases are published to npm from a GitHub Actions workflow with +[npm provenance](https://docs.npmjs.com/generating-provenance-statements) +enabled, so each published tarball is cryptographically linked to the commit and +workflow run that produced it. You can verify a release with: + +```bash +npm audit signatures +``` diff --git a/package.json b/package.json index 616e3b3..bb53943 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "main": "dist/youtube-transcript-plus.cjs", "module": "dist/youtube-transcript-plus.mjs", "types": "dist/index.d.ts", + "sideEffects": false, "exports": { ".": { "import": { @@ -32,7 +33,15 @@ "author": "ericmmartin", "keywords": [ "youtube", - "transcript" + "transcript", + "transcripts", + "captions", + "subtitles", + "closed-captions", + "innertube", + "srt", + "vtt", + "typescript" ], "license": "MIT", "lint-staged": {