Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .cursor/rules/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Cursor rules — @contentstack/marketplace-sdk

Rules live in this directory. Each file states its scope in YAML frontmatter (`description`, and either `globs` and/or `alwaysApply`).

| Rule file | `alwaysApply` | Globs | When it applies |
|-----------|---------------|-------|-----------------|
| [dev-workflow.mdc](dev-workflow.mdc) | no | `**/*` | Branching, local commands, CI expectations, releases |
| [javascript.mdc](javascript.mdc) | no | `lib/**`, `test/**`, `types/**`, config roots | ESLint Standard, ES modules, project layout |
| [contentstack-javascript-marketplace.mdc](contentstack-javascript-marketplace.mdc) | no | `lib/**` only | Developer Hub host/region, auth, HTTP client behavior, marketplace modules |
| [testing.mdc](testing.mdc) | no | `test/**` | Mocha vs Jest, sanity env, naming |
| [code-review.mdc](code-review.mdc) | **yes** | — | Every session — PR / change checklist |

## Referencing rules in chat

In Cursor, mention a rule by **filename** or **@ mention** when the picker lists project rules, for example:

- `@dev-workflow` or `.cursor/rules/dev-workflow.mdc`
- `@javascript` / `@contentstack-javascript-marketplace` / `@testing` / `@code-review`

See also the repository [AGENTS.md](../../AGENTS.md) (repo root) and [skills/README.md](../../skills/README.md).
50 changes: 50 additions & 0 deletions .cursor/rules/code-review.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
description: PR checklist — API docs, compat, errors, tests, Marketplace vs CDA/CMA terminology
alwaysApply: true
---

# Code review checklist

Use this for any change touching the SDK. Severity labels are optional guidance for reviewers.

## API and documentation

- **Public surface:** New or changed `client()`, `marketplace()`, or chain methods need **JSDoc** consistent with surrounding symbols (params, return `Promise`, examples where helpful).
- **Types:** Update `types/**/*.d.ts` when exports or shapes change.

## Product terminology

- This repo is **Marketplace / Developer Hub** — **not CDA** (Delivery) and not general **stack CMA content** unless the change explicitly introduces that scope. PR text and user-facing strings must not mislabel the product.

## Backward compatibility

- Avoid breaking `client()` options, method signatures, or default behavior without semver intent and migration notes.
- Preserve existing header names and axios defaults unless versioned or documented.

## Errors

- HTTP failures should continue to map through **`contentstackError`** patterns (status, message body fields, header redaction)—no raw axios leaks to callers unless intentional and documented.

## Safety and robustness

- Guard null/undefined for optional nested params consistent with existing modules.
- No sensitive logging of full tokens (follow redaction patterns in `contentstackError`).

## Dependencies and security

- New dependencies need justification; run/license alignment with MIT stack.
- Be mindful of supply-chain risk for install scripts and pinned ranges.

## Tests

- **Unit:** Extend `test/unit/` for logic in `lib/`.
- **Sanity:** Only when live API checks are required—document env vars; do not commit credentials.
- TypeScript samples: update `test/typescript/` when public types warrant it.

## Severity (optional)

