Skip to content

Conversation

@gastonmorixe
Copy link

@gastonmorixe gastonmorixe commented Sep 25, 2025

Note

Coded with assistance of Codex and Gemini

Important

This PR requires to enable Github Pages with a custom GitHub Actions workflow in repo config

Docs, Lint, and CI Modernization

TypeDoc + TSDoc enforcement, and automatic Pages deploy.

Screenshot 2025-09-24 at 20 34 53 Screenshot 2025-09-24 at 20 36 58 Screenshot 2025-09-24 at 20 36 46 Screenshot 2025-09-24 at 20 36 31

Motivation

We want our public API docs to be:

  • Accurate: generated from the source of truth (TSDoc in src/).
  • Complete: every exported symbol is documented or the build fails.
  • Easy to preview: one command to build/serve; CI deploys to Pages.
  • Low‑friction: lint validates documentation fast for contributors.

At the same time, our lint stack must understand modern TypeScript (TS 5.9), without warnings, and CI should be current and fast.

What Changed (High‑Level)

  • Documentation system tightened and clarified:
    • TypeDoc enforces documentation coverage (Classes/Interfaces/Functions/Methods/TypeAliases/Enums/EnumMembers/Variables/Properties).
    • Lint runs TypeDoc in validation‑only mode (--emit none) so “lint” doesn’t generate HTML.
    • Developer guide docs/README.md now documents workflows, scope, troubleshooting, and quick commands.
  • Lint + TypeScript alignment:
    • Upgraded to @typescript-eslint v8 to officially support TS 5.9.
    • Added Yarn resolutions to force aligned versions across the tree.
    • Set the explicit parser at the root (parser: '@typescript-eslint/parser') to avoid nested parser pickup.
    • Minimal compatibility shim for one removed “extension rule” (maps to base ESLint rule) — preserves behavior.
  • CI modernization:
    • Linter workflow (ESLint + SwiftLint) updated to modern Actions and caching.
    • Docs workflow builds TypeDoc site and deploys to GitHub Pages (push to master), with PR artifacts.
    • Build workflow (examples) uses Node 22 + Yarn cache, Gradle wrapper validation + caching, and Bundler cache on iOS.
  • Packaging:
    • images/ added to npm files whitelist so README assets render on npm.

No behavioral changes to the runtime library. Public API surface remains the same. The only functional code change in scope fixed an iOS helper call (see “Notable Fix” below).

Developer Experience — What to Expect

  • One command to validate code style and documentation coverage:
yarn lint

This runs eslint . --max-warnings=0 and then typedoc --emit none (validate only). If any exported symbol reachable from src/index.ts is missing docs, the command fails.

  • Build and preview docs site locally:
yarn docs:build
yarn docs:serve # http://localhost:8080
  • Typical workflow:
    1. Write code and TSDoc in src/…
    2. yarn lint (fast, no HTML) — fix any style/doc issues
    3. yarn docs:build && yarn docs:serve to preview the site

Detailed Changes

1) Lint + TS alignment (TS 5.9 support)

  • Upgraded lint stack to officially support TS 5.9 and remove the “unsupported TypeScript” warning emitted by old typescript-estree versions.
  • Added Yarn resolutions (deterministic) to ensure no nested dependency drags old versions back into ESLint initialization:
{
  "resolutions": {
    "@typescript-eslint/parser": "^8.44.1",
    "@typescript-eslint/eslint-plugin": "^8.44.1",
    "@typescript-eslint/utils": "^8.44.1",
    "@typescript-eslint/typescript-estree": "^8.44.1",
    "eslint-plugin-jest": "^29.0.1"
  }
}
  • .eslintrc.js:
    • parser: '@typescript-eslint/parser' at the root so ESLint doesn’t pick a nested parser from extended configs.
    • Added a minimal compatibility shim for a removed “extension rule” to preserve behavior while upstream configs catch up:
'@typescript-eslint/func-call-spacing': 'off',
'func-call-spacing': ['error', 'never'],
  • Verified via:
    • eslint --print-config src/index.ts shows the top‑level parser.
    • yarn why @typescript-eslint/typescript-estree shows only v8 in use.
    • yarn lint — clean, no warnings.

