Skip to content

Commit 336cfd5

Browse files
Merge pull request #66 from contentstack/staging
DX | 06-04-2026 | Release
2 parents 5161006 + 9d3cc7f commit 336cfd5

File tree

22 files changed

+2492
-1095
lines changed

22 files changed

+2492
-1095
lines changed

.cursor/rules/README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Cursor rules
2+
3+
Rules give context-aware guidance for this **Contentstack query-export CLI plugin** (`@contentstack/cli-cm-export-query`).
4+
5+
## Rules overview
6+
7+
| File | Purpose |
8+
|------|---------|
9+
| `dev-workflow.md` | TDD, structure, validation commands (always applied) |
10+
| `typescript.mdc` | TypeScript style and naming |
11+
| `contentstack-cli.mdc` | Contentstack CLI utilities, export flow, API habits |
12+
| `testing.mdc` | Mocha/Chai/Sinon and coverage |
13+
| `oclif-commands.mdc` | Command flag and delegation patterns |
14+
15+
## How they attach
16+
17+
- **Always**: `dev-workflow.md`
18+
- **TypeScript**: `typescript.mdc`
19+
- **Commands** (`src/commands/**`): `oclif-commands.mdc` + `typescript.mdc`
20+
- **Core / utils** (`src/core/**`, `src/utils/**`, `src/types/**`): `contentstack-cli.mdc` + `typescript.mdc`
21+
- **Tests** (`test/**`): `testing.mdc` + domain rules as needed
22+
23+
## Chat shortcuts
24+
25+
You can `@`-mention rule topics (for example TypeScript or testing) depending on how your workspace maps rule names.

.cursor/rules/contentstack-cli.mdc

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
description: "Contentstack query-export plugin: CLI utilities, export flow, and API habits"
3+
globs:
4+
- "**/core/**/*.ts"
5+
- "**/utils/**/*.ts"
6+
- "**/types/**/*.ts"
7+
- "**/config/**/*.ts"
8+
alwaysApply: false
9+
---
10+
11+
# Contentstack CLI — query export plugin
12+
13+
This package is **`@contentstack/cli-cm-export-query`**. Business logic lives in **`src/core/`** and **`src/utils/`** (there is no `src/services/` layer).
14+
15+
## Stack and auth
16+
17+
- Use **`@contentstack/cli-utilities`**: `managementSDKClient`, `flags`, `log`, `handleAndLogError`, `sanitizePath`, etc.
18+
- Resolve management tokens and stack context the same way as **`src/commands/cm/stacks/export-query.ts`** (alias, `--stack-api-key`, config file).
19+
- **Never** log or write secrets (API keys, management tokens) to export artifacts or casual log lines.
20+
21+
## Export orchestration
22+
23+
- **`QueryExporter`** (`src/core/query-executor.ts`) drives the flow: parse query → export modules → resolve dependencies / references / assets per flags.
24+
- **`ModuleExporter`** (`src/core/module-exporter.ts`) handles module-level export alongside **`@contentstack/cli-cm-export`** behavior.
25+
- Prefer extending **utils** and **core** classes rather than putting heavy logic in the command’s `run()`.
26+
27+
## Queries
28+
29+
- Queries are JSON (string or path to a JSON file); see **`QueryParser`** (`src/utils/query-parser.ts`) and command examples in `export-query.ts`.
30+
- Respect flags: **`skip-references`**, **`skip-dependencies`**, **`secured-assets`**, branch / branch-alias.
31+
32+
## API usage
33+
34+
- Respect Contentstack **rate limits**; use backoff for **429** and transient failures when adding new API calls.
35+
- Mock **all** HTTP/SDK usage in tests (sinon); no live stack calls in unit tests.
36+
37+
## Not in this plugin
38+
39+
- Other CLI repos may use **`BaseBulkCommand`** or **`bulk-operation/*.json`** logs. This plugin uses **`Command`** from **`@contentstack/cli-command`** and the **`QueryExporter`** pipeline only.

