diff --git a/.cursor/rules/README.md b/.cursor/rules/README.md new file mode 100644 index 00000000..0c75565b --- /dev/null +++ b/.cursor/rules/README.md @@ -0,0 +1,5 @@ +# Cursor (optional) + +**Cursor** users: start at the repo root **[`AGENTS.md`](../../AGENTS.md)**. All conventions live in **`skills/*/SKILL.md`** (universal for any editor or tool). + +This folder only points contributors here so nothing editor-specific duplicates the canonical docs. diff --git a/.github/workflows/check-version-bump.yml b/.github/workflows/check-version-bump.yml new file mode 100644 index 00000000..31bdf666 --- /dev/null +++ b/.github/workflows/check-version-bump.yml @@ -0,0 +1,79 @@ +# Catches when developers forget to bump package.json for release-affecting changes. +# App code changes (app.js, bin/, config/, routes/, views/, etc.) require a version bump vs latest tag. +# Skips for: test-only, docs, .github (workflows/config), dependency-only bumps without app edits. +name: Check Version Bump + +on: + pull_request: + +jobs: + version-bump: + name: Version bump + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Detect changed files and version bump + id: detect + run: | + if git rev-parse HEAD^2 >/dev/null 2>&1; then + FILES=$(git diff --name-only HEAD^1 HEAD^2) + else + FILES=$(git diff --name-only HEAD~1 HEAD) + fi + VERSION_FILES_CHANGED=false + echo "$FILES" | grep -qx 'package.json' && VERSION_FILES_CHANGED=true + echo "version_files_changed=$VERSION_FILES_CHANGED" >> $GITHUB_OUTPUT + # App source paths for this boilerplate (no lib/webpack/dist); .github/ and test/ do not count + CODE_CHANGED=false + echo "$FILES" | grep -qE '^app\.js$|^bin/|^config/|^middlewares/|^models/|^public/|^routes/|^views/|^schemaNentries/' && CODE_CHANGED=true + echo "$FILES" | grep -qx 'package.json' && CODE_CHANGED=true + echo "code_changed=$CODE_CHANGED" >> $GITHUB_OUTPUT + + - name: Skip when only test/docs/.github changed + if: steps.detect.outputs.code_changed != 'true' + run: | + echo "No release-affecting files changed (e.g. only test/docs/.github). Skipping version-bump check." + exit 0 + + - name: Fail when version bump was missed + if: steps.detect.outputs.code_changed == 'true' && steps.detect.outputs.version_files_changed != 'true' + run: | + echo "::error::This PR has code changes but no version bump. Please bump the version in package.json." + exit 1 + + - name: Setup Node + if: steps.detect.outputs.code_changed == 'true' && steps.detect.outputs.version_files_changed == 'true' + uses: actions/setup-node@v4 + with: + node-version: '22.x' + + - name: Check version bump + if: steps.detect.outputs.code_changed == 'true' && steps.detect.outputs.version_files_changed == 'true' + run: | + set -e + PKG_VERSION=$(node -p "require('./package.json').version.replace(/^v/, '')") + if [ -z "$PKG_VERSION" ]; then + echo "::error::Could not read version from package.json" + exit 1 + fi + git fetch --tags --force 2>/dev/null || true + LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || true) + if [ -z "$LATEST_TAG" ]; then + echo "No existing tags found. Skipping version-bump check (first release)." + exit 0 + fi + LATEST_VERSION="${LATEST_TAG#v}" + LATEST_VERSION="${LATEST_VERSION%%-*}" + if [ "$(printf '%s\n' "$LATEST_VERSION" "$PKG_VERSION" | sort -V | tail -1)" != "$PKG_VERSION" ]; then + echo "::error::Version bump required: package.json version ($PKG_VERSION) is not greater than latest tag ($LATEST_TAG). Please bump the version in package.json." + exit 1 + fi + if [ "$PKG_VERSION" = "$LATEST_VERSION" ]; then + echo "::error::Version bump required: package.json version ($PKG_VERSION) equals latest tag ($LATEST_TAG). Please bump the version in package.json." + exit 1 + fi + echo "Version bump check passed: package.json is at $PKG_VERSION (latest tag: $LATEST_TAG)." diff --git a/.github/workflows/issues-jira.yml b/.github/workflows/issues-jira.yml deleted file mode 100644 index 7bf04694..00000000 --- a/.github/workflows/issues-jira.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: Create Jira Ticket for Github Issue - -on: - issues: - types: [opened] - -jobs: - issue-jira: - runs-on: ubuntu-latest - steps: - - - name: Login to Jira - uses: atlassian/gajira-login@master - env: - JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} - JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} - JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} - - - name: Create Jira Issue - id: create_jira - uses: atlassian/gajira-create@master - with: - project: ${{ secrets.JIRA_PROJECT }} - issuetype: ${{ secrets.JIRA_ISSUE_TYPE }} - summary: Github | Issue | ${{ github.event.repository.name }} | ${{ github.event.issue.title }} - description: | - *GitHub Issue:* ${{ github.event.issue.html_url }} - - *Description:* - ${{ github.event.issue.body }} - fields: "${{ secrets.ISSUES_JIRA_FIELDS }}" \ No newline at end of file diff --git a/.github/workflows/sca-scan.yml b/.github/workflows/sca-scan.yml index f09161f5..79b65575 100644 --- a/.github/workflows/sca-scan.yml +++ b/.github/workflows/sca-scan.yml @@ -5,6 +5,9 @@ on: jobs: security-sca: runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write steps: - uses: actions/checkout@master - name: Run Snyk to check for vulnerabilities @@ -13,3 +16,6 @@ jobs: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} with: args: --all-projects --fail-on=all + json: true + continue-on-error: true + - uses: contentstack/sca-policy@main diff --git a/.gitignore b/.gitignore index 5524fdfd..2c27ea5d 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,6 @@ example/**/* _old_test_backup #dist -dist \ No newline at end of file +dist + +datasync-boilerplate \ No newline at end of file diff --git a/.husky/post-checkout b/.husky/post-checkout new file mode 100755 index 00000000..302fdc6a --- /dev/null +++ b/.husky/post-checkout @@ -0,0 +1,40 @@ +#!/usr/bin/env sh +# When switching to a branch that doesn't exist on remote (e.g. newly created), +# pull and merge origin/main or origin/master into current branch. Does not push. + +# Only run on branch checkout (not file checkout) +if [ "$3" != "1" ]; then + exit 0 +fi + +# Skip if we don't have a remote +if ! git rev-parse --verify origin 2>/dev/null; then + exit 0 +fi + +CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) + +# Skip main/master - no need to merge base into these +case "$CURRENT_BRANCH" in + main|master) exit 0 ;; +esac + +# Only run when current branch does not exist on origin (treat as new local branch) +if git ls-remote --heads origin "$CURRENT_BRANCH" 2>/dev/null | grep -q .; then + echo "post-checkout: $CURRENT_BRANCH exists on origin, skipping merge." + exit 0 +fi + +# Prefer main, fallback to master +if git rev-parse --verify origin/main 2>/dev/null; then + BASE=origin/main +elif git rev-parse --verify origin/master 2>/dev/null; then + BASE=origin/master +else + exit 0 +fi + +echo "New branch detected: merging latest $BASE into $CURRENT_BRANCH (local only, not pushing)..." +git fetch origin +git merge "$BASE" --no-edit --no-ff +echo "Done. Merge is local only; push when ready." diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..56757e65 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,49 @@ +# Contentstack DataSync Filesystem SDK – Agent guide + +**Universal entry point** for contributors and AI agents (Cursor, Copilot, CLI tools, or none). Conventions and detailed guidance live in **`skills/*/SKILL.md`**, not in editor-specific config, so the same instructions apply everywhere. + +**Flow:** [`.cursor/rules/README.md`](.cursor/rules/README.md) (optional, Cursor only) → **`AGENTS.md`** (this file) → **`skills//SKILL.md`** + +## What this repo is + +| Field | Detail | +|-------|--------| +| *Name:* | [`@contentstack/datasync-filesystem-sdk`](https://github.com/contentstack/datasync-filesystem-sdk/) | +| *Purpose:* | TypeScript/JavaScript library to **query locally synced filesystem JSON** produced by [Contentstack DataSync](https://www.contentstack.com/docs/guide/synchronization/contentstack-datasync), typically after sync via `@contentstack/datasync-content-store-filesystem`. | +| *Out of scope (if any):* | **Not** the Contentstack Delivery (CDA) or Management (CMA) HTTP SDK; **no** REST calls for core behavior—reads disk and runs in-process queries (`lodash`, `sift`, `json-mask`). | + +## Tech stack (at a glance) + +| Area | Details | +|------|---------| +| Language | TypeScript `^4.9.5` (`package.json`); Node.js v20+ recommended (`README.md`) | +| Build | `tsc` → `dist/`; declarations in `typings/`; `tsconfig.json`; `npm run build-ts` / `compile` | +| Tests | Jest + ts-jest; `jest.config.js`; tests under `test/**/*.ts` (see `testMatch` / ignores) | +| Lint / coverage | `npm run lint` (ESLint per `package.json` on `src/**/*.ts`); Jest coverage to `coverage/` | +| Other | Core deps: `lodash`, `sift`, `json-mask`, `mkdirp`; docs: `npm run build-doc` → `docs/` | + +## Commands (quick reference) + +| Command type | Command | +|--------------|---------| +| Build | `npm run build-ts` (clean + compile) or `npm run compile` (`tsc` only) | +| Test | `npm test` (`pretest` runs `build-ts`, then Jest with coverage) | +| Lint | `npm run lint` | + +Optional: CI and automation live under [`.github/workflows/`](.github/workflows/) (e.g. CodeQL, SCA, policy scans, version-bump checks—see each workflow for triggers). + +## Where the documentation lives: skills + +| Skill | Path | What it covers | +|-------|------|----------------| +| Dev workflow | [`skills/dev-workflow/SKILL.md`](skills/dev-workflow/SKILL.md) | Branches, hooks, build/test/lint, PR and version expectations | +| TypeScript (`src/`) | [`skills/typescript/SKILL.md`](skills/typescript/SKILL.md) | Compiler/lint, layout, JSDoc, dependencies—no HTTP/REST assumptions | +| DataSync filesystem SDK | [`skills/datasync-filesystem/SKILL.md`](skills/datasync-filesystem/SKILL.md) | Stack, config, query surface, DataSync vs CDA/CMA | +| Testing | [`skills/testing/SKILL.md`](skills/testing/SKILL.md) | Jest layout, fixtures, temp dirs, env, coverage | +| Code review | [`skills/code-review/SKILL.md`](skills/code-review/SKILL.md) | PR checklist, semver, terminology, severity labels | + +An index with “when to use” hints is in [`skills/README.md`](skills/README.md). + +## Using Cursor (optional) + +If you use *Cursor*, [`.cursor/rules/README.md`](.cursor/rules/README.md) only points to *[`AGENTS.md`](AGENTS.md)*—same docs as everyone else. diff --git a/CODEOWNERS b/CODEOWNERS index 0496bc6a..d9f2fb34 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,11 +1,5 @@ -* @contentstack/devex-pr-reviewers - -.github/workflows/sca-scan.yml @contentstack/security-admin - -.github/workflows/codeql-anaylsis.yml @contentstack/security-admin - +* @contentstack/developer-ecosystem-pr-reviewers +.github/workflows/ @contentstack/security-admin **/.snyk @contentstack/security-admin - -.github/workflows/policy-scan.yml @contentstack/security-admin - -.github/workflows/issues-jira.yml @contentstack/security-admin +**/CODEOWNERS @contentstack/security-admin +**/.gitguardian.yaml @contentstack/security-admin \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 918df6ff..067cb180 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@contentstack/datasync-filesystem-sdk", - "version": "1.5.1", + "version": "1.5.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@contentstack/datasync-filesystem-sdk", - "version": "1.5.1", + "version": "1.5.3", "license": "MIT", "dependencies": { "json-mask": "2.0.0", diff --git a/package.json b/package.json index 05b88dc2..d3c793e0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/datasync-filesystem-sdk", - "version": "1.5.1", + "version": "1.5.3", "description": "JavaScript filesystem SDK to query data synced via @contentstack/datasync-content-store-filesystem", "main": "dist/index.js", "scripts": { diff --git a/skills/README.md b/skills/README.md new file mode 100644 index 00000000..b969d01e --- /dev/null +++ b/skills/README.md @@ -0,0 +1,20 @@ +# Skills – Contentstack DataSync Filesystem SDK + +**This directory is the source of truth** for detailed conventions (workflow, TypeScript/`src/`, DataSync SDK behavior, tests, code review). Read [`AGENTS.md`](../AGENTS.md) at the repo root for the index and quick commands; each skill is a folder with **`SKILL.md`** (YAML frontmatter: `name`, `description`). + +## When to use which skill + +| Skill folder | Use when | +|--------------|----------| +| [`dev-workflow/`](dev-workflow/SKILL.md) | Branching (`development` / `master`), local hooks, running build/test/lint, releases and version bumps | +| [`typescript/`](typescript/SKILL.md) | TypeScript/`tsconfig`, ESLint, `src/` layout, JSDoc, style in library code | +| [`datasync-filesystem/`](datasync-filesystem/SKILL.md) | Stack, config, query surface, DataSync vs CDA/CMA—behavior in `src/` | +| [`testing/`](testing/SKILL.md) | Writing or debugging Jest tests, fixtures, `test/utils`, coverage | +| [`code-review/`](code-review/SKILL.md) | Reviewing or preparing PRs—API, compatibility, tests, terminology | + +Each folder contains `SKILL.md` with YAML frontmatter (`name`, `description`). + +## How to use these docs + +- **Humans / any AI tool:** Start at **`AGENTS.md`**, then open the relevant **`skills//SKILL.md`**. +- **Cursor users:** **[`.cursor/rules/README.md`](../.cursor/rules/README.md)** only points to **`AGENTS.md`** so guidance stays universal—no duplicate rule prose required in `.cursor/rules/`. diff --git a/skills/code-review/SKILL.md b/skills/code-review/SKILL.md new file mode 100644 index 00000000..a464ea9e --- /dev/null +++ b/skills/code-review/SKILL.md @@ -0,0 +1,61 @@ +--- +name: code-review +description: PR review checklist for DataSync Filesystem SDK—API docs, compatibility, tests, terminology (not CDA/CMA HTTP SDK) +--- + +# Code review – Contentstack DataSync Filesystem SDK + +## When to use + +- Reviewing a pull request that touches `src/`, `test/`, or public docs +- Preparing your own PR and self-checking before request for review +- Verifying semver impact or regression risk for query/config behavior + +## Instructions + +### Scope and terminology + +- This package is the **DataSync Filesystem SDK** (local synced content). Do **not** describe it as the **CDA** or **CMA** HTTP client unless the change explicitly documents comparison or migration. +- Distinguish **in-memory/filesystem** queries from **REST** or **CDN** behavior. +- Confirm behavior changes are covered by **filesystem-based** Jest tests, not live API calls. + +### Public API and docs + +- Exported APIs should have accurate **JSDoc** (`@public`, parameters, return shape). +- **README** and **example/** snippets must match real `Contentstack.Stack` usage and config keys. + +### Compatibility + +- Avoid breaking query result shape, config schema, or public method signatures without a **semver-major** plan and changelog intent. +- Deprecations: comment + document clearly. + +### Errors and messages + +- Prefer centralized strings from **`src/messages.ts`** (`ERROR_MESSAGES`, `WARNING_MESSAGES`); keep messages actionable. + +### Correctness and null safety + +- Guard missing files, empty arrays, and malformed JSON consistently with patterns in `stack.ts` / `fs.ts`. + +### Dependencies and security + +- New dependencies need justification (bundle size, maintenance). Align with **`package.json`**. +- Consider **Snyk** / org policy — `pretest` does not replace dependency review. + +### Tests + +- Behavioral changes in **`src/`** need matching updates under **`test/`** with fixtures in **`test/data/`** — not live API calls. + +### Optional severity + +| Level | Examples | +|-------|----------| +| Blocker | Wrong query results, data loss risk, security issue, broken public API contract | +| Major | Missing tests for core behavior, breaking change without version/docs strategy | +| Minor | Style, non-user-facing refactors, doc nits | + +## References + +- [`../testing/SKILL.md`](../testing/SKILL.md) +- [`../datasync-filesystem/SKILL.md`](../datasync-filesystem/SKILL.md) +- [`../../AGENTS.md`](../../AGENTS.md) diff --git a/skills/datasync-filesystem/SKILL.md b/skills/datasync-filesystem/SKILL.md new file mode 100644 index 00000000..1c1bc7e8 --- /dev/null +++ b/skills/datasync-filesystem/SKILL.md @@ -0,0 +1,61 @@ +--- +name: datasync-filesystem +description: DataSync Filesystem SDK mental model—Stack, contentStore paths, queries in src/; not CDA/CMA HTTP +--- + +# SDK core and queries – Contentstack DataSync Filesystem SDK + +## When to use + +- Implementing or changing query behavior, filters, or references in `src/stack.ts` +- Adjusting defaults, paths, or locale handling (`src/config.ts`, `src/utils.ts`, `src/fs.ts`) +- Adding exports or user-facing errors (`src/index.ts`, `src/messages.ts`) + +## Instructions + +### Product model + +- This is the **filesystem query SDK** for **DataSync-stored** JSON — **not** the Contentstack **Delivery** or **Management** REST SDK. +- **Stack** here means the in-memory/query facade over **disk**, not an API stack or region endpoint. +- **`@contentstack/datasync-filesystem-sdk`** reads JSON after DataSync / `@contentstack/datasync-content-store-filesystem` sync; it does **not** call Contentstack REST APIs for core behavior. + +### Entry flow + +1. **`Contentstack.Stack(userConfig)`** in `src/index.ts` merges config and returns **`Stack`** (`src/stack.ts`). +2. **`Stack.connect()`** resolves when the stack is ready to query; use `.then()` / `.catch()` as in README examples. +3. Queries from **`contentType('uid')`**, **`assets()`**, then filters, references, pagination, projections — see `src/stack.ts`. + +### Configuration + +- **`Contentstack.Stack(config)`** merges into internal config (`setConfig` / `getConfig` in `src/index.ts`). +- Typical shape: `contentStore.baseDir`, `contentStore.patterns` (assets, content_types, entries), `locale`, `referenceDepth`, `projections`, `defaultSortingField` — see `src/config.ts` defaults and README. +- Optional **env:** `APP_ROOT` can influence where content resolves (README). +- Path helpers: **`src/utils.ts`**; promisified reads and FS helpers: **`src/fs.ts`**. + +### Query execution + +- Entry points: **`contentType(uid)`**, **`assets()`**, query builders (filters, references, sort, skip/limit, projections) in **`src/stack.ts`**. +- **Filtering:** `sift`; **sort/merge:** `lodash`; **projections:** `json-mask` where used. +- **References:** depth from config and `includeReferences` behavior in `stack.ts`. + +### Scope + +- **`src/`** SDK core is canonical; **`example/`** is illustrative only — not the source of API design. + +### Where to change code + +| Concern | Start here | +|---------|------------| +| New operator or filter | `src/stack.ts` | +| Path / base dir / `APP_ROOT` | `src/config.ts`, `src/utils.ts`, `README.md` | +| FS reads | `src/fs.ts` | +| User-visible messages | `src/messages.ts` | +| Public API surface | `src/index.ts` | + +## References + +- [DataSync guide](https://www.contentstack.com/docs/guide/synchronization/contentstack-datasync) +- [SDK query examples](https://contentstack.github.io/datasync-filesystem-sdk/) (when linked from repo README) +- [`../typescript/SKILL.md`](../typescript/SKILL.md) — TypeScript and `src/` conventions +- [`../testing/SKILL.md`](../testing/SKILL.md) +- [`../../AGENTS.md`](../../AGENTS.md) diff --git a/skills/dev-workflow/SKILL.md b/skills/dev-workflow/SKILL.md new file mode 100644 index 00000000..0a89d4fc --- /dev/null +++ b/skills/dev-workflow/SKILL.md @@ -0,0 +1,61 @@ +--- +name: dev-workflow +description: Branches, Husky hooks, build/test/lint commands, PR expectations, and version bumps for this repo +--- + +# Dev workflow – Contentstack DataSync Filesystem SDK + +## When to use + +- Setting up the repo locally or onboarding +- Before opening or updating a PR +- Planning a release or changing `package.json` version + +## Instructions + +### Branches + +- Use **feature branches** for new work; open pull requests against **`development`** to integrate changes. +- For a **release**, open a pull request from **`development`** into **`master`**. Releases to npm are driven from **`master`**. +- Alternatively, follow your team’s current branch policy if it differs. + +### Install and build + +```bash +npm install +npm run build-ts +``` + +`npm run build-ts` cleans `dist/`, `typings/`, `coverage/` and runs `tsc` (`package.json`). + +### Quality gates + +```bash +npm run lint # ESLint — see package.json for config path and globs +npm test # pretest runs build-ts, then Jest with coverage +``` + +- Jest runs `test/**/*.ts` except ignored paths in `jest.config.js` (e.g. `test/data/*`, `test/utils.ts`). Suites use fixtures under `test/data/` and temp trees per module (see `test/utils.ts`). + +### PR expectations + +- Run **build**, **lint**, and **tests** before opening or updating a PR. +- Avoid committing secrets; **Talisman** runs on pre-commit when configured. +- For **release-impacting** changes to library behavior or `src/`, coordinate a **`package.json` version bump** with maintainers. If **Check Version Bump** (or similar) in `.github/workflows/` applies, follow its rules. + +### Hooks (`.husky/`) + +- `.husky/pre-commit` runs **Talisman** and **Snyk** when those tools are installed; use `SKIP_HOOK=1` only when your team allows bypassing checks. + +### Docs + +- `npm run build-doc` — JSDoc site (requires successful `build-ts` first). + +### CI + +- Workflows under `.github/workflows/` include CodeQL, SCA, policy scans, version-bump checks—see each file for triggers. + +## References + +- [`../testing/SKILL.md`](../testing/SKILL.md) — Jest and test layout +- [`../../AGENTS.md`](../../AGENTS.md) — entry point and commands table diff --git a/skills/testing/SKILL.md b/skills/testing/SKILL.md new file mode 100644 index 00000000..fd735e83 --- /dev/null +++ b/skills/testing/SKILL.md @@ -0,0 +1,62 @@ +--- +name: testing +description: Jest tests for datasync-filesystem-sdk—pretest build, fixtures, test/utils, ignores, coverage, no live API +--- + +# Testing – Contentstack DataSync Filesystem SDK + +## When to use + +- Adding or changing tests under `test/` +- Debugging failures after `src/` changes +- Understanding why a path is ignored in Jest or how temp dirs are created + +## Instructions + +### Commands + +- `npm test` — `pretest` runs `npm run build-ts`, then Jest with coverage (`jest.config.js`). +- `npm run build-ts` — use alone when you need `dist/` / `typings/` before debugging tests. + +### Runner and config + +- **Jest** with **ts-jest**, **Node** environment (`jest.config.js`). +- **Coverage:** enabled; output under `coverage/` (`collectCoverage` true). +- **Ignored from test discovery:** `test/data/*`, `test/utils.ts`, and paths in `testPathIgnorePatterns` — change only together with `jest.config.js`. + +### Layout + +| Path | Role | +|------|------| +| `test/**/*.ts` | Test suites (`testMatch` in `jest.config.js`) | +| `test/data/` | Static JSON fixtures (ignored as test files) | +| `test/utils.ts` | `init`, `populate*`, `destroy` (ignored as a test file) | +| Per-suite dirs | Temp content under `test//` via `init(Contentstack, config, moduleName)` | + +### Naming and style + +- Suites use `describe` / `it` with labels like `# Core`, `# Queries` (existing convention). +- File names need not be `*.test.ts`; Jest matches by path pattern. +- **No live HTTP** — tests exercise the SDK against **written files** only. + +### Environment and credentials + +- **No** Delivery or Management API keys for default tests. +- Optional: `APP_ROOT` only if a test exercises README-documented root resolution. + +### Mocks and I/O + +- Tests write **real files** under temp directories; reuse `populateAssets`, `populateContentTypes`, `pupulateEntries` from `test/utils.ts` where applicable. + +### Coverage + +- Reports under `coverage/`; change `jest.config.js` only when intentionally adjusting collect rules. + +### Notifications + +- Jest `notify: true` may use `node-notifier` locally — notification failures are normal if unavailable in CI. + +## References + +- [`../datasync-filesystem/SKILL.md`](../datasync-filesystem/SKILL.md) — what `src/` is doing under test +- [`../../AGENTS.md`](../../AGENTS.md) diff --git a/skills/typescript/SKILL.md b/skills/typescript/SKILL.md new file mode 100644 index 00000000..b57dbadd --- /dev/null +++ b/skills/typescript/SKILL.md @@ -0,0 +1,39 @@ +--- +name: typescript +description: TypeScript conventions for src/—tsconfig, ESLint, layout, JSDoc, no HTTP/REST assumptions +--- + +# TypeScript (`src/`) – Contentstack DataSync Filesystem SDK + +## When to use + +- Editing or adding files under `src/` +- Aligning with compiler and lint settings +- Choosing where new code belongs (`index.ts`, `stack.ts`, `utils.ts`, etc.) + +## Instructions + +### Tooling + +- **Compiler:** `tsconfig.json` — `module` CommonJS, `target` ES6, unused locals/parameters, `noImplicitReturns`, declarations emitted to `typings/`. +- **Lint:** `npm run lint` uses ESLint with the config referenced in `package.json` (a `.eslintrc` may also exist at repo root). +- **Formatting:** `.jsbeautifyrc` at repo root; match neighboring code (indentation, quotes, semicolons). + +### Layout + +- Keep the public surface in `src/index.ts`; heavy logic stays in `stack.ts`, `utils.ts`, `fs.ts`, `config.ts`, `messages.ts`. +- Prefer **JSDoc** on exported symbols (`@public`, `@description`, `@api`) for `npm run build-doc`. +- Use **error/warning** patterns from `messages.ts` instead of ad hoc user-facing strings where appropriate. + +### Logging + +- Avoid `console` noise in library code; tests may use `debug` (see `test/utils.ts`). + +### Dependencies + +- Do not add HTTP clients or REST assumptions — this SDK targets **local filesystem** content and in-process queries. New deps must align with `package.json` and team policy. + +## References + +- [`../datasync-filesystem/SKILL.md`](../datasync-filesystem/SKILL.md) — SDK behavior and Stack API +- [`../../AGENTS.md`](../../AGENTS.md)