2) Documentation system

  • typedoc.json now treats missing docs as errors for: Class, Interface, Function, Method, TypeAlias, Enum, EnumMember, Variable, Property.
  • Lint runs typedoc --emit none — validates docs coverage, does not generate HTML during lint.
  • Typed custom theme and configured: docs/theme/custom-typedocs.css.
  • docs/README.md (developer guide) updated with:
    • Contents, troubleshooting, quick commands, tool alignment rationale, Yarn resolutions rationale, explicit parser rationale, diagnostics commands, and an “assets on npm” note.

3) CI workflows

  • Docs (GitHub Pages):
    • actions/checkout@v5, actions/configure-pages@v5, actions/upload-pages-artifact@v3, actions/deploy-pages@v4.
    • Node LTS '22'; yarn docs:build used for site generation; PRs get a downloadable typedoc-site artifact.
  • Linter:
    • ESLint job on Ubuntu with Node 22 + Yarn cache, yarn lint (ESLint + TypeDoc validate only).
    • Separate SwiftLint job on macOS (unchanged behavior; modernized checkout).
  • Build examples:
    • Node 22 + Yarn cache; Gradle wrapper validation + gradle/actions/setup-gradle@v4 caching.
    • iOS uses ruby/setup-ruby@v1 with bundler-cache: true and BUNDLE_GEMFILE=example/Gemfile to speed CocoaPods/Bundler.

4) Packaging / README assets

  • package.json#files: added images/ so README’s header image renders on npm.

Notable Fix (iOS only)

  • src/Camera.ios.tsx: requestDeviceCameraAuthorization now calls the correct TurboModule method (request...) instead of check.... This matches the intended iOS helper behavior. Android retains “Not implemented” in the JS wrapper (as before).

Backward Compatibility

  • No breaking API changes. Export surface and Orientation values remain the same.
  • Docs/CI/lint changes do not affect runtime behavior.
  • iOS helper correction makes the method work as intended (non‑breaking; safer behavior).

How to Review

  • Code style/docs gate:
    • yarn installyarn lint should be green.
  • Build & Docs:
    • yarn build (TS compile), then yarn docs:build && yarn docs:serve to preview.
  • CI:
    • Check that Docs (TypeDoc → GitHub Pages), Linter, and Build workflows succeed on this branch.

Rollout / Backout

  • Rollout: merge to master and the Docs workflow will publish to Pages automatically.
  • Backout: revert this PR. CI and lint will return to prior behavior.
  • Future cleanups: once upstream eslint configs stop referencing removed extension rules, remove the local rule shim and consider migrating to ESLint 9 + flat config.

Appendix — Diagnostics Commands

# Which parser is ESLint actually using for a file?
eslint --print-config src/index.ts | rg '"parser"\s*:\\s*".*parser'

# Show all installed versions of typescript-estree
yarn why @typescript-eslint/typescript-estree

# Inspect runtime versions
node -p "({parser:require('@typescript-eslint/parser/package.json').version, estree:require('@typescript-eslint/typescript-estree/package.json').version, eslint:require('eslint/package.json').version, ts:require('typescript/package.json').version})"

…ng pipeline; align TS 5.9; publish to Pages

This commit introduces a complete, professional documentation and quality assurance pipeline to improve developer experience, code quality, and maintainability — without changing runtime behavior.

Motivation
- Resolve the persistent "Unsupported TypeScript version" linter warning.
- Establish a coherent, enforceable documentation strategy that keeps the public API accurate and complete.
- Modernize CI for faster, more reliable builds and documentation deployments.

Key Achievements
1) New Documentation System
- TypeDoc generates a full API site from TSDoc comments.
- Comprehensive TSDoc across the public API (examples, remarks, platform-specific notes).
- New developer guide (docs/README.md) explains workflow, scope (entry point src/index.ts), troubleshooting, quick commands, and tooling alignment.
- New CI workflow (docs.yml) automatically builds and deploys the documentation site to GitHub Pages on every push to master; PRs also publish a typedoc-site preview artifact.