.cursor/rules/dev-workflow.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
---
2+
description: "Core development workflow and TDD patterns - always applied"
3+
globs: ["**/*.ts", "**/*.js", "**/*.json"]
4+
alwaysApply: true
5+
---
6+
7+
# Development Workflow
8+
9+
## Quick Reference
10+
11+
For detailed patterns, see project skills:
12+
13+
- `@skills/testing` — Testing and TDD
14+
- `@skills/contentstack-cli` — Export command, utilities, and API usage
15+
- `@skills/framework` — Config, logging, and shared patterns
16+
- `@skills/code-review` — PR review checklist
17+
18+
## TDD workflow (recommended)
19+
20+
For **new behavior or bug fixes**, prefer working in three steps:
21+
22+
1. **RED** → Write a failing test (or extend an existing one)
23+
2. **GREEN** → Minimal code to pass
24+
3. **REFACTOR** → Clean up while tests stay green
25+
26+
**Exceptions (no new test required when behavior is unchanged):** pure refactors, documentation-only edits, comments/config-only tweaks, trivial typos.
27+
28+
## Guidelines
29+
30+
- **Coverage:** aim high; **~80%** (lines/branches/functions) is an **aspirational target**, not a CI gate in this repo
31+
- **TypeScript** — explicit return types where practical; avoid `any`
32+
- **NO test.skip or .only** in commits
33+
34+
## File structure (this repo)
35+
36+
- **Command**: `src/commands/cm/stacks/export-query.ts`
37+
- **Core**: `src/core/``QueryExporter`, `ModuleExporter`
38+
- **Utils**: `src/utils/` — query parsing, config, dependencies, assets, branches, file helpers
39+
- **Types**: `src/types/index.ts`
40+
- **Config**: `src/config/` (copied to `lib/` on build)
41+
- **Messages**: `messages/index.json`
42+
- **Tests**: `test/unit/*.test.ts` (grouped by module under test)
43+
44+
## Naming conventions
45+
46+
- Files: `kebab-case.ts` / `kebab-case.test.ts`
47+
- Classes: `PascalCase`
48+
- Functions: `camelCase`
49+
- Tests: `should [behavior] when [condition]`
50+
51+
## Before coding
52+
53+
1. Read relevant `@skills/*` references
54+
2. For behavior changes: prefer a failing test first, then implement
55+
3. Refactor and run tests
56+
57+
## Validation commands
58+
59+
- `npm run lint` — ESLint on `src/**/*.ts`
60+
- `npm run test` — All tests with nyc
61+
- `npm run test:report` — LCOV coverage report
62+
- `npm run test:unit` — Unit tests only
63+
- `npm run format` — ESLint `--fix`
64+
65+
## Commit suggestions
66+
67+
- Conventional commits are helpful but optional: `feat(scope): description`
68+
- Tests passing before merge
69+
- No lint errors
70+
- No stray `console.log` / `debugger`

.cursor/rules/oclif-commands.mdc

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
---
2+
description: "OCLIF / Contentstack command patterns for this plugin"
3+
globs: ["**/commands/**/*.ts"]
4+
alwaysApply: false
5+
---
6+
7+
# Command standards (`export-query`)
8+
9+
This plugin uses **`Command`** from **`@contentstack/cli-command`** and **`flags` / `FlagInput`** from **`@contentstack/cli-utilities`** (not `@oclif/core` `Flags` directly). Follow **`src/commands/cm/stacks/export-query.ts`** as the source of truth.
10+
11+
## Structure
12+
13+
```typescript
14+
import { Command } from '@contentstack/cli-command';
15+
import { flags, FlagInput, managementSDKClient, log, handleAndLogError } from '@contentstack/cli-utilities';
16+
import { QueryExporter } from '../../../core/query-executor';
17+
18+
export default class ExportQueryCommand extends Command {
19+
static description = 'Export content from a stack using query-based filtering';
20+
static examples = ['csdx cm:stacks:export-query --query \'{"modules":{...}}\''];
21+
22+
static flags: FlagInput = {
23+
query: flags.string({ required: true, description: 'Query as JSON string or file path' }),
24+
};
25+
26+
async run(): Promise<void> {
27+
const { flags } = await this.parse(ExportQueryCommand);
28+
// Build config via src/utils (e.g. setupQueryExportConfig), then:
29+
const exporter = new QueryExporter(client, exportQueryConfig);
30+
await exporter.execute();
31+
}
32+
}
33+
```
34+
35+
## Practices
36+
37+
- **Validate early**: required `query`; ensure stack auth is present before calling the API.
38+
- **Delegate**: keep parsing, paths, and SDK wiring out of `QueryExporter` where helpers already exist under **`src/utils/`**.
39+
- **User feedback**: prefer **`log`** from **`@contentstack/cli-utilities`** with export context.
40+
- **Errors**: use **`handleAndLogError`** and/or command error UX consistent with other Contentstack CLI plugins.
41+
42+
## Flags
43+
44+
- Define flags with **`flags.string`**, **`flags.boolean`**, etc., and **`FlagInput`** typing for the static `flags` object.
45+
- Use **`exclusive`** on mutually exclusive options (see branch vs branch-alias in `export-query.ts`).

