diff --git a/.cursor/rules/README.md b/.cursor/rules/README.md new file mode 100644 index 00000000..2216160d --- /dev/null +++ b/.cursor/rules/README.md @@ -0,0 +1,49 @@ +# Cursor Rules Documentation + +This directory contains **Cursor AI rules** that provide context-aware guidance for the **Contentstack Management JavaScript SDK** (`@contentstack/management`) — CMA client development, not a separate CLI repo. + +## Rules overview + +| Rule | Role | +|------|------| +| [`dev-workflow.md`](dev-workflow.md) | Branches, lint/tests before PR (unit + optional sanity), version bump guidance, links to skills | +| [`javascript.mdc`](javascript.mdc) | JavaScript / TypeScript declaration style: `lib/`, `webpack/`, `types/`, root `*.mjs` | +| [`contentstack-javascript-cma.mdc`](contentstack-javascript-cma.mdc) | CMA SDK patterns in `lib/`: client, stack, auth, host/region, HTTP/error handling | +| [`testing.mdc`](testing.mdc) | Mocha unit suite, sanity/API tests, Jest + `test/typescript`; env and mocks | +| [`code-review.mdc`](code-review.mdc) | PR checklist: JSDoc, compat, errors, SCA, unit + sanity tests, CMA semantics (**always applied**) | + +## Rule application + +Rules load from **globs** and **`alwaysApply`** in each file’s frontmatter (not every rule runs for every file). + +| Context | Typical rules | +|---------|----------------| +| **Every chat / session** | [`code-review.mdc`](code-review.mdc) (`alwaysApply: true`) | +| **Most project files** | [`dev-workflow.md`](dev-workflow.md) — `**/*.js`, `**/*.ts`, `**/*.json`, `**/*.mjs` | +| **SDK implementation** | [`javascript.mdc`](javascript.mdc) + [`contentstack-javascript-cma.mdc`](contentstack-javascript-cma.mdc) for `lib/**/*.js` | +| **Build config** | [`javascript.mdc`](javascript.mdc) for `webpack/**/*.js` | +| **Public types** | [`javascript.mdc`](javascript.mdc) for `types/**` | +| **Tests** | [`testing.mdc`](testing.mdc) for `test/unit/**`, `test/sanity-check/**`, `test/typescript/**`, `test/**/index.js` | + +Overlaps are expected (e.g. editing `lib/foo.js` can match `dev-workflow`, `javascript`, and `contentstack-javascript-cma`). + +## Usage + +- Rules are **loaded automatically** when opened files match their globs (and `code-review` is always in context). +- You can **@ mention** rule files in chat when your Cursor build supports file references, e.g. `@dev-workflow`, `@javascript`, `@contentstack-javascript-cma`, `@testing`, `@code-review` (exact names depend on how Cursor labels `.md` / `.mdc` rules in your project). + +## Quick reference table + +| File | `alwaysApply` | Globs (summary) | +|------|---------------|-----------------| +| `dev-workflow.md` | no | `**/*.js`, `**/*.ts`, `**/*.json`, `**/*.mjs` | +| `javascript.mdc` | no | `lib/**/*.js`, `webpack/**/*.js`, `types/**/*.ts`, `types/**/*.d.ts`, `*.mjs` | +| `contentstack-javascript-cma.mdc` | no | `lib/**/*.js` | +| `testing.mdc` | no | `test/unit/**`, `test/sanity-check/**`, `test/typescript/**`, `test/**/index.js` | +| `code-review.mdc` | **yes** | — | + +## Skills & maintenance + +- Deeper playbooks: [`skills/README.md`](../../skills/README.md). +- Repo agent entry: [`AGENTS.md`](../../AGENTS.md). +- When directories change, update **globs** in rule frontmatter; keep rules short and put detail in `skills/*/SKILL.md`. diff --git a/.cursor/rules/code-review.mdc b/.cursor/rules/code-review.mdc new file mode 100644 index 00000000..6386a87b --- /dev/null +++ b/.cursor/rules/code-review.mdc @@ -0,0 +1,39 @@ +--- +description: "PR review themes — API docs, compatibility, errors, security, tests" +alwaysApply: true +--- + +# Code review checklist (CMA JavaScript SDK) + +Apply when reviewing changes to `@contentstack/management`. + +## Public API & documentation + +- **JSDoc** updated for new or changed public methods/classes (params, return shape, examples), matching style in `lib/contentstack.js` / `lib/contentstackClient.js`. +- **`types/**`** updated when TypeScript consumers would see different signatures or new exports. + +## Backward compatibility + +- Avoid breaking changes to exported function signatures, option objects, or default behavior without a major version rationale. +- If behavior changes, ensure **callers inside `lib/`** and tests reflect the new contract. + +## Errors & safety + +- HTTP failures should flow through **`lib/core/contentstackError.js`** (or equivalent existing error path), preserving **status** and safe **request** metadata. +- Do not log or stringify full **authtoken**, **authorization**, or **management_token** values; follow existing redaction patterns in `contentstackError.js`. +- Respect **null/undefined** edge cases for optional API fields; avoid assuming nested objects always exist. + +## Dependencies & supply chain + +- New **dependencies** should be justified (size, maintenance, license); prefer existing `lodash` / `axios` patterns. +- Lockfile and **`package.json`** version bumps should be minimal and reviewable. + +## Tests + +- **Unit tests** for new logic or regressions (`test/unit/`), with HTTP **mocked** (Nock, axios-mock-adapter, Sinon, etc.). +- **Sanity / API tests** (`test/sanity-check/api/`) when change affects live CMA behavior, request shape, or end-to-end flows: add or update the relevant `*-test.js` suite and ensure **`sanity.js`** still wires it; run against **`dist/node/contentstack-management.js`** after **`npm run build`**. Do not commit secrets; env vars belong in `test/sanity-check/utility/testSetup.js` documentation only. +- Document any new env requirements for sanity in **`test/sanity-check/utility/testSetup.js`** header comments. + +## Security & privacy + +- No hardcoded credentials; no accidental exposure of customer content in logs or error messages. diff --git a/.cursor/rules/contentstack-javascript-cma.mdc b/.cursor/rules/contentstack-javascript-cma.mdc new file mode 100644 index 00000000..1a681a91 --- /dev/null +++ b/.cursor/rules/contentstack-javascript-cma.mdc @@ -0,0 +1,40 @@ +--- +description: "Contentstack CMA SDK patterns for lib/ (Management API client)" +globs: ["lib/**/*.js"] +alwaysApply: false +--- +# Contentstack CMA SDK (`lib/`) + +This package implements the **Content Management API (CMA)** client, not the read-only Content Delivery API. + +## Client + +- Entry: **`contentstack.client(params)`** in `lib/contentstack.js` — wires HTTP client, region/host/endpoint, **timeout**, **retryOnError**, **retryLimit**, **retryDelay**, **maxRequests**, **early_access**, optional **proxy**, **plugins**, etc. +- Endpoint resolution uses **`getContentstackEndpoint`** from `@contentstack/utils` where applicable (see `contentstack.js`). + +## Authentication & stack scoping + +- **User/session**: `authtoken` or `authorization` header patterns set on the axios instance after `login` (`lib/contentstackClient.js`). +- **Stack**: `client.stack({ api_key, management_token, ... })` — management token is stack-scoped. +- **Organization**: `client.organization()` for org-level operations. +- **Branch**: pass branch options where the Stack/entity factory methods accept them (match existing callers in `lib/stack/`). + +## HTTP & errors + +- All requests go through the **axios** instance created in **`lib/core/contentstackHTTPClient.js`** (concurrency queue, interceptors, retries on e.g. **429** per `retryCondition`). +- Failures should continue to use **`lib/core/contentstackError.js`** in promise rejection chains (e.g. `.then(success, error)`), producing errors with **status**, **request** metadata, and **`error_message` / `error_code`** from CMA JSON when present. + +## Resource modules + +- **Entity** helpers and collection patterns: `lib/entity.js`, `lib/contentstackCollection.js`, `lib/query/index.js`. +- New resources should follow existing **constructor(http, data)** + **`urlPath`** + **`stackHeaders`** patterns in sibling modules under `lib/stack/`. + +## Callbacks vs async + +- Prefer **Promises** (`async`/`await` or `.then`) consistent with surrounding code; avoid introducing callback-style APIs unless matching an existing public surface. + +## CMA concepts + +This SDK targets the **Content Management API (CMA)**, not the Content Delivery API. + +- **Entry, Query, Asset, Content type, Taxonomy (terms, etc.), Stack, Branch, Locale, Webhooks,** and related resources — follow existing **class/module names and method names** in `lib/stack/` (and siblings) and **Management API** semantics (paths, query/body shapes, response parsing). When adding or changing CMA features, align with the official [Content Management API](https://www.contentstack.com/docs/developers/apis/content-management-api/) documentation. \ No newline at end of file diff --git a/.cursor/rules/dev-workflow.md b/.cursor/rules/dev-workflow.md new file mode 100644 index 00000000..ac844124 --- /dev/null +++ b/.cursor/rules/dev-workflow.md @@ -0,0 +1,32 @@ +--- +description: "Branches, tests, and PR expectations for contentstack-management-javascript" +globs: ["**/*.js", "**/*.ts", "**/*.json", "**/*.mjs"] +alwaysApply: false +--- + +# Development workflow - Contentstack javascript CMA SDK + +## Branches + +- Follow team Git conventions (e.g. feature branches off `development` / default integration branch as used in this repo). +- Keep commits focused; do not commit with `test.only`, `it.only`, `describe.only`, or skipped tests meant to be permanent. + +## Before opening a PR + +1. **`npm run lint`** — ESLint must pass on `lib` and `test`. +2. **Unit tests** — `npm run test:unit` (default `npm test` also invokes `test:api` first — ensure that script exists in `package.json` on your branch). +3. **Sanity / API tests** — only when explicitly validating against live CMA: run `npm run test:sanity-nocov` or `test:sanity-test` after **`npm run build`**, with env vars documented in `test/sanity-check/utility/testSetup.js` (`EMAIL`, `PASSWORD`, `HOST`, `ORGANIZATION`, etc.). Never commit secrets. +4. **Version bump** — When the PR introduces **user-visible or release-worthy** `lib/` behavior (new API, bug fix shipped to npm, or a **breaking** change), update **`version`** in `package.json` per **semver**: **patch** (fixes, internal-compatible tweaks), **minor** (backward-compatible features or additive API), **major** (breaking public contract). Docs-only, tests-only, or chore-only changes often **omit** a bump if your team bumps only at release; follow team practice (some repos bump only on `main`/`release`). If unsure, ask the reviewer or match sibling PRs. + +## PR expectations (summary) + +- **User-facing changes** — JSDoc on public methods; update `types/**` when the public surface changes. +- **Behavior** — Preserve backward compatibility unless the change is explicitly breaking and documented. +- **Errors** — Route HTTP failures through existing patterns (`lib/core/contentstackError.js`-style handling); avoid leaking full tokens in logs (existing code redacts authtoken/authorization in error paths). +- **Tests** — Add or adjust unit tests under `test/unit/` for new behavior; use mocks (Sinon / Nock / axios-mock-adapter) rather than live API in unit tests. + +## Quick links + +- Agent overview: repo root `AGENTS.md` +- CMA SDK patterns: `skills/contentstack-javascript-cma/SKILL.md` +- HTTP / retry layer: `skills/framework/SKILL.md` diff --git a/.cursor/rules/javascript.mdc b/.cursor/rules/javascript.mdc new file mode 100644 index 00000000..7065e5b2 --- /dev/null +++ b/.cursor/rules/javascript.mdc @@ -0,0 +1,33 @@ +--- +description: "JavaScript/TypeScript conventions for lib, types, and webpack" +globs: + - "lib/**/*.js" + - "webpack/**/*.js" + - "types/**/*.ts" + - "types/**/*.d.ts" + - "*.mjs" +alwaysApply: false +--- + +# JavaScript & types (this repo) + +## Runtime & modules + +- **Source** is **ES modules** under `lib/` (`import` / `export`). Builds target Node and browsers via Babel + Webpack (see `package.json` scripts). +- **`types/`** holds public TypeScript declarations consumed from npm; keep them aligned with `lib/` JSDoc and exports. + +## Style & tooling + +- **ESLint** uses **`eslint-config-standard`** and **`@babel/eslint-parser`**; match existing **semicolon-free** standard style and two-space indentation seen in `lib/`. +- **Environment**: ESLint `es2020`; tests may relax rules via `overrides` in `.eslintrc.js` for `test/**/*.js`. + +## Patterns + +- Prefer **named exports** from feature modules where the codebase already does; default exports are used for factory-style modules (e.g. `contentstackClient`, HTTP client factory). +- Use **JSDoc** (`@memberof`, `@func`, `@param`, `@returns`, `@example`) on **public** package API consistent with `lib/contentstack.js` and `lib/contentstackClient.js`. +- **Dependencies**: `lodash` (e.g. `cloneDeep`), `axios`, `qs`, `@contentstack/utils` — follow existing import paths (`.js` suffixes in imports where used). + +## Logging + +- Do not add noisy `console.log` in library code except where aligned with existing `logHandler` / error reporting in `lib/core/contentstackHTTPClient.js`. +- Never log full **authtoken**, **management tokens**, or raw **passwords**. diff --git a/.cursor/rules/testing.mdc b/.cursor/rules/testing.mdc new file mode 100644 index 00000000..5db1caea --- /dev/null +++ b/.cursor/rules/testing.mdc @@ -0,0 +1,43 @@ +--- +description: "Mocha, Jest, and sanity-check tests for this SDK" +globs: + - "test/unit/**/*.js" + - "test/sanity-check/**/*.js" + - "test/typescript/**/*.ts" + - "test/**/index.js" +alwaysApply: false +--- + +# Testing — `@contentstack/management` + +## Frameworks + +| Suite | Runner | Assertion / mocks | Notes | +|-------|--------|-------------------|--------| +| **Unit** | **Mocha** + `@babel/register` | **Chai**, **Sinon**, **Nock**, **axios-mock-adapter** | Entry: `test/unit/index.js`; **30s** timeout in npm script | +| **Sanity / API** | Mocha | Chai; **live HTTP** | Entry: `test/sanity-check/sanity.js`; imports **`dist/node/contentstack-management.js`** — run **`npm run build`** first | +| **TypeScript** | **Jest** + **ts-jest** | Jest mocks | `jest.config.js`; `npm run test:typescript` | + +## Naming & layout + +- **Unit**: `test/unit/*-test.js` (required from `test/unit/index.js`). +- **Sanity**: `test/sanity-check/api/*-test.js` (orchestrated via `sanity.js`); shared setup in `test/sanity-check/utility/testSetup.js` and helpers. +- **TS**: `test/typescript/**/*.test.ts` per Jest config. + +## Credentials & env (sanity only) + +- Canonical env documentation: **`test/sanity-check/utility/testSetup.js`** (see also `sanity.js`). +- **Required for setup:** `EMAIL`, `PASSWORD`, `HOST`, `ORGANIZATION`. +- **Suite-specific (tests skip when unset):** OAuth — `CLIENT_ID`, `APP_ID`, `REDIRECT_URI`; 2FA — `TFA_EMAIL`, `TFA_PASSWORD`; MFA — `MFA_SECRET`; team/stack share — `MEMBER_EMAIL`; DAM 2.0 — `DAM_2_0_ENABLED=true`. +- **Optional / defaults:** `PERSONALIZE_HOST`, `DELETE_DYNAMIC_RESOURCES`. Use `HOST` for the target CMA API host / region. +- Setup **writes** `API_KEY`, `AUTHTOKEN`, `MANAGEMENT_TOKEN`, `PERSONALIZE_PROJECT_UID` at runtime — never commit those. +- Unit tests must **not** rely on real API keys; mock HTTP. + +## Coverage + +- **nyc** is used with `npm run test:unit` / `test:sanity-test`; exclusions are configured under `package.json` → `nyc`. + +## Hygiene + +- No committed **`only`** / **`skip`** for tests that should run in CI. +- Prefer existing **`test/unit/mock/`** and sanity **`mock/`** patterns for fixtures. diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..26494d77 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,59 @@ +# AGENTS.md — AI / automation context + +## Project + +| | | +|---|---| +| **Name** | `@contentstack/management` (npm) — **Contentstack Management JavaScript SDK** | +| **Purpose** | Client for the **Content Management API (CMA)**: create, update, delete, and fetch content and stack configuration in a Contentstack account. *(This is not the Content Delivery API / read-only delivery client.)* | +| **Repository** | [contentstack/contentstack-management-javascript](https://github.com/contentstack/contentstack-management-javascript.git) | + +## Tech stack + +| Area | Details | +|------|---------| +| **Language** | JavaScript (ES modules in `lib/`); TypeScript declarations under `types/`; small Jest suite under `test/typescript/` | +| **Runtime** | Node `>=8` per `package.json` `engines`; README suggests Node 10+ for typical development | +| **Build** | Babel (`lib/` → `dist/es5`, `dist/es-modules`); Webpack bundles for `node`, `web`, `react-native`, `nativescript` | +| **Lint / style** | ESLint with `standard` config (`eslint-config-standard`), `@babel/eslint-parser`, `es2020` env | +| **Unit / API tests** | Mocha + Chai + `@babel/register` + `nyc`; Sinon / Nock / `axios-mock-adapter` where used | +| **TypeScript tests** | Jest + `ts-jest` (`jest.config.js`, `npm run test:typescript`) | +| **HTTP / JSON** | **Axios** (`axios`); query serialization via **qs**; helpers from **`@contentstack/utils`** (e.g. `getContentstackEndpoint`) | + +## Source layout & public entrypoints + +| Path | Role | +|------|------| +| `lib/contentstack.js` | Package entry: `contentstack.client()`, re-exports | +| `lib/contentstackClient.js` | High-level client: `login`, `stack`, `organization`, etc. | +| `lib/core/contentstackHTTPClient.js` | Axios instance, retries, concurrency, interceptors | +| `lib/core/contentstackError.js` | Maps failed HTTP responses to thrown errors | +| `lib/stack/**`, `lib/organization/**`, `lib/user/**`, `lib/query/**` | Resource modules | +| `types/**` | Public `.d.ts` (and some `.ts`) for consumers | +| `dist/**` | Built artifacts (`package.json` `main` / `browser`) | + +## Common commands + +```bash +npm install +npm run build # clean + babel + webpack targets +npm run lint # eslint lib test +npm run test # package.json chains test:api + test:unit (verify test:api exists in scripts) +npm run test:unit # Mocha unit suite + nyc +npm run test:sanity-test # integration-style suite (needs env + network) +npm run test:sanity-nocov # same without nyc +npm run test:typescript # Jest for test/typescript +npm run generate:docs # JSDoc +``` + +**Unit vs integration** + +- **Unit**: `test/unit/index.js` wires Mocha files; mocked HTTP, no live CMA. +- **Sanity / API**: `test/sanity-check/sanity.js` runs against a real stack; imports **`dist/node/contentstack-management.js`** (built output). **Requires credentials and env** (see `test/sanity-check/utility/testSetup.js`: `EMAIL`, `PASSWORD`, `HOST`, `ORGANIZATION`, optional OAuth / Personalize vars). + +## Further guidance + +- **Cursor rules (globs, always-apply):** [`.cursor/rules/README.md`](.cursor/rules/README.md) +- **Deeper playbooks:** [`skills/README.md`](skills/README.md) + +When unsure about API behavior, prefer the official [Content Management API](https://www.contentstack.com/docs/developers/apis/content-management-api/) docs and existing JSDoc in `lib/`. diff --git a/skills/README.md b/skills/README.md new file mode 100644 index 00000000..5f8f2e65 --- /dev/null +++ b/skills/README.md @@ -0,0 +1,14 @@ +# Project skills + +Short playbooks for agents and maintainers. Prefer these when you need depth beyond `.cursor/rules/*.mdc`. + +| Skill | When to use | +|-------|-------------| +| [`code-review/`](code-review/SKILL.md) | Structured PR review, release readiness, API/doc alignment | +| [`testing/`](testing/SKILL.md) | Mocha unit vs sanity runs, env vars, mocks, Jest TS tests | +| [`contentstack-javascript-cma/`](contentstack-javascript-cma/SKILL.md) | CMA client usage: `client`, `stack`, auth, regions, entities | +| [`framework/`](framework/SKILL.md) | Axios HTTP layer: retries, concurrency queue, interceptors, plugins, errors | + +**Repo overview:** see root [`AGENTS.md`](../AGENTS.md). **Rule index:** [`.cursor/rules/README.md`](../.cursor/rules/README.md). + +In Cursor, reference a skill in chat when supported (e.g. instructions that point at `@skills/testing` may map to these paths depending on your setup). diff --git a/skills/code-review/SKILL.md b/skills/code-review/SKILL.md new file mode 100644 index 00000000..6e9d259e --- /dev/null +++ b/skills/code-review/SKILL.md @@ -0,0 +1,62 @@ +--- +name: code-review +description: Use when reviewing PRs or before opening a PR — API design, null-safety, errors, backward compatibility, dependencies, security, and test quality. +--- + +# Code review — Contentstack Management JavaScript SDK + +Use this skill when performing or preparing a pull request review for **`@contentstack/management`** (CMA — Content Management API client, not the Java CDA SDK). + +## When to use + +- Reviewing someone else’s PR. +- Self-reviewing your own PR before submission. +- Checking that changes meet project standards (API, errors, compatibility, tests, security). + +## Instructions + +Work through the checklist below. Optionally tag items with severity: **Blocker**, **Major**, **Minor**. + +### 1. API design and stability + +- [ ] **Public API:** New or changed public exports are necessary and documented with **JSDoc** (purpose, `@param` / `@returns`, `@example` where helpful), consistent with `lib/contentstack.js` and `lib/contentstackClient.js`. +- [ ] **TypeScript surface:** **`types/**`** updated when consumers would see new or changed signatures or exports. +- [ ] **Backward compatibility:** No breaking changes to public function signatures, option objects, defaults, or export shape unless explicitly agreed (e.g. major version). Deprecations should note alternatives when used in this codebase. +- [ ] **Naming:** Consistent with existing modules and **CMA** terminology (e.g. stack, entry, content type, asset, taxonomy) and paths under `lib/stack/`. + +**Severity:** Breaking public API without approval = **Blocker**. Missing JSDoc or types on new public API = **Major**. + +### 2. Error handling and robustness + +- [ ] **Errors:** HTTP failures flow through **`lib/core/contentstackError.js`** (or the same promise-rejection pattern used by neighboring code), preserving **status** and safe **request** metadata. +- [ ] **Null safety:** No unsafe assumptions on optional fields; guard or default where API responses can omit nested objects. +- [ ] **Secrets:** Do not log or stringify full **authtoken**, **authorization**, or **management_token**; follow redaction patterns in **`contentstackError.js`**. + +**Severity:** Wrong or missing error handling on new/changed paths = **Major**. + +### 3. Dependencies and security + +- [ ] **Dependencies:** New or upgraded npm dependencies are justified; prefer existing **`lodash` / `axios`** patterns where possible. **Lockfile** / **`package.json`** bumps are intentional and reviewable. +- [ ] **SCA:** Security findings (e.g. Snyk, Dependabot) in the change set are addressed or explicitly deferred with a tracked follow-up. + +**Severity:** New critical/high vulnerability or unfixed blocker finding in scope = **Blocker**. + +### 4. Testing + +- [ ] **Unit:** New or modified **`lib/`** behavior has tests under **`test/unit/`** with HTTP **mocked** (Nock, axios-mock-adapter, Sinon, etc.); register suites in **`test/unit/index.js`** when adding files. +- [ ] **Sanity / API:** When behavior is integration-sensitive, update or add **`test/sanity-check/api/*-test.js`** and ensure **`test/sanity-check/sanity.js`** includes it; run against **`dist/node/contentstack-management.js`** after **`npm run build`**. Document new env vars in **`test/sanity-check/utility/testSetup.js`** header only — no committed secrets. +- [ ] **Quality:** Tests are readable, deterministic (no flaky timing or live-network dependence in unit tests), and assert meaningful behavior. + +**Severity:** No tests for new behavior = **Blocker**. Flaky or weak tests = **Major**. + +### 5. Optional severity summary + +- **Blocker:** Must fix before merge (e.g. breaking API without approval, security issue, no tests for new code). +- **Major:** Should fix (e.g. inconsistent error handling, missing JSDoc on new public API, flaky tests). +- **Minor:** Nice to fix (e.g. style, minor docs, redundant code). + +## References + +- Project rule: `.cursor/rules/code-review.mdc` +- Workflow (lint, tests, version bump): `.cursor/rules/dev-workflow.md` +- Testing detail: `skills/testing/SKILL.md` diff --git a/skills/contentstack-javascript-cma/SKILL.md b/skills/contentstack-javascript-cma/SKILL.md new file mode 100644 index 00000000..2aed90ad --- /dev/null +++ b/skills/contentstack-javascript-cma/SKILL.md @@ -0,0 +1,37 @@ +--- +name: contentstack-js-cma +description: Contentstack Management (CMA) JavaScript SDK — client, stack, auth, regions, entities in lib/. +--- + +# Contentstack JavaScript CMA SDK skill + +This repository ships **`@contentstack/management`**, the **Content Management API** client. It is **not** the Content Delivery API (CDA) read client. + +## Mental model + +1. **`contentstack.client(options)`** (`lib/contentstack.js`) builds the axios-based HTTP stack and returns a **client** facade. +2. **`contentstackClient`** (`lib/contentstackClient.js`) adds **login**, **logout**, **stack**, **organization**, etc. +3. **Stack-scoped** modules live under **`lib/stack/`** (content types, entries, assets, branches, …). +4. Shared HTTP behavior: **`lib/core/contentstackHTTPClient.js`**; errors: **`lib/core/contentstackError.js`**. + +## Configuration knobs (see JSDoc on `client()`) + +- **region**, **host**, **endpoint** — CMA base URL resolution; **host** overrides region when both set (per README / JSDoc). +- **timeout**, **retryOnError**, **retryLimit**, **retryDelay**, **maxRequests** — network behavior. +- **authtoken** / **authorization** — user-scoped auth; **management_token** + **api_key** on **stack()** for stack operations. +- **early_access** — forwarded as `x-header-ea` for EA features. +- **plugins** — axios interceptors normalized in HTTP client (see `normalizePlugins` usage). + +## Implementing new resources + +- Follow neighbors in **`lib/stack//`**: accept **`http`**, carry **`urlPath`** / **`uid`**, clone **`stackHeaders`**, use **`entity`** / **`ContentstackCollection`** patterns where appropriate. +- Pass the shared **`error`** handler from **`contentstackError`** on HTTP promise chains for consistent failures. + +## Docs + +- Product: [Content Management API](https://www.contentstack.com/docs/developers/apis/content-management-api/) +- Types: **`types/contentstackClient.d.ts`** and nested `types/stack/**` + +## Rule shortcut + +- Cursor: `.cursor/rules/contentstack-javascript-cma.mdc` when editing `lib/**/*.js` diff --git a/skills/framework/SKILL.md b/skills/framework/SKILL.md new file mode 100644 index 00000000..86e3552e --- /dev/null +++ b/skills/framework/SKILL.md @@ -0,0 +1,34 @@ +--- +name: framework +description: Axios HTTP layer for the SDK — contentstackHTTPClient, retries, concurrency, plugins, oauth utilities. +--- + +# Framework skill — HTTP / config / transport + +The SDK isolates HTTP and cross-cutting behavior under **`lib/core/`**. Read these when changing requests, retries, auth headers, or queueing — not when only adjusting a single stack resource’s URL path. + +## Key modules + +| File | Responsibility | +|------|----------------| +| **`contentstackHTTPClient.js`** | Builds **axios** instance: **baseURL** from host/port/version/`endpoint`, **paramsSerializer** (qs + JSON `query`), **interceptors** (path versioning, plugins), **retry** adapter pattern, **ConcurrencyQueue**, default **logHandler**, **retryCondition** (e.g. 429) | +| **`concurrency-queue.js`** | Limits parallel in-flight requests (`maxRequests`) | +| **`contentstackError.js`** | Maps axios errors to enriched `Error` objects (redacts token fields in logged config) | +| **`errorMessages.js`** | User-facing error string helpers | +| **`oauthHandler.js`** | OAuth-related client behavior used by `contentstackClient` | +| **`pkceStorage.js`** | PKCE storage helper for OAuth flows | +| **`Util.js`** | Host checks, user agent, plugin normalization, shared helpers | + +## When to change this layer + +- **New global header**, **auth scheme**, or **base URL** rule → HTTP client / client bootstrap (`contentstack.js`). +- **Retry policy**, **429** handling, **timeout** defaults → `contentstackHTTPClient.js` (and JSDoc on `client()` options). +- **Concurrency** behavior → `concurrency-queue.js` + options plumbed from `client()`. + +## Tests + +- **`test/unit/ContentstackHTTPClient-test.js`**, **`concurrency-Queue-test.js`**, **`contentstackError-test.js`**, **`Util-test`** exercise this stack — update or extend when behavior changes. + +## Rule shortcut + +- Cursor: `.cursor/rules/javascript.mdc` for style; **CMA usage** rules in `.cursor/rules/contentstack-javascript-cma.mdc` diff --git a/skills/testing/SKILL.md b/skills/testing/SKILL.md new file mode 100644 index 00000000..b44f7b8b --- /dev/null +++ b/skills/testing/SKILL.md @@ -0,0 +1,70 @@ +--- +name: testing +description: How to run and extend tests — Mocha unit, sanity API, Jest TypeScript; env and mocks. +--- + +# Testing skill — `@contentstack/management` + +## Commands (from `package.json`) + +| Goal | Command | +|------|---------| +| Lint (pre-test hook) | `npm run lint` | +| Default `npm test` | Runs `test:api` then `test:unit` per `package.json` — **confirm `test:api` is defined** in your branch (it may be missing); otherwise use `test:unit` directly | +| Unit only | `npm run test:unit` — Mocha `test/unit/index.js`, **nyc** coverage | +| Unit JSON report | `npm run test:unit:report:json` | +| Sanity + coverage | `npm run test:sanity-test` | +| Sanity, no nyc | `npm run test:sanity-nocov` | +| TypeScript / Jest | `npm run test:typescript` | + +Always **`npm run build`** before sanity if `dist/node/contentstack-management.js` must match `lib/` (sanity imports built output). + +## Unit tests (`test/unit/`) + +- **Mocha** + **Chai** + **@babel/register**; **30s** timeout per script. +- **HTTP**: mock with **Nock**, **axios-mock-adapter**, or stubs — **no live CMA**. +- Suites are **`require`d** from `test/unit/index.js` — add new `*-test.js` files and register them there. + +## Sanity tests (`test/sanity-check/`) + +- **Live** Contentstack CMA calls; orchestrated by `test/sanity-check/sanity.js`. +- **Authoritative list:** variable names and defaults are documented in **`test/sanity-check/utility/testSetup.js`** (and mirrored in `sanity.js`); prefer that file when adding new env vars. + +### Environment variables + +**Required (core)** — setup fails or cannot run without these: + +- `EMAIL`, `PASSWORD`, `HOST`, `ORGANIZATION` + +Without them, login / stack creation / org-scoped setup does not complete. + +**Required for specific suites** — related tests **skip** (or degrade) when missing: + +| Area | Variables | Notes | +|------|-----------|--------| +| **OAuth** | `CLIENT_ID`, `APP_ID`, `REDIRECT_URI` | Used by `oauth-test.js` and auth flows that need app registration | +| **2FA (TFA)** | `TFA_EMAIL`, `TFA_PASSWORD` | `user-test.js` — skip TFA scenarios when unset | +| **MFA (TOTP)** | `MFA_SECRET` | `user-test.js` — MFA login path; optional asserts still run without it in some cases | +| **Team / stack share** | `MEMBER_EMAIL` | `team-test.js`, `stack-test.js` — avoids mutating the admin user; share tests skip if unset | +| **DAM 2.0** | `DAM_2_0_ENABLED=true` | `entry-test.js` — asset/DAM 2.0 block gated on this flag | + +**Optional / config** (defaults exist; override when needed): + +- `PERSONALIZE_HOST` — defaults to `personalize-api.contentstack.com` in setup +- `DELETE_DYNAMIC_RESOURCES` — defaults to deleting dynamic stack/Personalize resources; set to `false` to keep them for debugging + +**Regions / hosts:** point `HOST` at the **API host** for the stack you are testing (e.g. regional or custom CMA host), consistent with `testSetup.js`. + +**Runtime (not for .env check-in):** after setup, `testSetup` assigns `process.env.API_KEY`, `AUTHTOKEN`, `MANAGEMENT_TOKEN`, `PERSONALIZE_PROJECT_UID`, etc. Do not commit those; they are produced by the harness. + +- **Flow**: setup creates stack, management token, and Personalize project where applicable; teardown reads `DELETE_DYNAMIC_RESOURCES`. Read **`testSetup.js`** before adding destructive or org-wide tests. + +## Jest (`test/typescript/`) + +- **`jest.config.js`**: `ts-jest`, coverage to `coverage/`. +- Use for TypeScript-first checks; keep in sync with public types if asserting SDK shape. + +## Hygiene + +- No committed **`only`** / **`skip`** on tests meant for CI. +- Never commit **real tokens** in tests or snapshots.