2) Unified & Strict Linting Pipeline
- The "yarn lint" command is now a single, unified quality gate: ESLint (style/syntax) + TypeDoc validation (documentation coverage).
- The build fails if any exported API is missing TSDoc comments, preventing documentation rot.
- TypeDoc runs with "--emit none" during lint (no HTML emission), keeping the feedback loop fast and side-effect free.

3) Dependency Conflict Resolution (TS 5.9)
- Upgraded @typescript-eslint (parser + plugin) to v8 to officially support TypeScript 5.9.
- Deterministic alignment via Yarn "resolutions" ensures one correct set of versions across the tree (parser, plugin, utils, typescript-estree, eslint-plugin-jest), eliminating nested old copies that emitted the warning.
- Set the explicit parser at the root (parser: '@typescript-eslint/parser') so ESLint does not pick a nested parser from extended configs.

4) Robust ESLint Configuration
- Targeted overrides keep src/specs/** from traversing into RN internals via import rules.
- Compatibility shim: '@typescript-eslint/func-call-spacing' (removed in v8) mapped to base 'func-call-spacing' — preserves intended behavior until upstream configs drop extension rules.

5) CI/CD Modernization
- Docs: Node 22 LTS, actions/checkout@v5, configure-pages@v5, upload-pages-artifact@v3, deploy-pages@v4; site built via "yarn docs:build" and deployed on push to master.
- Linter: ESLint job (Node 22 + Yarn cache) and SwiftLint job on macOS; both use modern Actions.
- Build: Node 22 + Yarn cache; Gradle wrapper validation + setup-gradle caching; Bundler caching on iOS (bundler-cache: true, BUNDLE_GEMFILE=example/Gemfile).

6) Packaging / README assets
- Added "images/" to package.json#files so README header images render on npm.

Notable Fix (iOS)
- requestDeviceCameraAuthorization now calls the correct TurboModule method (request...) instead of check.... Android remains "Not implemented" in the JS wrapper (unchanged).

Backward Compatibility
- No breaking API changes; Orientation values unchanged; runtime behavior unaffected.

How to Use
- Validate: yarn lint (ESLint + docs coverage, no HTML)
- Preview docs: yarn docs:build && yarn docs:serve (http://localhost:8080)

Verification
- eslint --print-config src/index.ts shows the top-level v8 parser.
- yarn why @typescript-eslint/typescript-estree shows only v8 in use.
- yarn build, yarn lint, and the Docs workflow succeed.

Follow-ups
- Flip workflow triggers if the default branch is not "master".
- Consider Ruby 3.x for the iOS example when the Gemfile allows.
- Remove rule shims and consider ESLint 9 + flat config once upstream configs drop extension rules.
Comment on lines -26 to 27
return await NativeCameraKitModule.checkDeviceCameraAuthorizationStatus();
return await NativeCameraKitModule.requestDeviceCameraAuthorization();
},
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quick fix

@@ -1,28 +1,83 @@
import { NativeModules } from 'react-native';
Copy link
Author

@gastonmorixe gastonmorixe Sep 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • TODO: manual review this whole file changes

PORTRAIT_UPSIDE_DOWN: 2,
/** Landscape: right edge up (Surface.ROTATION_270 on Android). */
LANDSCAPE_RIGHT: 3,
} as const;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • TODO: manual review as const doesn't break anything

Comment on lines +89 to +104
* - iOS: Saves a JPEG under Caches at `.../Library/Caches/<bundleId>/com.tesla.react-native-camera-kit/<unique>.jpg`.
* Includes `size` in bytes; `width`/`height` reflect the final pixel dimensions.
* - Android: Uses MediaStore/output file; returns a `file://` or `content://` URI.
* `id`/`path` may be empty on some devices. `width`/`height` intend to describe the saved image.
* - Orientation is already encoded in pixels and EXIF. No JS rotation required.
*
* @example Move to app documents (react-native-fs)
* ```ts
* import RNFS from 'react-native-fs';
* const photo = await ref.current?.capture();
* if (photo?.uri?.startsWith('file://')) {
* const fileName = photo.name;
* const dest = `${RNFS.DocumentDirectoryPath}/${fileName}`;
* await RNFS.moveFile(photo.uri.replace('file://', ''), dest);
* }
* ```
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • TODO: Double check this is correct

