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
5 changes: 5 additions & 0 deletions .cursor/rules/README.md
Original file line number Diff line number Diff line change
@@ -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.
79 changes: 79 additions & 0 deletions .github/workflows/check-version-bump.yml
Original file line number Diff line number Diff line change
@@ -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)."
39 changes: 11 additions & 28 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
name: Release

on:
push:
branches: [master]
release:
types: [created]

jobs:
build:
Expand All @@ -12,61 +12,44 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4

# Setup Node.js environment
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22.x"

# Install dependencies
- name: Install dependencies
run: npm install

# Fetch package details (name and version)
- name: Get package details
id: package
uses: codex-team/action-nodejs-package-info@v1.1

# Install npm-pack-all to create a package archive
- name: Install npm pack
run: npm install npm-pack

# Pack the package into a .tgz archive
- name: Pack the npm package
run: npm pack

# Publish package to npm
# Publish the package to npm
- name: Publish to npm
id: publish_npm
uses: JS-DevTools/npm-publish@v3
with:
token: ${{ secrets.NPM_TOKEN }}
# access: public # Uncomment this line if you want to publish the package as public for first time

# Auto-tag new version
- name: Auto-tag new version
id: update_tag
uses: Klemensas/action-autotag@stable
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
tag_prefix: "v"

# Create GitHub Release
- name: Create GitHub Release
if: steps.update_tag.outputs.tagname != ''
uses: actions/create-release@v1
id: create_release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.update_tag.outputs.tagname }}
release_name: Release ${{ steps.update_tag.outputs.tagname }}
draft: false
prerelease: false

# Upload release asset
# Upload the packaged .tgz to the release that triggered this workflow
- name: Upload Release Asset
if: steps.update_tag.outputs.tagname != ''
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
upload_url: ${{ github.event.release.upload_url }}
asset_path: "./contentstack-datasync-filesystem-sdk-${{ steps.package.outputs.version }}.tgz"
asset_name: "contentstack-datasync-filesystem-sdk-${{ steps.package.outputs.version }}.tgz"
asset_content_type: application/tgz
asset_content_type: application/tgz
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ example/**/*
_old_test_backup

#dist
dist
dist

datasync-boilerplate
40 changes: 40 additions & 0 deletions .husky/post-checkout
Original file line number Diff line number Diff line change
@@ -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."
49 changes: 49 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -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/<name>/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.
Loading
Loading