| Level | Examples |
|-------|----------|
| **Blocker** | Broken default auth, security regression of tokens, published API removed without major bump |
| **Major** | Missing tests for new behavior, incorrect error mapping, wrong docs that mislead CDA vs Marketplace |
| **Minor** | JSDoc nits, internal naming, non-user-facing refactor |
31 changes: 31 additions & 0 deletions .cursor/rules/contentstack-javascript-marketplace.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
description: Marketplace / Developer Hub SDK — auth, host, HTTP behavior in lib/
globs: lib/**
alwaysApply: false
---

# Contentstack Marketplace SDK (`lib/`)

This package is a **Marketplace (Developer Hub) management** client, not **CDA** and not generic **stack CMA content** APIs. Terminology and docs should say **Marketplace**, Developer Hub, apps, installations, hosting, OAuth as appropriate—avoid implying Delivery or stack entry CRUD unless adding a new surface that truly uses those APIs.

## Client bootstrap

- **`lib/contentstack.js` — `client(params)`:** Builds axios-based HTTP client via `contentstackHTTPClient`, merges `authtoken` / `authorization` into headers, sets `X-User-Agent` / `User-Agent` (includes `contentstack-marketplace-sdk/<version>`). Default hostname comes from `@contentstack/utils` `getContentstackEndpoint(region, 'developerHub', true)`.
- **`Region`:** `lib/core/region.js` — `eu`, `na` (empty string), `azure-na`, `azure-eu`, `gcp-na`. Pass via `params.region` (lowercased internally).

## Auth patterns (actual usage)

- Headers: `authtoken` and/or `authorization` (e.g. OAuth bearer) on the axios instance.
- **`contentstackClient.login`:** POST to `/v3/user-session` (host varies by `region` / `host`); stores returned `authtoken` on `http.defaults.headers.common`.
- **`refreshToken`:** Optional callback in `client()` params (see JSDoc in `contentstack.js`) for token rotation.
- **Marketplace calls:** `client.marketplace(orgUid)` → `lib/marketplace/**` (apps, installation, hosting, webhooks, OAuth helpers, authorization, app requests).

## HTTP layer

- **`lib/core/contentstackHTTPClient.js`:** Axios instance, default `timeout` 30000, `retryOnError` true, default `retryCondition` retries on **HTTP 429**. Uses `Qs` for `paramsSerializer` (including encoded `query` JSON). `versioningStrategy: 'path'`.
- **Concurrency:** `lib/core/concurrency-queue.js` caps parallel requests (`maxRequests`).
- **Errors:** Responses go through `lib/core/contentstackError.js` — enriches thrown `Error` with `status`, `errorMessage`, `errorCode`, `errors`, sanitized headers.

## Official docs alignment

Relate behavior to **Developer Hub / Marketplace** and **user session** documentation on [contentstack.com/docs](https://www.contentstack.com/docs), not to **CDA** delivery references unless the code explicitly integrates delivery tokens for a marketplace feature.
33 changes: 33 additions & 0 deletions .cursor/rules/dev-workflow.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
description: Branches, lint/tests, PR and release expectations for marketplace-sdk
globs: "**/*"
alwaysApply: false
---

# Dev workflow

## Branching

Follow team/GitHub conventions (feature branches, PRs to default branch). Use ticket IDs in branch names when required by the team (e.g. `feat/DX-5383-...`).

## Local quality gate

1. `npm run lint` — ESLint on `lib/` and `test/`.
2. `npm run test:unit` — Mocha + NYC (triggers `pretest`: cleans coverage and runs lint).
3. Optional: `npm run test:typescript` for Jest TS samples.

CI runs `npm ci` and `npm run test:unit:report:json` (see `.github/workflows/unit-test.yml`).

## PR expectations

- Unit tests updated or added for behavioral changes in `lib/`.
- No committed secrets; sanity fixtures stay out of version control if they contain tokens.
- Match existing Standard JS style and JSDoc depth on public APIs.

## Releases

Version lives in `package.json`. `prepare` runs `npm run build` on install/publish—ensure the `dist/` build succeeds before tagging. Coordinate npm release process with maintainers (changelog, semver).

## Known script gap

Root `npm test` references a non-existent `test:api` script; use `npm run test:unit` until `test:api` is defined.
27 changes: 27 additions & 0 deletions .cursor/rules/javascript.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
description: JavaScript source layout, ESLint Standard, logging for marketplace-sdk
globs: "**/*.{js,ts}"
alwaysApply: false
---

# JavaScript (lib / test / types)

## Language and layout

- **Source:** `lib/` — ES modules (`import`/`export`). Built outputs in `dist/` (Webpack + Babel); do not hand-edit `dist/`.
- **Tests:** Mocha + Chai in `test/unit/` and `test/sanity-check/`; Jest + TypeScript samples in `test/typescript/`.
- **Types:** Hand-maintained declarations under `types/` (e.g. `types/contentstackClient.d.ts`, `types/marketplace/**`).

## Style

- **ESLint:** `extends: 'standard'` (`.eslintrc.js`), `ecmaVersion: 2020`, `sourceType: 'module'`.
- Prefer explicit, readable names; avoid drive-by reformatting unrelated code.

## Logging

- HTTP logging hooks: `lib/core/messageHandler.js` (`httpLogHandler` referenced from `contentstackHTTPClient`).
- When adding diagnostics, follow existing patterns—do not replace with ad-hoc `console` in core paths unless consistent with `logHandler` usage.

## Dependencies (declared)

Runtime: `axios`, `@contentstack/utils`. Keep `package.json` accurate when adding imports.
35 changes: 35 additions & 0 deletions .cursor/rules/testing.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
description: Mocha, Jest, sanity tests, env vars for marketplace-sdk
globs: test/**
alwaysApply: false
---

# Testing

## Unit tests (Mocha + NYC)

- **Entry:** `test/unit/index.js` requires individual `*-test.js` files.
- **Command:** `npm run test:unit` (30s timeout, `BABEL_ENV=test`, `@babel/register`, `babel-polyfill`).
- **Coverage:** NYC HTML + text; clover for `test:unit:report:json` (CI).
- **Mocks:** `test/unit/mock/**`, `axios-mock-adapter`, `nock`, `sinon` as used in existing tests.

## TypeScript / Jest

- **Config:** `jest.config.js` — `ts-jest`, coverage to `coverage/`, tests under `test/typescript/` (`*.test.ts`, etc.).
- **Command:** `npm run test:typescript`.

## Sanity / integration-style (live API)

- **Entry:** `test/sanity-check/sanity.js` requires API suites under `test/sanity-check/api/`.
- **Command:** `npm run test:sanity-test` (or `test:sanity` which swallows failures—avoid for strict gates).
- **Env:** `dotenv` loads `.env`. Examples from existing specs: `ORG_UID`, `HOST`, `DEFAULTHOST`, `ADMIN_EMAIL`, `USER_EMAIL`, `EMAIL`, `PASSWORD`. Utility client: `test/sanity-check/utility/ContentstackClient.js` (`host`, `defaultHostName` from env).
- **Fixtures:** JSON read/write in `test/sanity-check/utility/fileOperations/readwrite.js` (e.g. `loggedinAdmin.json`) — treat as local secrets; never commit populated files.

## Naming

- Unit: `*-test.js` beside concepts (`marketplace-test.js`, `ContentstackHTTPClient-test.js`).
- Sanity: `*-test.js` or descriptive names under `test/sanity-check/api/`.

## Pretest

`npm run test:unit` runs `pretest` (`rimraf coverage` + `npm run lint`) unless invoked with `--ignore-scripts`—account for lint when debugging failing tests.
58 changes: 58 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Agent guide — @contentstack/marketplace-sdk

## What this package is

**Contentstack Marketplace SDK** — a **JavaScript client for Marketplace / Developer Hub** operations (apps, installations, hosting, OAuth, webhooks, authorization flows against the Developer Hub API). It is **not** the [Content Delivery API (CDA)](https://www.contentstack.com/docs/developers/apis/content-delivery-api/) SDK and **not** a general stack **Content Management API (CMA)** content SDK; it targets **marketplace app lifecycle and related management APIs** using the same style of auth as CMA (authtoken, `authorization` header, optional `login`).

- **Repository:** [github.com/contentstack/contentstack-marketplace-sdk](https://github.com/contentstack/contentstack-marketplace-sdk)
- **npm:** `@contentstack/marketplace-sdk`

## Tech stack

| Area | Choice |
|------|--------|
| Language | JavaScript (ES modules in `lib/`), transpiled with Babel; TypeScript only for `test/typescript/` and `types/` |
| Runtime | Node (README: 10+; CI uses Node 22.x) |
| HTTP / JSON | [axios](https://axios-http.com/), [qs](https://github.com/ljharb/qs) for query serialization |
| Config / regions | [@contentstack/utils](https://www.npmjs.com/package/@contentstack/utils) (`getContentstackEndpoint` for Developer Hub host) |
| Unit / API-style tests | Mocha, Chai, NYC; Babel register for `lib/` |
| Typecheck tests | Jest + ts-jest (`jest.config.js`) |
| Lint | ESLint + `eslint-config-standard` (`.eslintrc.js`) |
| Bundling | Webpack → `dist/node`, `dist/web`, etc. |

## Public entry points (source of truth)

| Role | Path |
|------|------|
| Factory | `lib/contentstack.js` — `client()`, exports `Region` |
| Request surface | `lib/contentstackClient.js` — `login`, `marketplace`, `logout` |
| HTTP stack | `lib/core/contentstackHTTPClient.js`, `lib/core/concurrency-queue.js`, `lib/core/messageHandler.js` |
| Errors | `lib/core/contentstackError.js` |
| Marketplace domain | `lib/marketplace/**` |
| Published `main` | `dist/node/contentstack-marketplace.js` (build output) |
| Type declarations | `types/contentstackClient.d.ts` and `types/marketplace/**` |

## Commands

```bash
npm install
npm run build # clean + Babel + webpack targets
npm run lint # eslint lib test
npm run format # eslint --fix lib test
npm run test:unit # Mocha unit suite + NYC (also runs lint via pretest)
npm run test:typescript # Jest on test/typescript
npm run test:sanity-test # Mocha live stack under test/sanity-check (long timeout)
```

**CI (`.github/workflows/unit-test.yml`):** `npm ci` then `npm run test:unit:report:json`.

> **`npm test` caveat:** `package.json` defines `"test": "npm run test:api && npm run test:unit"` but there is **no** `test:api` script. Use `npm run test:unit` (or fix the `test` script when adding `test:api`).

## Credentials and live tests

Sanity tests under `test/sanity-check/` use **dotenv** and env vars such as `HOST` / `DEFAULTHOST`, `ORG_UID`, `ADMIN_EMAIL`, `USER_EMAIL`, `EMAIL`, `PASSWORD`. They also read/write JSON fixtures (e.g. `loggedinAdmin.json`) via `test/sanity-check/utility/fileOperations/readwrite.js`. Do not commit real tokens; use `.env` locally (see `.gitignore`).

## Further reading for agents

- [Cursor rules index](.cursor/rules/README.md) — when each rule applies and how to reference it.
- [Skills index](skills/README.md) — deeper checklists and SDK mental model.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## [v1.5.1](https://github.com/contentstack/contentstack-marketplace-sdk/tree/v1.5.0) (2026-03-23)
- Fix snyk issues

## [v1.5.0](https://github.com/contentstack/contentstack-marketplace-sdk/tree/v1.5.0) (2026-02-02)
- Enhancement: Use `getContentstackEndpoint` from `@contentstack/utils` to set marketplace host based on region
- Removed local `regions.json` and `getRegionEndpoint`; region endpoints are now resolved via `@contentstack/utils`
Expand Down
12 changes: 12 additions & 0 deletions skills/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Skills — @contentstack/marketplace-sdk

Project-local skills for AI agents. Each folder contains a `SKILL.md` with YAML frontmatter (`name`, `description`).

| Skill | When to use |
|-------|-------------|
| [code-review](code-review/SKILL.md) | PRs, pre-merge review, risk triage |
| [testing](testing/SKILL.md) | Running/fixing tests, env for sanity runs, mocks |
| [contentstack-javascript-marketplace](contentstack-javascript-marketplace/SKILL.md) | Where to change client/marketplace behavior; auth and host model |
| [framework](framework/SKILL.md) | Axios HTTP client, retries, concurrency queue, serializers |

Cursor rules index: [`.cursor/rules/README.md`](../.cursor/rules/README.md). Repo overview: [`AGENTS.md`](../AGENTS.md).
52 changes: 52 additions & 0 deletions skills/code-review/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
name: code-review
description: Expanded PR checklist for marketplace-sdk — docs, compat, errors, terminology, tests, dependency/security notes
---

# Code review (marketplace-sdk)

Use with `.cursor/rules/code-review.mdc` (always-on summary). This skill adds detail and examples.

## 1. Public API and JSDoc

- Every new exported function or fluent chain method should document parameters, return type (Promise + payload shape if stable), and Edge cases (region, required `orgUid`, token type).
- Cross-check `types/` — `.d.ts` must match runtime exports from `lib/contentstack.js` and `lib/marketplace/**`.

## 2. Terminology

- **Marketplace / Developer Hub** — correct framing for this package.
- **Not CDA** — do not describe this SDK as the Content Delivery API client.
- **CMA** — only where accurate (user-session / management-style tokens); avoid saying this SDK “is the CMA SDK” if the change is marketplace-only.

## 3. Backward compatibility

- Default host derivation (`getContentstackEndpoint`, `region`) must remain stable for existing consumers.
- Changing retry defaults, timeout, or header names is a **semver** decision.

## 4. Error mapping

- Reject patterns that bypass `contentstackError` for normal HTTP failures unless there is a dedicated low-level escape hatch.
- Ensure token redaction in thrown error details stays intact when touching `contentstackError` or interceptors.

## 5. Null safety and input validation

- Match defensive style used in sibling modules; avoid throwing non-`Error` values from async paths.

## 6. Dependencies and SCA

- New packages: license compatible with MIT, minimal footprint, no unnecessary postinstall scripts.
- Run `npm audit` / org policy as required before merge.

## 7. Tests

| Change type | Expectation |
|-------------|-------------|
| `lib/` behavior | `test/unit/` coverage or extension of existing suites |
| Type surface | `test/typescript/` if consumers rely on types |
| Live-only behavior | sanity suite + documented env; no secrets in repo |

## 8. Severity (optional)

- **Blocker:** Security, broken auth defaults, semver violation.
- **Major:** Missing tests, wrong product labeling in docs, incorrect error mapping.
- **Minor:** Comment/JSDoc only, internal refactor with identical behavior.
32 changes: 32 additions & 0 deletions skills/contentstack-javascript-marketplace/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
name: contentstack-javascript-marketplace
description: Mental model for the Marketplace SDK — client factory, org-scoped marketplace API, auth, regions, module map
---

# Contentstack JavaScript Marketplace SDK

## Mental model

1. **`contentstack.client(options)`** (`lib/contentstack.js`) creates an axios-based HTTP client pointed at the **Developer Hub** host (via `@contentstack/utils` + `region`), then wraps it with **`contentstackClient`** (`lib/contentstackClient.js`).
2. **Auth:** Pass `authtoken` and/or `authorization`, or call **`login`** to set `authtoken` on shared axios defaults. Optional **`refreshToken`** callback supports rotation.
3. **Marketplace entry:** **`client.marketplace(organization_uid)`** returns `lib/marketplace/index.js` — apps (`app()`, `findAllApps`, …), installations, hosting/deployments, webhooks, OAuth under `app/oauth`, authorization helpers, app requests.

## Where to change things

| Concern | Primary paths |
|---------|----------------|
| Client defaults, User-Agent, region → host | `lib/contentstack.js`, `lib/core/region.js` |
| Login / logout / marketplace root | `lib/contentstackClient.js` |
| Axios, retries (429), timeout, query encoding | `lib/core/contentstackHTTPClient.js` |
| Request queuing | `lib/core/concurrency-queue.js` |
| Error shape | `lib/core/contentstackError.js` |
| Marketplace resources | `lib/marketplace/**/*.js` |
| Public TypeScript types | `types/**/*.d.ts` |

## Docs alignment

Describe behavior against **Contentstack Marketplace / Developer Hub** APIs. Do not document this package as **CDA**. Mention **CMA-style tokens** only when describing authtoken / management-style auth accurately.

## Integration reminder

Downstream apps use **`@contentstack/marketplace-sdk`** with **`import contentstack from '@contentstack/marketplace-sdk'`** (see README). The built **`main`** field points to **`dist/node/...`** — edit **`lib/`** and run **`npm run build`** for distributable changes.
Loading
Loading