'prefer-const': 'error',
'no-multiple-empty-lines': 'error',
'no-unused-vars': 'error',
'no-unused-vars': 'off',
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • TODO: check impact of this change

'error',
{
code: 120,
ignoreComments: true, // allow longer TSDoc/comment lines
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • maybe not?

"build",
"dist",
"ios",
"images",
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI said this was needed for images to show in npm website

"@typescript-eslint/parser": "^8.44.1",
"eslint": "^8.57.0",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-jest": "^29.0.1",
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

upgraded to solve:

❯ yarn lint
yarn run v1.22.22
$ eslint --max-warnings=0 -c .eslintrc.js --ext .js,.jsx,.ts,.tsx,.mjs .
=============

WARNING: You are currently running a version of TypeScript which is not officially supported by @typescript-eslint/typescript-estree.

You may find that it works just fine, or you may not.

SUPPORTED TYPESCRIPT VERSIONS: >=4.7.4 <5.6.0

YOUR TYPESCRIPT VERSION: 5.9.2

Please only submit bug reports when using the officially supported version.

Comment on lines -17 to -25
uses: actions/checkout@v3
- name: Install modules
run: yarn
- name: Install Bundler
run: sudo gem install bundler
- name: Install gems
run: cd example && sudo bundle install
- name: Install example
run: yarn bootstrap-linux
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • TODO: check or revert this

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

- Add workflow_dispatch (shows Run button on master).
- Split deploy into production (push/dispatch) and PR preview (pull_request).
- Keep artifact fallback for all PRs.
- Update docs/README.md Automated Deployment to reflect PR previews and manual deploy on master.

Note: forked PRs will not publish preview (token is read-only); artifact remains.
- Remove pr-artifact job that re-uploaded the Pages artifact under a second name.
- Keep a single `github-pages` artifact; deploy uses it for production and PR previews.
- Update docs/README.md to explain preview behavior and that the standard artifact is available when previews are blocked.

No library code changes.
- Ignore example/.bundle/ and example/vendor/bundle/ so local Bundler config
  (BUNDLE_PATH=vendor/bundle) does not pollute the repo with thousands of files.
- Keeps existing root-level /vendor/bundle/ ignore intact.

Note: We intentionally do not commit any .bundle/config; it is developer-local.
…gn example Gemfile

Android:
- Remove explicit gradle/actions/wrapper-validation step; rely on setup-gradle@v4
  with validate-wrappers=true (built-in wrapper validation) and caching enabled.
- Use Node 20 for example build to match RN 0.79 guidance.

iOS:
- Ensure checkout occurs before Ruby setup.
- Enable bundler cache with BUNDLE_GEMFILE=example/Gemfile.
- Use Node 20 for yarn install.
- Add CODE_SIGNING_ALLOWED=NO to xcodebuild to avoid signing on CI.

Example app:
- Restore Gemfile constraints (match master):
  cocoapods ">=1.13" but not 1.15.0/1.15.1, activesupport ">=6.1.7.5" but not 7.1.0,
  xcodeproj "<1.26.0", concurrent-ruby "<1.3.4", and stdlib gems for newer rubies.

No source code changes.
- Change top-level script `bootstrap-linux` to run `yarn --ignore-scripts` in
  `example/` so it does not invoke `example`'s postinstall (which runs
  `bundle exec pod install`). This fixes the Android workflow error `/bin/sh: bundle: not found`.

Note: Intentionally not committing example/Gemfile.lock changes, which were
produced by a local Ruby 3.3.5 environment and would break CI (iOS job uses
ruby/setup-ruby 2.7.4). We'll keep the lockfile aligned with CI Ruby.
@gastonmorixe
Copy link
Author

gastonmorixe commented Sep 25, 2025

Comment on lines 106 to 112
// not mentioned in props but available on the native side
/** @internal Android-only: shutter flash animation duration in ms. */
shutterAnimationDuration?: WithDefault<Int32, -1>;
/** @internal Android-only: output file path override for captures. */
outputPath?: string;
/** @internal Android-only: internal picture taken event. */
onPictureTaken?: DirectEventHandler<{uri: string}>;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • TODO: investigate whether these are android only or not

