Compare commits

..

31 Commits

Author SHA1 Message Date
37a1495ca7 Update repository and homepage URLs in package.json to point to GitHub
All checks were successful
RenovateBot / renovate (push) Successful in 26s
Test / Basic (push) Successful in 2m44s
2026-02-06 04:04:42 +04:00
5cb05bd37e Merge pull request 'Update actions/checkout action to v6' (!11) from renovate/actions-checkout-6.x into master
Some checks failed
RenovateBot / renovate (push) Has been cancelled
Test / Basic (push) Has been cancelled
Reviewed-on: #11
2026-02-06 04:04:35 +04:00
c352511bd2 Update actions/setup-node action to v6
Some checks failed
RenovateBot / renovate (push) Has been cancelled
Test / Basic (push) Has been cancelled
Test / Basic (pull_request) Successful in 2m55s
2026-02-06 00:01:03 +00:00
b13bf7fd8c Update actions/checkout action to v6
All checks were successful
Test / Basic (pull_request) Successful in 2m47s
2026-02-06 00:01:00 +00:00
a7b4d14685 Upgrade npm version in GitHub Actions workflow for trusted publishing
All checks were successful
Test / Basic (push) Successful in 2m47s
RenovateBot / renovate (push) Successful in 1m0s
2026-02-05 23:54:21 +00:00
4bb3145906 Update GitHub Actions workflow to simplify publish step name
All checks were successful
RenovateBot / renovate (push) Successful in 25s
Test / Basic (push) Successful in 2m48s
2026-02-05 23:49:25 +00:00
cb6ca38f7f Update GitHub Actions workflow to publish with provenance
Some checks failed
RenovateBot / renovate (push) Successful in 26s
Test / Basic (push) Has been cancelled
- Removed the registry URL from the setup-node action for cleaner configuration.
- Modified the publish command to include the --provenance flag, enhancing the security and traceability of published packages.
2026-02-05 23:47:19 +00:00
074bd549d5 Update version to 1.0.0 in package.json and package-lock.json
All checks were successful
RenovateBot / renovate (push) Successful in 25s
Test / Basic (push) Successful in 3m24s
- Bumped the version from 0.0.0 to 1.0.0 in both package.json and package-lock.json to reflect the initial release of the plugin.
2026-02-05 23:31:42 +00:00
e9726a120a Update package-lock.json to reflect dependency changes
All checks were successful
RenovateBot / renovate (push) Successful in 24s
Test / Basic (push) Successful in 3m27s
- Upgraded @pkgr/core from version 0.1.2 to 0.2.9 and updated its funding URL.
- Added mime-db version 1.52.0 as a dependency for multiple packages.
- Updated mime-db to version 1.54.0 in the root dependencies.
- Removed outdated dependencies related to jest-snapshot and synckit.
- Added new dependencies for prettier-plugin-packagejson.
2026-02-05 23:25:10 +00:00
0be90df662 Update package.json and GitHub Actions workflow for version consistency
Some checks failed
RenovateBot / renovate (push) Successful in 25s
Test / Basic (push) Has been cancelled
- Changed the repository URL in package.json from SSH to HTTPS for better accessibility.
- Updated the homepage URL in package.json to remove the #readme fragment.
- Added a step in the GitHub Actions workflow to ensure that the tag matches the package version before publishing, enhancing version control integrity.
2026-02-05 23:22:48 +00:00
c20175cffb Add GitHub Actions workflow for publishing plugin
All checks were successful
RenovateBot / renovate (push) Successful in 24s
Test / Basic (push) Successful in 3m25s
- Introduced a new workflow file (.github/workflows/publish.yml) to automate the publishing process for the plugin.
- Configured jobs for testing and publishing to NPM upon version tag pushes.
- Included steps for dependency installation, plugin building, and verification before publishing.
- Ensured integration tests are run in the playground environment before publishing the plugin.
2026-02-06 03:11:14 +04:00
7714b04a3f Merge pull request 'Update dependency mime-types to v3' (#10) from renovate/mime-types-3.x into master
Some checks failed
RenovateBot / renovate (push) Has been cancelled
Test / Basic (push) Has been cancelled
Reviewed-on: #10
2026-02-06 03:07:39 +04:00
4ff7a080f3 Update dependency mime-types to v3
All checks were successful
Test / Basic (pull_request) Successful in 3m23s
2026-02-05 23:04:51 +00:00
260b11c335 Update dependency jest to v30
Some checks failed
RenovateBot / renovate (push) Has been cancelled
Test / Basic (push) Has been cancelled
Test / Basic (pull_request) Successful in 3m26s
2026-02-05 23:04:38 +00:00
84854cee8e Add CHANGELOG.md to document project updates and version history
Some checks failed
RenovateBot / renovate (push) Successful in 1m45s
Test / Basic (push) Has been cancelled
- Introduced a new CHANGELOG.md file to track notable changes in the project.
- Documented the initial release (1.0.0) with details on added features, documentation improvements, and licensing information.
- Adheres to the Keep a Changelog format and Semantic Versioning.
2026-02-06 03:03:07 +04:00
319ffbe9a8 Update maintainer contact format in README.md to use a mailto link for better accessibility. 2026-02-06 03:03:07 +04:00
f91940ddbe Remove specific Strapi version requirement from README.md 2026-02-06 03:03:06 +04:00
fc85dc3835 Merge pull request 'Update actions/checkout action to v6' (#7) from renovate/actions-checkout-6.x into master
Some checks failed
Test / Basic (push) Has been cancelled
RenovateBot / renovate (push) Has been cancelled
Reviewed-on: #7
2026-02-06 03:02:18 +04:00
1af4c9473b Update actions/setup-node action to v6
Some checks failed
Test / Basic (pull_request) Successful in 3m34s
Test / Basic (push) Has been cancelled
RenovateBot / renovate (push) Has been cancelled
2026-02-05 22:31:55 +00:00
005a8b8526 Update actions/checkout action to v6
All checks were successful
Test / Basic (pull_request) Successful in 2m46s
2026-02-05 22:31:52 +00:00
08dac92ead Add .npmignore, LICENSE.txt, and update README.md
All checks were successful
RenovateBot / renovate (push) Successful in 31s
Test / Basic (push) Successful in 2m49s
- Created a .npmignore file to exclude unnecessary files and directories from npm packages.
- Added LICENSE.txt to specify the licensing terms for the project.
- Expanded README.md to include detailed plugin features, installation instructions, usage guidelines, and contribution information.
- Updated package.json to reflect new repository URLs for issues and homepage.
2026-02-05 22:31:20 +00:00
d387c7bf8a Refactor Gitea workflow and update package dependencies
All checks were successful
RenovateBot / renovate (push) Successful in 25s
Test / Basic (push) Successful in 3m24s
- Simplified the Gitea workflow by removing the E2E testing section and renaming the integration tests job.
- Updated package-lock.json to include new dependencies for escape-string-regexp and removed outdated dependencies.
- Removed Playwright configuration and related test files from the playground directory to streamline testing processes.
2026-02-05 21:53:51 +00:00
7a0e6615d0 Add Gitea workflow for testing and E2E integration
Some checks failed
RenovateBot / renovate (push) Successful in 25s
Test / Basic (push) Successful in 3m26s
Test / E2E (push) Has been cancelled
- Introduced a new workflow file (.gitea/workflows/test.yml) to automate testing processes.
- Configured jobs for basic testing and end-to-end (E2E) testing using Jest, Supertest, and Playwright.
- Included steps for dependency installation, plugin building, and Strapi server management during E2E tests.
- Set up environment variables for E2E tests and ensured proper handling of the Strapi server lifecycle.
2026-02-05 21:39:52 +00:00
9012c5cb1f Update dependency fs-extra to v11 (#6)
All checks were successful
RenovateBot / renovate (push) Successful in 24s
This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [fs-extra](https://github.com/jprichardson/node-fs-extra) | [`^10.0.0` → `^11.0.0`](https://renovatebot.com/diffs/npm/fs-extra/10.1.0/11.3.3) | ![age](https://developer.mend.io/api/mc/badges/age/npm/fs-extra/11.3.3?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/fs-extra/10.1.0/11.3.3?slim=true) |

---

### Release Notes

<details>
<summary>jprichardson/node-fs-extra (fs-extra)</summary>

### [`v11.3.3`](https://github.com/jprichardson/node-fs-extra/blob/HEAD/CHANGELOG.md#1133--2025-12-18)

[Compare Source](https://github.com/jprichardson/node-fs-extra/compare/11.3.2...11.3.3)

- Fix copying symlink when destination is a symlink to the same target ([#&#8203;1019](https://github.com/jprichardson/node-fs-extra/issues/1019), [#&#8203;1060](https://github.com/jprichardson/node-fs-extra/pull/1060))

### [`v11.3.2`](https://github.com/jprichardson/node-fs-extra/blob/HEAD/CHANGELOG.md#1132--2025-09-15)

[Compare Source](https://github.com/jprichardson/node-fs-extra/compare/11.3.1...11.3.2)

- Fix spurrious `UnhandledPromiseRejectionWarning` that could occur when calling `.copy()` in some cases ([#&#8203;1056](https://github.com/jprichardson/node-fs-extra/issues/1056), [#&#8203;1058](https://github.com/jprichardson/node-fs-extra/pull/1058))

### [`v11.3.1`](https://github.com/jprichardson/node-fs-extra/blob/HEAD/CHANGELOG.md#1131--2025-08-05)

[Compare Source](https://github.com/jprichardson/node-fs-extra/compare/11.3.0...11.3.1)

- Fix case where `move`/`moveSync` could incorrectly think files are identical on Windows ([#&#8203;1050](https://github.com/jprichardson/node-fs-extra/pull/1050))

### [`v11.3.0`](https://github.com/jprichardson/node-fs-extra/blob/HEAD/CHANGELOG.md#1130--2025-01-15)

[Compare Source](https://github.com/jprichardson/node-fs-extra/compare/11.2.0...11.3.0)

- Add promise support for newer `fs` methods ([#&#8203;1044](https://github.com/jprichardson/node-fs-extra/issues/1044), [#&#8203;1045](https://github.com/jprichardson/node-fs-extra/pull/1045))
- Use `fs.opendir` in `copy()`/`copySync()` for better perf/scalability ([#&#8203;972](https://github.com/jprichardson/node-fs-extra/issues/972), [#&#8203;1028](https://github.com/jprichardson/node-fs-extra/pull/1028))

### [`v11.2.0`](https://github.com/jprichardson/node-fs-extra/blob/HEAD/CHANGELOG.md#1120--2023-11-27)

[Compare Source](https://github.com/jprichardson/node-fs-extra/compare/11.1.1...11.2.0)

- Copy directory contents in parallel for better performance ([#&#8203;1026](https://github.com/jprichardson/node-fs-extra/pull/1026))
- Refactor internal code to use `async`/`await` ([#&#8203;1020](https://github.com/jprichardson/node-fs-extra/issues/1020))

### [`v11.1.1`](https://github.com/jprichardson/node-fs-extra/blob/HEAD/CHANGELOG.md#1111--2023-03-20)

[Compare Source](https://github.com/jprichardson/node-fs-extra/compare/11.1.0...11.1.1)

- Preserve timestamps when moving files across devices ([#&#8203;992](https://github.com/jprichardson/node-fs-extra/issues/992), [#&#8203;994](https://github.com/jprichardson/node-fs-extra/pull/994))

### [`v11.1.0`](https://github.com/jprichardson/node-fs-extra/blob/HEAD/CHANGELOG.md#1110--2022-11-29)

[Compare Source](https://github.com/jprichardson/node-fs-extra/compare/11.0.0...11.1.0)

- Re-add `main` field to `package.json` for better TypeScript compatibility ([#&#8203;979](https://github.com/jprichardson/node-fs-extra/issues/979), [#&#8203;981](https://github.com/jprichardson/node-fs-extra/pull/981))

### [`v11.0.0`](https://github.com/jprichardson/node-fs-extra/blob/HEAD/CHANGELOG.md#1100--2022-11-28)

[Compare Source](https://github.com/jprichardson/node-fs-extra/compare/10.1.0...11.0.0)

##### Breaking Changes

- Don't allow requiring `fs-extra/lib/SOMETHING` (switched to `exports`) ([#&#8203;974](https://github.com/jprichardson/node-fs-extra/pull/974))
- Require Node v14.14+ ([#&#8203;968](https://github.com/jprichardson/node-fs-extra/issues/968), [#&#8203;969](https://github.com/jprichardson/node-fs-extra/pull/969))

##### New Features

- Add `fs-extra/esm` for ESM named export support; see [docs](https://github.com/jprichardson/node-fs-extra#esm) for details ([#&#8203;746](https://github.com/jprichardson/node-fs-extra/issues/746), [#&#8203;974](https://github.com/jprichardson/node-fs-extra/pull/974))
- Add promise support for `fs.readv()` ([#&#8203;970](https://github.com/jprichardson/node-fs-extra/pull/970))

##### Bugfixes

- Don't `stat` filtered items in `copy*` ([#&#8203;965](https://github.com/jprichardson/node-fs-extra/issues/965), [#&#8203;971](https://github.com/jprichardson/node-fs-extra/pull/971))
- Remove buggy stats check in `copy` ([#&#8203;918](https://github.com/jprichardson/node-fs-extra/issues/918), [#&#8203;976](https://github.com/jprichardson/node-fs-extra/pull/976))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4wLjUiLCJ1cGRhdGVkSW5WZXIiOiI0My4wLjUiLCJ0YXJnZXRCcmFuY2giOiJtYXN0ZXIiLCJsYWJlbHMiOlsiYXV0b21hdGVkIiwiZGVwZW5kZW5jaWVzIl19-->

Reviewed-on: https://code.popov.link/valentineus/strapi-plugin-checkbox-list/pulls/6
Co-authored-by: renovate[bot] <renovatebot@noreply.localhost>
Co-committed-by: renovate[bot] <renovatebot@noreply.localhost>
2026-02-06 01:36:58 +04:00
5cb863b56c Update actions/setup-node action to v6
Some checks failed
RenovateBot / renovate (push) Has been cancelled
2026-02-05 21:35:34 +00:00
393e2fb7f2 Update actions/checkout action to v6
All checks were successful
RenovateBot / renovate (push) Successful in 1m24s
2026-02-05 15:55:01 +00:00
f83b43e6f6 Add GitHub Actions workflow for testing and E2E integration
All checks were successful
RenovateBot / renovate (push) Successful in 29s
- Created a new workflow file (.github/workflows/test.yml) to automate testing processes.
- Defined jobs for basic testing and end-to-end (E2E) testing using Jest, Supertest, and Playwright.
- Included steps for dependency installation, plugin building, and Strapi server management during E2E tests.
2026-02-05 15:54:27 +00:00
1d3a010b50 Refactor Gitea workflow to alternate between npm install and npm ci for dependency management in different job stages
Some checks failed
RenovateBot / renovate (push) Successful in 29s
Test / Basic (push) Failing after 1m57s
Test / E2E (push) Has been skipped
2026-02-05 15:46:01 +00:00
60310f5b9d Update Gitea workflow to use npm install instead of npm ci for dependency installation
Some checks failed
RenovateBot / renovate (push) Successful in 29s
Test / Basic (push) Failing after 1m42s
Test / E2E (push) Has been skipped
2026-02-05 15:41:47 +00:00
ee32dedf61 Enhance testing and integration for checkbox-list custom field
Some checks failed
RenovateBot / renovate (push) Successful in 27s
Test / Basic (push) Failing after 1m43s
Test / E2E (push) Has been skipped
- Updated Gitea workflow to trigger on pushes to the master branch and refined job configurations for testing and E2E processes.
- Added Jest and Playwright configurations for integration and E2E testing.
- Introduced new checkbox-item API with corresponding controller, service, and routes.
- Created integration tests for the checkbox-list functionality, ensuring proper handling of required fields and default values.
- Updated package.json and package-lock.json to include necessary dependencies for testing.
2026-02-05 19:38:48 +04:00
0c71c44599 Update dependency @types/node to v20.19.32
Some checks failed
Test / Basic (pull_request) Failing after 1m44s
Test / E2E (pull_request) Has been skipped
RenovateBot / renovate (push) Successful in 28s
2026-02-05 15:01:39 +00:00
17 changed files with 4931 additions and 1646 deletions

View File

@@ -1,6 +1,9 @@
name: Test
on:
push:
branches:
- master
pull_request:
workflow_dispatch:
@@ -9,14 +12,19 @@ jobs:
name: Basic
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v4
- name: Checkout
uses: actions/checkout@v6
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: 22
cache: "npm"
cache-dependency-path: |
package-lock.json
playground/package-lock.json
- name: Write playground .env
run: |
printf '%s' "${{ secrets.PLAYGROUND_ENV_BASE64 }}" | base64 -d > playground/.env
- name: Install root deps
run: npm ci
- name: Build plugin
@@ -29,59 +37,11 @@ jobs:
mkdir -p playground/.yalc/strapi-plugin-checkbox-list
tar -xzf "$TARBALL" -C playground/.yalc/strapi-plugin-checkbox-list --strip-components=1
- name: Install playground deps
run: npm ci --prefix playground
working-directory: playground
run: npm install
- name: Build playground
run: npm run build --prefix playground
- name: Integration tests (Jest + Supertest)
run: npm run test:integration --prefix playground
e2e:
name: E2E
runs-on: ubuntu-latest
needs: test
env:
STRAPI_ADMIN_EMAIL: admin@example.com
STRAPI_ADMIN_PASSWORD: Admin12345
STRAPI_ADMIN_FIRSTNAME: Admin
STRAPI_ADMIN_LASTNAME: User
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v4
with:
node-version: 22
cache: "npm"
cache-dependency-path: |
package-lock.json
playground/package-lock.json
- name: Install root deps
run: npm ci
- name: Build plugin
working-directory: playground
run: npm run build
- name: Pack plugin into playground .yalc
run: |
TARBALL=$(npm pack --silent)
mkdir -p playground/.yalc/strapi-plugin-checkbox-list
tar -xzf "$TARBALL" -C playground/.yalc/strapi-plugin-checkbox-list --strip-components=1
- name: Install playground deps
run: npm ci --prefix playground
- name: Create admin user
run: |
cd playground
npx strapi admin:create-user \
--email "$STRAPI_ADMIN_EMAIL" \
--password "$STRAPI_ADMIN_PASSWORD" \
--firstname "$STRAPI_ADMIN_FIRSTNAME" \
--lastname "$STRAPI_ADMIN_LASTNAME"
- name: Start Strapi
run: |
npm run develop --prefix playground -- --host 0.0.0.0 --port 1337 &
echo $! > /tmp/strapi.pid
until curl -sSf http://127.0.0.1:1337/admin >/dev/null; do sleep 2; done
- name: E2E tests (Playwright/Cypress)
run: npm run e2e --prefix playground
- name: Stop Strapi
if: always()
run: |
if [ -f /tmp/strapi.pid ]; then
kill "$(cat /tmp/strapi.pid)" || true
fi
- name: Integration tests
working-directory: playground
run: npm run test:integration

89
.github/workflows/publish.yml vendored Normal file
View File

@@ -0,0 +1,89 @@
name: Publish
on:
push:
tags:
- "v*"
permissions:
contents: read
id-token: write
jobs:
test:
name: Tests
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: 22
cache: "npm"
cache-dependency-path: |
package-lock.json
playground/package-lock.json
- name: Check tag matches package version
run: |
VERSION=$(node -p "require('./package.json').version")
TAG="${GITHUB_REF_NAME}"
if [ "v${VERSION}" != "${TAG}" ]; then
echo "Tag ${TAG} does not match package.json version v${VERSION}"
exit 1
fi
- name: Write playground .env
run: |
printf '%s' "${{ secrets.PLAYGROUND_ENV_BASE64 }}" | base64 -d > playground/.env
- name: Install root deps
run: npm ci
- name: Build plugin
run: npm run build
- name: Verify plugin
run: npm run verify
- name: Pack plugin into playground .yalc
run: |
TARBALL=$(npm pack --silent)
mkdir -p playground/.yalc/strapi-plugin-checkbox-list
tar -xzf "$TARBALL" -C playground/.yalc/strapi-plugin-checkbox-list --strip-components=1
- name: Install playground deps
working-directory: playground
run: npm install
- name: Build playground
working-directory: playground
run: npm run build
- name: Integration tests
working-directory: playground
run: npm run test:integration
publish:
name: Publish to NPM
runs-on: ubuntu-latest
needs: test
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: 22
cache: "npm"
cache-dependency-path: package-lock.json
- name: Upgrade npm for trusted publishing
run: npm install -g npm@^11.5.1
- name: Check tag matches package version
run: |
VERSION=$(node -p "require('./package.json').version")
TAG="${GITHUB_REF_NAME}"
if [ "v${VERSION}" != "${TAG}" ]; then
echo "Tag ${TAG} does not match package.json version v${VERSION}"
exit 1
fi
- name: Install deps
run: npm ci
- name: Build plugin
run: npm run build
- name: Verify plugin
run: npm run verify
- name: Publish
run: npm publish --provenance

39
.npmignore Normal file
View File

@@ -0,0 +1,39 @@
# Dependencies and logs
node_modules/
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Caches and temp
.cache/
.tmp/
*.tgz
# VCS / CI / IDE
.git/
.gitea/
.github/
.gitlab/
.vscode/
.idea/
.DS_Store
# Playground / tests / coverage
playground/
tests/
coverage/
**/__tests__/
**/*.spec.*
**/*.test.*
# Source-only folders (built output lives in dist/)
admin/
server/
# Misc project files
renovate.config.cjs
package-lock.json
.env
.env.*

27
CHANGELOG.md Normal file
View File

@@ -0,0 +1,27 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.0.0] (2026-02-06)
### Added
- Custom checkbox list field for Strapi v5 Content Type Builder
- Multi-select interface with intuitive checkbox-based selection
- Flexible configuration for defining custom option lists per field instance
- Native integration with Strapi's Content Type Builder
- Full TypeScript support for type-safe development
- Playground environment for development and testing
- Watch mode for active development with automatic rebuilds
- Plugin linker support for local development workflow
### Documentation
- Comprehensive README with installation and usage instructions
- Development setup guide for contributors
- MIT License
[1.0.0]: https://code.popov.link/valentineus/strapi-plugin-checkbox-list/releases/tag/v1.0.0

7
LICENSE.txt Normal file
View File

@@ -0,0 +1,7 @@
Copyright (c) 2026 Valentin Popov <valentin@popov.link>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -1 +1,79 @@
# strapi-plugin-checkbox-list
# Strapi Checkbox List Plugin
A custom field plugin for Strapi v5 that extends the Content Type Builder with a flexible checkbox list component. Enable content editors to select multiple values from predefined options with an intuitive interface that seamlessly integrates into the Strapi admin panel.
## Features
- **Multi-select interface**: Intuitive checkbox-based selection for content editors
- **Flexible configuration**: Define custom option lists for each field instance
- **Native integration**: Works seamlessly within Strapi's Content Type Builder
- **Type-safe**: Full TypeScript support for enhanced development experience
## Requirements
- Node.js and npm compatible with Strapi v5
## Installation
Install the package in your Strapi project:
```bash
npm install strapi-plugin-checkbox-list
```
Restart your Strapi application, then navigate to the Content Type Builder to add the **Checkbox list** custom field to your content types.
## Usage
After installation, the Checkbox list field type will be available in the Content Type Builder:
1. Open Content Type Builder
2. Select a content type or create a new one
3. Click "Add another field"
4. Choose "Checkbox list" from the custom fields
5. Configure your checkbox options
6. Save and use in your content entries
## Contributing & Support
This project is actively maintained and welcomes contributions. Issues and pull requests can be submitted through either repository:
- **Primary development**: [valentineus/strapi-plugin-checkbox-list](https://code.popov.link/valentineus/strapi-plugin-checkbox-list/issues)
- **GitHub mirror**: [valentineus/strapi-plugin-checkbox-list](https://github.com/valentineus/strapi-plugin-checkbox-list/issues)
Development primarily takes place on the self-hosted Git instance, with GitHub serving as a mirror for broader accessibility.
**Maintainer**: [Valentin Popov](mailto:valentin@popov.link)
## Development
Build the plugin:
```bash
npm install
npm run build
```
For active development with automatic rebuilds:
```bash
npm run watch
```
To run the test Strapi app from `playground/`:
```bash
cd playground
npm install
npm run develop
```
If you need the plugin linked into the playground app, use the Strapi plugin linker and point it at `playground/`:
```bash
npm run watch:link
```
## License
This project is licensed under the [MIT License](LICENSE.txt).

346
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "strapi-plugin-checkbox-list",
"version": "0.0.0",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "strapi-plugin-checkbox-list",
"version": "0.0.0",
"version": "1.0.0",
"license": "MIT",
"dependencies": {
"@sindresorhus/slugify": "^3.0.0",
@@ -1081,6 +1081,19 @@
"dev": true,
"license": "MIT"
},
"node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@emotion/babel-plugin/node_modules/source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
@@ -4558,18 +4571,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@sindresorhus/slugify/node_modules/escape-string-regexp": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
"integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@sindresorhus/transliterate": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@sindresorhus/transliterate/-/transliterate-2.3.1.tgz",
@@ -5398,6 +5399,19 @@
"@types/react": "^18.0.0"
}
},
"node_modules/@strapi/content-manager/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@strapi/content-manager/node_modules/intl-messageformat": {
"version": "10.5.11",
"resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.5.11.tgz",
@@ -5975,6 +5989,19 @@
"@types/react": "^18.0.0"
}
},
"node_modules/@strapi/content-type-builder/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@strapi/content-type-builder/node_modules/intl-messageformat": {
"version": "10.5.11",
"resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.5.11.tgz",
@@ -6733,6 +6760,19 @@
"node": ">=8"
}
},
"node_modules/@strapi/generators/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@strapi/generators/node_modules/lodash": {
"version": "4.17.23",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
@@ -8135,18 +8175,6 @@
"csstype": "^3.2.2"
}
},
"node_modules/@strapi/ui-primitives/node_modules/aria-hidden": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz",
"integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==",
"license": "MIT",
"dependencies": {
"tslib": "^2.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@strapi/ui-primitives/node_modules/react-remove-scroll": {
"version": "2.5.10",
"resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.10.tgz",
@@ -8436,6 +8464,19 @@
"@types/react": "^18.0.0"
}
},
"node_modules/@strapi/upload/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@strapi/upload/node_modules/execa": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
@@ -8703,6 +8744,19 @@
"node": ">=8"
}
},
"node_modules/@strapi/utils/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@strapi/utils/node_modules/execa": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
@@ -9573,9 +9627,9 @@
"license": "MIT"
},
"node_modules/@types/node": {
"version": "25.2.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.0.tgz",
"integrity": "sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w==",
"version": "25.2.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.1.tgz",
"integrity": "sha512-CPrnr8voK8vC6eEtyRzvMpgp3VyVRhgclonE7qYi6P9sXwYb59ucfrnmFBTaP0yUi8Gk4yZg/LlTJULGxvTNsg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -9685,12 +9739,13 @@
}
},
"node_modules/@types/send": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz",
"integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==",
"version": "0.17.6",
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz",
"integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/mime": "^1",
"@types/node": "*"
}
},
@@ -9706,17 +9761,6 @@
"@types/send": "<1"
}
},
"node_modules/@types/serve-static/node_modules/@types/send": {
"version": "0.17.6",
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz",
"integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/mime": "^1",
"@types/node": "*"
}
},
"node_modules/@types/stylis": {
"version": "4.2.7",
"resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.7.tgz",
@@ -10372,9 +10416,9 @@
"license": "Python-2.0"
},
"node_modules/aria-hidden": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz",
"integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==",
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz",
"integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==",
"license": "MIT",
"dependencies": {
"tslib": "^2.0.0"
@@ -10844,28 +10888,6 @@
"nodemailer-shared": "1.1.0"
}
},
"node_modules/buildmail/node_modules/iconv-lite": {
"version": "0.4.13",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz",
"integrity": "sha512-QwVuTNQv7tXC5mMWFX5N5wGjmybjNBBD8P3BReTkPmipoxTUFgWM2gXNvldHQr6T14DH0Dh6qBVg98iJt7u4mQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/buildmail/node_modules/libmime": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/libmime/-/libmime-2.1.0.tgz",
"integrity": "sha512-4be2R6/jOasyPTw0BkpIZBVk2cElqjdIdS0PRPhbOCV4wWuL/ZcYYpN1BCTVB+6eIQ0uuAwp5hQTHFrM5Joa8w==",
"dev": true,
"license": "MIT",
"dependencies": {
"iconv-lite": "0.4.13",
"libbase64": "0.1.0",
"libqp": "1.1.0"
}
},
"node_modules/byte-size": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/byte-size/-/byte-size-8.1.1.tgz",
@@ -13247,13 +13269,12 @@
"license": "MIT"
},
"node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true,
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
"integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
"license": "MIT",
"engines": {
"node": ">=10"
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@@ -14059,13 +14080,13 @@
}
},
"node_modules/framer-motion": {
"version": "12.31.1",
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.31.1.tgz",
"integrity": "sha512-cMwCU/k6k7ktHbIXE5NFCgG+BLW2CmCahPMw2MuZuIUHOy1HEa4wnYXBWz4l16eQc8eRGHpO5umWQ0QDl+evPw==",
"version": "12.33.0",
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.33.0.tgz",
"integrity": "sha512-ca8d+rRPcDP5iIF+MoT3WNc0KHJMjIyFAbtVLvM9eA7joGSpeqDfiNH/kCs1t4CHi04njYvWyj0jS4QlEK/rJQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"motion-dom": "^12.30.1",
"motion-dom": "^12.33.0",
"motion-utils": "^12.29.2",
"tslib": "^2.4.0"
},
@@ -14381,9 +14402,9 @@
}
},
"node_modules/get-tsconfig": {
"version": "4.13.1",
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.1.tgz",
"integrity": "sha512-EoY1N2xCn44xU6750Sx7OjOIT59FkmstNc3X6y5xpz7D5cBtZRe/3pSlTkDJgqsOk3WwZPkWfonhhUJfttQo3w==",
"version": "4.13.3",
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.3.tgz",
"integrity": "sha512-vp8Cj/+9Q/ibZUrq1rhy8mCTQpCk31A3uu9wc1C50yAb3x2pFHOsGdAZQ7jD86ARayyxZUViYeIztW+GE8dcrg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -16332,16 +16353,6 @@
"zod": "^3.19.1"
}
},
"node_modules/koa-body/node_modules/zod": {
"version": "3.25.76",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
},
"node_modules/koa-compose": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz",
@@ -16679,25 +16690,25 @@
"license": "MIT"
},
"node_modules/libmime": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/libmime/-/libmime-2.1.3.tgz",
"integrity": "sha512-ABr2f4O+K99sypmkF/yPz2aXxUFHEZzv+iUkxItCeKZWHHXdQPpDXd6rV1kBBwL4PserzLU09EIzJ2lxC9hPfQ==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/libmime/-/libmime-2.1.0.tgz",
"integrity": "sha512-4be2R6/jOasyPTw0BkpIZBVk2cElqjdIdS0PRPhbOCV4wWuL/ZcYYpN1BCTVB+6eIQ0uuAwp5hQTHFrM5Joa8w==",
"dev": true,
"license": "MIT",
"dependencies": {
"iconv-lite": "0.4.15",
"iconv-lite": "0.4.13",
"libbase64": "0.1.0",
"libqp": "1.1.0"
}
},
"node_modules/libmime/node_modules/iconv-lite": {
"version": "0.4.15",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz",
"integrity": "sha512-RGR+c9Lm+tLsvU57FTJJtdbv2hQw42Yl2n26tVIBaYmZzLN+EGfroUugN/z9nJf9kOXd49hBmpoGr4FEm+A4pw==",
"version": "0.4.13",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz",
"integrity": "sha512-QwVuTNQv7tXC5mMWFX5N5wGjmybjNBBD8P3BReTkPmipoxTUFgWM2gXNvldHQr6T14DH0Dh6qBVg98iJt7u4mQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
"node": ">=0.8.0"
}
},
"node_modules/libqp": {
@@ -17050,28 +17061,6 @@
"libmime": "2.1.0"
}
},
"node_modules/mailcomposer/node_modules/iconv-lite": {
"version": "0.4.13",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz",
"integrity": "sha512-QwVuTNQv7tXC5mMWFX5N5wGjmybjNBBD8P3BReTkPmipoxTUFgWM2gXNvldHQr6T14DH0Dh6qBVg98iJt7u4mQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/mailcomposer/node_modules/libmime": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/libmime/-/libmime-2.1.0.tgz",
"integrity": "sha512-4be2R6/jOasyPTw0BkpIZBVk2cElqjdIdS0PRPhbOCV4wWuL/ZcYYpN1BCTVB+6eIQ0uuAwp5hQTHFrM5Joa8w==",
"dev": true,
"license": "MIT",
"dependencies": {
"iconv-lite": "0.4.13",
"libbase64": "0.1.0",
"libqp": "1.1.0"
}
},
"node_modules/make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
@@ -17238,6 +17227,19 @@
"node": ">=10"
}
},
"node_modules/matcher/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
@@ -17972,9 +17974,9 @@
"license": "MIT"
},
"node_modules/mime-db": {
"version": "1.54.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
"integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -17994,16 +17996,6 @@
"node": ">= 0.6"
}
},
"node_modules/mime-types/node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
@@ -18171,9 +18163,9 @@
}
},
"node_modules/motion-dom": {
"version": "12.30.1",
"resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.30.1.tgz",
"integrity": "sha512-QXB+iFJRzZTqL+Am4a1CRoHdH+0Nq12wLdqQQZZsfHlp9AMt6PA098L/61oVZsDA+Ep3QSGudzpViyRrhYhGcQ==",
"version": "12.33.0",
"resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.33.0.tgz",
"integrity": "sha512-XRPebVypsl0UM+7v0Hr8o9UAj0S2djsQWRdHBd5iVouVpMrQqAI0C/rDAT3QaYnXnHuC5hMcwDHCboNeyYjPoQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -19771,10 +19763,9 @@
}
},
"node_modules/postcss": {
"version": "8.5.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
"integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
"dev": true,
"version": "8.4.49",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
"integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
"funding": [
{
"type": "opencollective",
@@ -19791,7 +19782,7 @@
],
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.11",
"nanoid": "^3.3.7",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
@@ -21475,6 +21466,19 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/sanitize-html/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/sanitize-html/node_modules/htmlparser2": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
@@ -21715,9 +21719,9 @@
}
},
"node_modules/sharp/node_modules/semver": {
"version": "7.7.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
"integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
"dev": true,
"license": "ISC",
"bin": {
@@ -22061,9 +22065,9 @@
}
},
"node_modules/sort-package-json/node_modules/semver": {
"version": "7.7.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
"integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
"dev": true,
"license": "ISC",
"bin": {
@@ -22477,34 +22481,6 @@
}
}
},
"node_modules/styled-components/node_modules/postcss": {
"version": "8.4.49",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
"integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.7",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/styled-components/node_modules/stylis": {
"version": "4.3.6",
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz",
@@ -24153,6 +24129,19 @@
"node": ">= 10"
}
},
"node_modules/webpack-bundle-analyzer/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/webpack-bundle-analyzer/node_modules/ws": {
"version": "7.5.10",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
@@ -24812,12 +24801,11 @@
}
},
"node_modules/zod": {
"version": "4.3.6",
"resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz",
"integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
"version": "3.25.76",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
"dev": true,
"license": "MIT",
"peer": true,
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}

View File

@@ -1,5 +1,5 @@
{
"version": "0.0.0",
"version": "1.0.0",
"keywords": [],
"type": "commonjs",
"exports": {
@@ -69,11 +69,11 @@
"license": "MIT",
"repository": {
"type": "git",
"url": "git+ssh://git@popov.link/valentineus/strapi-plugin-checkbox-list.git"
"url": "https://github.com/valentineus/strapi-plugin-checkbox-list.git"
},
"bugs": {
"url": "https://popov.link/valentineus/strapi-plugin-checkbox-list/issues"
"url": "https://github.com/valentineus/strapi-plugin-checkbox-list/issues"
},
"homepage": "https://popov.link/valentineus/strapi-plugin-checkbox-list#readme",
"homepage": "https://github.com/valentineus/strapi-plugin-checkbox-list#readme",
"author": "Valentin Popov <valentin@popov.link>"
}

View File

@@ -0,0 +1,6 @@
module.exports = {
testEnvironment: 'node',
testMatch: ['<rootDir>/tests/integration/**/*.test.js'],
testTimeout: 120000,
verbose: true,
};

File diff suppressed because it is too large Load Diff

View File

@@ -12,6 +12,7 @@
"seed:example": "node ./scripts/seed.js",
"start": "strapi start",
"strapi": "strapi",
"test:integration": "NODE_ENV=test STRAPI_DISABLE_ADMIN=true jest --runInBand",
"upgrade": "npx @strapi/upgrade latest",
"upgrade:dry": "npx @strapi/upgrade latest --dry"
},
@@ -20,8 +21,8 @@
"@strapi/plugin-users-permissions": "5.35.0",
"@strapi/strapi": "5.35.0",
"better-sqlite3": "12.6.2",
"fs-extra": "^10.0.0",
"mime-types": "^2.1.27",
"fs-extra": "^11.0.0",
"mime-types": "^3.0.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react-router-dom": "^6.0.0",
@@ -32,6 +33,8 @@
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"jest": "^30.0.0",
"supertest": "^7.0.0",
"typescript": "^5"
},
"engines": {

View File

@@ -0,0 +1,51 @@
{
"kind": "collectionType",
"collectionName": "checkbox_items",
"info": {
"singularName": "checkbox-item",
"pluralName": "checkbox-items",
"displayName": "Checkbox Item",
"description": "Content type for checkbox list integration tests"
},
"options": {
"draftAndPublish": false
},
"pluginOptions": {},
"attributes": {
"title": {
"type": "string",
"required": true
},
"choices": {
"type": "customField",
"customField": "plugin::checkbox-list.checkbox-list",
"options": {
"enum": ["alpha", "beta", "gamma"]
}
},
"choicesRequired": {
"type": "customField",
"customField": "plugin::checkbox-list.checkbox-list",
"options": {
"enum": ["alpha", "beta"]
},
"required": true
},
"choicesPrivate": {
"type": "customField",
"customField": "plugin::checkbox-list.checkbox-list",
"options": {
"enum": ["secret", "top-secret"]
},
"private": true
},
"choicesDefault": {
"type": "customField",
"customField": "plugin::checkbox-list.checkbox-list",
"options": {
"enum": ["defaultA", "defaultB"]
},
"default": ["defaultA"]
}
}
}

View File

@@ -0,0 +1,7 @@
/**
* checkbox-item controller
*/
import { factories } from '@strapi/strapi';
export default factories.createCoreController('api::checkbox-item.checkbox-item');

View File

@@ -0,0 +1,7 @@
/**
* checkbox-item router
*/
import { factories } from '@strapi/strapi';
export default factories.createCoreRouter('api::checkbox-item.checkbox-item');

View File

@@ -0,0 +1,7 @@
/**
* checkbox-item service
*/
import { factories } from '@strapi/strapi';
export default factories.createCoreService('api::checkbox-item.checkbox-item');

View File

@@ -0,0 +1,163 @@
const fs = require('fs');
const path = require('path');
const supertest = require('supertest');
const { compileStrapi, createStrapi } = require('@strapi/core');
const appRoot = path.resolve(__dirname, '..', '..');
const dbFile = path.join(appRoot, '.tmp', 'test.db');
const ensurePublicPermissions = async (strapi, actions) => {
const role = await strapi.db.query('plugin::users-permissions.role').findOne({
where: { type: 'public' },
});
if (!role) {
throw new Error('Public role not found');
}
const permissions = strapi.db.query('plugin::users-permissions.permission');
for (const action of actions) {
const existing = await permissions.findOne({
where: { action, role: role.id },
});
if (!existing) {
await permissions.create({
data: {
action,
role: role.id,
enabled: true,
},
});
continue;
}
if (!existing.enabled) {
await permissions.update({
where: { id: existing.id },
data: { enabled: true },
});
}
}
};
describe('checkbox-list custom field (API)', () => {
let strapi;
let request;
beforeAll(async () => {
process.chdir(appRoot);
process.env.NODE_ENV = 'test';
process.env.HOST = '127.0.0.1';
process.env.PORT = '1339';
process.env.STRAPI_DISABLE_ADMIN = 'true';
process.env.STRAPI_TELEMETRY_DISABLED = 'true';
process.env.DATABASE_FILENAME = '.tmp/test.db';
process.env.JWT_SECRET = process.env.JWT_SECRET || 'test-jwt-secret';
process.env.ADMIN_JWT_SECRET = process.env.ADMIN_JWT_SECRET || 'test-admin-jwt-secret';
process.env.APP_KEYS =
process.env.APP_KEYS || 'testKey1,testKey2,testKey3,testKey4';
if (fs.existsSync(dbFile)) {
fs.rmSync(dbFile);
}
const appContext = await compileStrapi();
strapi = createStrapi(appContext);
strapi.log.level = 'error';
await strapi.start();
request = supertest(`http://127.0.0.1:${process.env.PORT}`);
await ensurePublicPermissions(strapi, [
'api::checkbox-item.checkbox-item.find',
'api::checkbox-item.checkbox-item.findOne',
'api::checkbox-item.checkbox-item.create',
'api::checkbox-item.checkbox-item.update',
'api::checkbox-item.checkbox-item.delete',
]);
});
afterAll(async () => {
if (strapi) {
await strapi.destroy();
}
});
test('creates and reads entries with checkbox list values', async () => {
const createResponse = await request.post('/api/checkbox-items').send({
data: {
title: 'First',
choices: ['alpha', 'beta'],
choicesRequired: ['alpha'],
choicesPrivate: ['secret'],
choicesDefault: ['defaultA'],
},
});
expect([200, 201]).toContain(createResponse.status);
const documentId = createResponse.body?.data?.documentId;
expect(documentId).toBeTruthy();
const fetchResponse = await request.get(`/api/checkbox-items/${documentId}`);
expect(fetchResponse.status).toBe(200);
expect(fetchResponse.body?.data?.choices).toEqual(['alpha', 'beta']);
});
test('enforces required checkbox list field', async () => {
const response = await request.post('/api/checkbox-items').send({
data: {
title: 'Missing required',
choices: ['alpha'],
},
});
expect(response.status).toBe(400);
});
test('applies default values and hides private field', async () => {
const createResponse = await request.post('/api/checkbox-items').send({
data: {
title: 'Defaults',
choices: ['beta'],
choicesRequired: ['beta'],
},
});
expect([200, 201]).toContain(createResponse.status);
const documentId = createResponse.body?.data?.documentId;
expect(documentId).toBeTruthy();
const fetchResponse = await request.get(`/api/checkbox-items/${documentId}`);
expect(fetchResponse.status).toBe(200);
const data = fetchResponse.body?.data;
expect(data?.choicesDefault).toEqual(['defaultA']);
expect(data?.choicesPrivate).toBeUndefined();
});
test('updates entries with checkbox list values', async () => {
const createResponse = await request.post('/api/checkbox-items').send({
data: {
title: 'Update me',
choices: ['alpha'],
choicesRequired: ['alpha'],
},
});
const documentId = createResponse.body?.data?.documentId;
expect(documentId).toBeTruthy();
const updateResponse = await request.put(`/api/checkbox-items/${documentId}`).send({
data: {
choices: ['alpha', 'gamma'],
choicesRequired: ['alpha'],
},
});
expect(updateResponse.status).toBe(200);
expect(updateResponse.body?.data?.choices).toEqual(['alpha', 'gamma']);
});
});

View File

@@ -503,6 +503,57 @@ export interface ApiCategoryCategory extends Struct.CollectionTypeSchema {
};
}
export interface ApiCheckboxItemCheckboxItem extends Struct.CollectionTypeSchema {
collectionName: 'checkbox_items';
info: {
description: 'Content type for checkbox list integration tests';
displayName: 'Checkbox Item';
pluralName: 'checkbox-items';
singularName: 'checkbox-item';
};
options: {
draftAndPublish: false;
};
attributes: {
choices: Schema.Attribute.CustomField<
'plugin::checkbox-list.checkbox-list',
{
enum: ['alpha', 'beta', 'gamma'];
}
>;
choicesDefault: Schema.Attribute.CustomField<
'plugin::checkbox-list.checkbox-list',
{
enum: ['defaultA', 'defaultB'];
}
> &
Schema.Attribute.DefaultTo<['defaultA']>;
choicesPrivate: Schema.Attribute.CustomField<
'plugin::checkbox-list.checkbox-list',
{
enum: ['secret', 'top-secret'];
}
> &
Schema.Attribute.Private;
choicesRequired: Schema.Attribute.CustomField<
'plugin::checkbox-list.checkbox-list',
{
enum: ['alpha', 'beta'];
}
> &
Schema.Attribute.Required;
createdAt: Schema.Attribute.DateTime;
createdBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> & Schema.Attribute.Private;
locale: Schema.Attribute.String & Schema.Attribute.Private;
localizations: Schema.Attribute.Relation<'oneToMany', 'api::checkbox-item.checkbox-item'> &
Schema.Attribute.Private;
publishedAt: Schema.Attribute.DateTime;
title: Schema.Attribute.String & Schema.Attribute.Required;
updatedAt: Schema.Attribute.DateTime;
updatedBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> & Schema.Attribute.Private;
};
}
export interface ApiGlobalGlobal extends Struct.SingleTypeSchema {
collectionName: 'globals';
info: {
@@ -963,6 +1014,7 @@ declare module '@strapi/strapi' {
'api::article.article': ApiArticleArticle;
'api::author.author': ApiAuthorAuthor;
'api::category.category': ApiCategoryCategory;
'api::checkbox-item.checkbox-item': ApiCheckboxItemCheckboxItem;
'api::global.global': ApiGlobalGlobal;
'plugin::content-releases.release': PluginContentReleasesRelease;
'plugin::content-releases.release-action': PluginContentReleasesReleaseAction;