.cursor/rules/testing.mdc

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
description: "Testing patterns and TDD workflow"
3+
globs: ["**/__tests__/**/*.ts", "**/*.spec.ts", "**/*.test.ts"]
4+
alwaysApply: true
5+
---
6+
7+
# Testing Standards
8+
9+
## TDD workflow
10+
1. For behavior changes, prefer a failing test first
11+
2. Minimal code to pass
12+
3. Refactor while keeping tests green
13+
14+
Pure refactors and docs-only changes may skip new tests when behavior is unchanged.
15+
16+
## Coverage
17+
- **~80%** (lines, branches, functions) is an **aspirational** goal, not enforced as a hard gate here
18+
- Test both success and failure paths
19+
- Mock all external dependencies
20+
21+
## Test Patterns
22+
```typescript
23+
// ✅ GOOD - Simple test structure
24+
describe('[ComponentName]', () => {
25+
beforeEach(() => {
26+
// Setup mocks and test data
27+
sinon.stub(ExternalService.prototype, 'method').resolves(mockData);
28+
});
29+
30+
afterEach(() => {
31+
sinon.restore();
32+
});
33+
34+
it('should [expected behavior] when [condition]', () => {
35+
// Arrange
36+
const input = { /* test data */ };
37+
38+
// Act
39+
const result = component.method(input);
40+
41+
// Assert
42+
expect(result).to.equal(expectedOutput);
43+
});
44+
});
45+
```
46+
47+
## Mocking Standards
48+
- Use sinon for API response mocking
49+
- Never make real API calls in tests
50+
- Mock at module boundaries (SDK clients, `fsUtil`, etc.), not irrelevant internals
51+
52+
## Layout
53+
54+
- Unit tests live under **`test/unit/**/*.test.ts`** (Mocha).
55+
56+
## Common mock patterns
57+
```typescript
58+
// Mock external API
59+
sinon.stub(HttpClient.prototype, 'request').resolves(mockResponse);
60+
61+
// Mock file operations
62+
sinon.stub(fs, 'readFile').resolves(mockFileContent);
63+
64+
// Mock rate limiter
65+
sinon.stub(RateLimiter.prototype, 'wait').resolves();
66+
```

.cursor/rules/typescript.mdc

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
description: "TypeScript strict mode standards and naming conventions"
3+
globs: ["**/*.ts", "**/*.tsx"]
4+
alwaysApply: false
5+
---
6+
7+
# TypeScript Standards
8+
9+
## Strict Mode Requirements
10+
- Explicit return types for all functions
11+
- No `any` type usage
12+
- Strict null checks enabled
13+
- No unused variables or imports
14+
15+
## Naming Conventions
16+
- **Files**: kebab-case.ts
17+
- **Classes**: PascalCase
18+
- **Functions/Variables**: camelCase
19+
- **Constants**: SCREAMING_SNAKE_CASE
20+
- **Interfaces**: PascalCase (no I prefix)
21+
- **Types**: PascalCase
22+
23+
## Code Examples
24+
```typescript
25+
// ✅ GOOD - Explicit types and proper naming
26+
export class UserService {
27+
async fetchUser(userId: string): Promise<User> {
28+
const user = await this.client.getUser(userId);
29+
return user;
30+
}
31+
}
32+
33+
// ❌ BAD - Implicit any, poor naming
34+
export class userservice {
35+
async fetchUser(id) {
36+
return await this.client.getUser(id);
37+
}
38+
}
39+
```
40+
41+
## Import Organization
42+
1. Node.js built-ins
43+
2. External libraries
44+
3. Internal modules (relative imports last)
45+
46+
## Error Handling
47+
- Use custom error classes
48+
- Include error context and cause
49+
- Never swallow errors silently

.cursor/skills/SKILL.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Project skills
2+
3+
Agent-oriented skills for **cli-query-export** (`@contentstack/cli-cm-export-query`) live under **[`skills/`](../../skills/)**.
4+
5+
Reference in chat with `@skills/<name>` (for example `@skills/contentstack-cli`, `@skills/testing`).

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ contents/
1717
logs/
1818
oclif.manifest.json
1919
talisman_output.log
20+
snyk_output.log

.nycrc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"inlcude": [
2+
"include": [
33
"lib/**/*.js"
44
]
55
}

.talismanrc

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
fileignoreconfig:
2-
- filename: src/core/query-executor.ts
3-
checksum: 3d0b5cf07f5a87256f132f85a5556d193ce5a1fa6d92df2c7c50514071d592b7
2+
- filename: skills/code-review/SKILL.md
3+
checksum: 8c0c5c1a18ba08aa0c048d261f1ca81c152def23745fd74b531b75a23a5ac969
4+
- filename: skills/framework/SKILL.md
5+
checksum: 5674849276e2087f6361decb2c7e427f451ec7799538fa2eb697b0a8b7b92f44
6+
- filename: .cursor/rules/contentstack-cli.mdc
7+
checksum: 11bf8883f584b900ce1cde336057391717b47eb5a304cb46c5660bb3185cef2f
8+
- filename: skills/code-review/references/code-review-checklist.md
9+
checksum: 6e65ad06469083ed0196edaf8bd2d4478800493b32535be7c98e436082fba44a
10+
- filename: skills/framework/references/framework-patterns.md
11+
checksum: cae3858eea36c1f716ebe4a9679fc3d4eee628cb244cf4fc0a6eccbd8cecb36d
412
- filename: package-lock.json
5-
checksum: 216c297102d8f30ebed4a942e24d27f94f714ef9e32a932474e85127fb7cc435
6-
- filename: src/types/index.ts
7-
checksum: 8d3021c2690dbceeb5a97e449262834b8177f2a4a674fe13ac33d71b890ab8fd
8-
- filename: src/utils/logger.ts
9-
checksum: c5baa97b996aaeaa0eb2c4d40d71bd67047fc85281449278f3d9058433dcb4ab
13+
checksum: 9b73c1e977f09964843bd5f7529ca8decb7e8b5ab462a4e9ab167ff2a05df53f
1014
version: '1.0'

0 commit comments

Comments
 (0)