Comment on lines +22 to +23
* - iOS: returns `size` in bytes; path is a `file://` URI under Caches.
* - Android: may include `id`/`path`; URI can be `file://` or `content://`.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Verify this

frameColor?: number | string;
barcodeFrameSize?: { width: number; height: number };
/** Size of the scanning frame.
* @defaultValue `{ width: 300, height: 150 }`
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Investigate and explain where is this default coming from

*/
scanThrottleDelay?: number;
/** **iOS Only**. 'speed' provides 60-80% faster image capturing */
/** iOS capture pipeline quality prioritization.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Any better way to mark iOS / Android only props?

"bootstrap-linux": "cd example/ && yarn --ignore-scripts",
"docs:clean": "rm -rf docs/site",
"docs:build": "typedoc && node scripts/postprocess-typedoc.mjs",
"docs:check": "typedoc",
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • maybe better to add --emit none here like lint script?

<h1 align="center">
🎈 React Native Camera Kit
</h1>
[![react-native-camera-kit](./images/header.png)](https://github.com/teslamotors/react-native-camera-kit)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Find a way to add an alt "React Native Camera Kit"

@@ -0,0 +1,100 @@
/* Themed tweaks for TypeDoc */
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/* Themed tweaks for TypeDoc */
/* Theme tweaks for TypeDoc */

Comment on lines +40 to +41
/* colors */

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/* colors */


- Every exported symbol has a TSDoc block with a one‑line summary.
- Use `@category` exactly once, choosing from: `Components`, `Constants`, `Enums`, `Events`, `Types`, `Other`.
- Add `@remarks` for platform notes and caveats (e.g., “Platform: iOS/Android”).
Copy link
Author

@gastonmorixe gastonmorixe Sep 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • or add a @platform whitelist

@scarlac scarlac requested a review from Copilot October 1, 2025 21:17
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces a comprehensive documentation system and modernizes the CI/lint infrastructure for react-native-camera-kit. It implements TypeDoc + TSDoc enforcement for complete API documentation coverage, upgrades to TypeScript-ESLint v8 for official TS 5.9 support, and adds automated GitHub Pages deployment.

Key changes:

  • Documentation system with TypeDoc + TSDoc validation enforcing 100% API coverage
  • ESLint + TypeScript alignment with v8 stack for official TS 5.9 support
  • CI modernization with automated Pages deployment and updated build workflows

Reviewed Changes

Copilot reviewed 28 out of 32 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
typedoc.json TypeDoc configuration with strict validation requiring documentation for all exported symbols
src/types.ts Complete TSDoc documentation for all type definitions and enums
src/specs/*.ts TSDoc documentation for TurboModule specs marked as internal
src/Camera*.tsx Component documentation with examples and platform-specific notes
package.json Updated dependencies, lint script, and added docs build commands
.eslintrc.js Updated to TypeScript-ESLint v8 with TSDoc validation and compatibility shims
.github/workflows/ Modernized CI workflows with Node 22, Yarn caching, and Pages deployment

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

}
},
"packageManager": "yarn@1.22.22"
,
Copy link

Copilot AI Oct 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an extra comma before the resolutions field. This should be removed as it creates invalid JSON syntax.

Suggested change
,

Copilot uses AI. Check for mistakes.
@gastonmorixe gastonmorixe marked this pull request as draft November 26, 2025 12:25
The documentation site is automatically built and deployed to GitHub Pages.

* **On Push to `master`:** Changes merged to `master` rebuild and publish the production site.
* **On Pull Requests (PR Preview):** CI publishes an ephemeral preview URL via GitHub Pages for PRs whose branch lives in this repository. The link appears on the PR checks as the environment URL for the "Deploy (PR Preview)" job and is cleaned up automatically when the PR closes. For forked PRs and Dependabot PRs (read‑only token) or when environment rules block previews, the build still uploads the standard `github-pages` artifact. Reviewers can download that artifact from the Actions run if a preview URL isn’t available.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may not work yet unfortunately (todo: add github issue link), the artifacts will work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants