diff --git a/.gitignore b/.gitignore index 7666e86f..0d600e32 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,6 @@ jsdoc/* out/* .DS_Store .vscode -dist/* \ No newline at end of file +dist/* +.env +.env.* diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..f647ba7a --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,41 @@ +# ui-extensions-sdk + +`@contentstack/ui-extensions-sdk`: the legacy (pre-Marketplace) UI extensions SDK. Existing custom fields, custom widgets and dashboard widgets in customers' stacks load it from npm/unpkg (`dist/ui-extension-sdk.js`, UMD global `ContentstackUIExtension`). It does the `init` handshake with the Contentstack web app (the host) over post-robot and exposes `extension.field`, `entry`, `window`, `stack` and `store`. New work belongs in `@contentstack/app-sdk`; this repo gets bug and security fixes. + +**Stack:** JavaScript (ES modules, Babel) · webpack 5 (UMD bundle + CSS in `dist/`) · Karma + Jasmine in headless Chrome · post-robot 8.0.29 · wolfy87-eventemitter · npm +**Commands:** `npm ci --legacy-peer-deps` (plain `npm ci` fails ERESOLVE: the airbnb ESLint config peers eslint 8, the repo is on 9; `prepare` builds) · `npm run build` (also lints with `--fix` and regenerates `jsdocs/`) · `npm test` · `npm run generate:docs` · `npm run generate:sri` (SRI hashes for the README) +**Env:** the library reads no environment variables, so there is no env sample. + +## Public API contract (hard rules) +- This package is public and runs inside customers' existing extensions. No breaking change: the `ContentstackUIExtension` global, exported classes, method names and signatures, the `init`/`ready` handshake, post-robot channel names (`init`, `ready`, `extensionEvent`, `stack`, ...) and payload shapes stay as they are. +- Change runtime behaviour only for a confirmed bug fix, and say in the PR exactly what consumers will see differ. Every other PR says it changes nothing for consumers. +- Host-to-extension listeners (`postRobot.on`) must accept messages from `window.parent` only (`{ window: window.parent }`); see contentstack/ui-extensions-sdk#65. +- No `console.log` of entry, field or user data; never log tokens, headers or bodies. +- Error messages are part of the contract (extensions may match them): keep the current text as the prefix. +- A version bump, release or `npm publish` is the release process's job (GitHub release -> `.github/workflows/npm-publish.yml`, which runs `npm test` first), never part of a feature or fix PR. + +## Layout +| Path | Purpose | +|------|---------| +| `lib/index.js` | `ContentstackUIExtension.init()` entry, `SDK_VERSION` | +| `lib/extension.js` | `init` handshake, location objects, host event routing (`extensionEvent`) | +| `lib/field.js`, `entry.js`, `window.js`, `store.js` | field, entry, iframe size and store APIs | +| `lib/stack/` | `stack` queries (content types, entries, assets) | +| `test/*Spec.js` | Karma/Jasmine specs; `test/data/` fixtures | +| `docs/ui-extensions-api-reference.md` | API reference (public) | +| `jsdocs/` | generated by the build; `.github/readme/blueprint.md` generates `README.md` | + +## Review rules (from the `master` ruleset) +The ruleset "Default branch protection rules for releases branch" covers `master`: +- Changes land by pull request only; no force push, no branch deletion. +- 1 approving review, including a code owner (`CODEOWNERS`: `@contentstack/developer-ecosystem-pr-reviewers`; workflows, `.snyk`, `CODEOWNERS` and `.gitguardian.yaml` need `@contentstack/security-admin`). +- The last push needs approval from someone other than its pusher; new pushes dismiss stale approvals; all review threads must be resolved. +- Required checks: `GitGuardian Security Checks`, `security-sca`, `security-license`, `security-policy`, `security/snyk`, `code/snyk`, `license/snyk` (contentstack-developer-ecosystem). Tests are not a required check: run `npm test` yourself. Until #69 merges no workflow runs them on pull requests; after it, read the `Unit tests` run on the PR. +- Merge, squash or rebase are all allowed. Release tags are protected by a separate ruleset. + +## Definition of Done +- `npm test` is green, with a spec for every public method the change adds or changes, written from the docs, not from the code's output. +- `npm run build` passes and adds no new ESLint warning. +- The PR states the consumer impact (none, or exactly what changes). +- `docs/ui-extensions-api-reference.md` updated for public API changes; README regenerated from the blueprint when the usage changes. +- No secrets in code, commits or logs. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..e81e374c --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,16 @@ +# Contributing to the Contentstack UI Extensions SDK + +Thanks for helping. This package is public and runs inside customers' existing custom fields, widgets and dashboard widgets, so changes are held to a strict compatibility bar. New features belong in the [App SDK](https://github.com/contentstack/app-sdk); this SDK takes bug and security fixes. + +## Reporting +- Bugs: open a GitHub issue with the SDK version, the extension type, and steps to reproduce. +- Security issues: do not open an issue; follow [SECURITY.md](SECURITY.md). + +## Pull requests +1. Fork, branch from `master`, and run `npm ci --legacy-peer-deps`. +2. Keep the public API stable: no change to exported names or method signatures, and no runtime change unless it fixes a bug. Say in the PR what consumers will see differ, or that nothing changes. +3. Add or update specs in `test/`, then run `npm test` and `npm run build`. +4. Update `docs/ui-extensions-api-reference.md` when the public API changes. +5. Open the pull request against `master`. A code owner reviews it, and the security checks must pass. + +By contributing you agree that your contribution is licensed under the [MIT License](LICENSE).