|
| 1 | +# AI Coding Agent Instructions |
| 2 | + |
| 3 | +Concise, project-specific guidance for working in this repo. Keep answers short, concrete, and adapt to these conventions. |
| 4 | + |
| 5 | +## Project Purpose |
| 6 | + |
| 7 | +Small TypeScript utility library published as `@supernaut/storyblok-tools` providing helpers for integrating Storyblok preview/editor features (currently: request validation for Storyblok visual editor iframe). |
| 8 | + |
| 9 | +## Tech Stack & Build |
| 10 | + |
| 11 | +- Language: TypeScript (strict) targeting ES2020; ESM + CJS outputs built via `tsup`. |
| 12 | +- Entry points declared explicitly in `tsup.config.ts`; update both `src/index.ts` (re-exports) AND `tsup.config.ts` (entry map) AND `package.json.exports` when adding a new public module. |
| 13 | +- No runtime framework dependencies beyond the Web Crypto API (Node >=18 provides `crypto.subtle`). Peer deps (`next`, `react`, `react-dom`) are declared for host apps but not used directly (forward compatibility). |
| 14 | + |
| 15 | +## Key Commands |
| 16 | + |
| 17 | +- Build: `pnpm build` (tsup) – cleans & emits `dist` with d.ts + sourcemaps. |
| 18 | +- Tests: `pnpm test` (vitest). Coverage: `pnpm test:coverage` (thresholds: branches 85 / funcs 90 / lines 90 / statements 90). |
| 19 | +- Lint: `pnpm lint` (ESLint w/ perfectionist, sonarjs, unused-imports). Auto-fix staged on pre-commit. |
| 20 | +- Type check (no emit): `pnpm type-check`. |
| 21 | +- Release (manual): bump version in `package.json`, generate changelog (step placeholder "conventional-changelog"), commit + tag + push. (No automated release script yet.) |
| 22 | + |
| 23 | +## Testing Patterns |
| 24 | + |
| 25 | +- Vitest with globals; spec files live beside source (`*.spec.ts`). |
| 26 | +- For functions that call helpers, mock dependencies BEFORE importing the SUT (see `is-storyblok-request.spec.ts` mocking `./sha1`). Maintain this pattern for new modules needing isolation. |
| 27 | +- Exhaustive negative-path tests favored (individual guard clauses). Follow style: one assertion per behavioral branch returning `false`. |
| 28 | + |
| 29 | +## Function Design Conventions |
| 30 | + |
| 31 | +- Use explicit guard clauses for parameter validation; prefer early `return false` for validation utilities instead of throwing (see `isStoryblokRequest`). |
| 32 | +- Preserve environment-variable requirements exactly (e.g., even if a preview token is passed as an argument, `process.env.STORYBLOK_PREVIEW_TOKEN` must exist). Document any seemingly redundant checks in JSDoc. |
| 33 | +- Async crypto/hash helpers return lowercase hex strings (40 chars for SHA-1). Maintain streaming/Uint8Array to hex pattern if adding hashes. |
| 34 | + |
| 35 | +## Adding a New Public Utility |
| 36 | + |
| 37 | +1. Implement in `src/lib/<name>.ts` with strict typing & JSDoc. |
| 38 | +2. Create `src/lib/<name>.spec.ts` covering: |
| 39 | + - Happy path |
| 40 | + - Each early-return / guard |
| 41 | + - Edge boundaries (time window, empty values, mismatched hashes, etc.). |
| 42 | +3. Export from `src/index.ts`. |
| 43 | +4. Add entry in `tsup.config.ts` `entry` map if standalone path import desired. |
| 44 | +5. Add corresponding conditional export block in `package.json.exports` (both `import` & `require`). |
| 45 | +6. Run lint, type-check, tests, build. |
| 46 | + |
| 47 | +## Style & Lint Nuances |
| 48 | + |
| 49 | +- Type aliases over interfaces (`@typescript-eslint/consistent-type-definitions`). |
| 50 | +- Unused imports auto-removed (`unused-imports` plugin). Avoid leaving commented-out imports. |
| 51 | +- Natural sorting preference (`perfectionist` plugin) – keep object keys sorted naturally when modifying existing objects. |
| 52 | + |
| 53 | +## Error & Logging Approach |
| 54 | + |
| 55 | +- Validation utilities swallow errors & return `false`, while logging a structured object via `console.error({ error, method, ...context })`. Keep this shape for consistency & future parsing. |
| 56 | + |
| 57 | +## Coverage Strategy |
| 58 | + |
| 59 | +- Guard branches exist partly to raise branch coverage; when modifying logic, adjust or add tests to maintain thresholds. |
| 60 | +- New early-return branches MUST have corresponding spec cases. |
| 61 | + |
| 62 | +## Environment & Crypto |
| 63 | + |
| 64 | +- Node >=18 required; relies on global `crypto.subtle`. If adding code needing Web APIs, either stay within APIs available in Node 18+ or add lightweight polyfills guarded behind feature detection. |
| 65 | + |
| 66 | +## Commit & Hooks |
| 67 | + |
| 68 | +- Conventional commits enforced via commitlint + czg. For automated commits, use a valid type (`feat`, `fix`, `docs`, etc.). No need for emojis (disabled by config). |
| 69 | +- Pre-commit runs prettier + eslint (auto-fix) on staged files; pre-push runs full test suite. Ensure tests pass locally before pushing heavy changes. |
| 70 | + |
| 71 | +## Publishing Safety Checklist (Manual) |
| 72 | + |
| 73 | +- All tests & coverage thresholds pass. |
| 74 | +- `dist` rebuilt fresh (`pnpm build`). |
| 75 | +- Version bumped; `CHANGELOG.md` updated (tool not yet scripted here). |
| 76 | +- Tag matches version (e.g., `v1.0.1`). |
| 77 | + |
| 78 | +## Not Yet Implemented (Avoid Assuming) |
| 79 | + |
| 80 | +- No automated changelog script or release GitHub Action present. |
| 81 | +- Commented-out tsup entries indicate potential future utilities; don’t resurrect without confirming design. |
| 82 | + |
| 83 | +## When Unsure |
| 84 | + |
| 85 | +Prefer inspecting existing pattern in `is-storyblok-request` & its spec; mirror structure & verbosity level. Keep public API minimal & explicit. |
| 86 | + |
| 87 | +--- |
| 88 | + |
| 89 | +Provide clarifying questions only if a requirement cannot be met from repository context. |
0 commit comments