Skip to content

Commit bc5c2a2

Browse files
committed
feat: @vllnt/convex-reactions 0.1.0 — reactions / votes / likes on any resource
Sandboxed type-A Convex component: reactions / votes / likes on any resource. Owns its own tables; host data via typed / host-supplied validators; explicit args+returns on every function; 100% E2E coverage. Built to the vllnt fleet Universal + component-only standard (convex ^1.41 / vitest ^4), mirrored from convex-async-operations.
0 parents  commit bc5c2a2

55 files changed

Lines changed: 8590 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/FUNDING.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
github: bntvllnt

.github/ISSUE_TEMPLATE/bug.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: Bug Report
2+
description: Report a bug in @vllnt/convex-reactions
3+
labels: ["bug"]
4+
body:
5+
- type: textarea
6+
id: description
7+
attributes:
8+
label: Description
9+
description: A clear description of the bug.
10+
validations:
11+
required: true
12+
- type: textarea
13+
id: repro
14+
attributes:
15+
label: Minimal Reproduction
16+
description: Code or steps to reproduce the issue.
17+
render: typescript
18+
validations:
19+
required: true
20+
- type: input
21+
id: package-version
22+
attributes:
23+
label: Package Version
24+
placeholder: "0.1.0"
25+
validations:
26+
required: true
27+
- type: input
28+
id: convex-version
29+
attributes:
30+
label: Convex Version
31+
placeholder: "1.41.0"
32+
validations:
33+
required: true

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
blank_issues_enabled: false
2+
contact_links:
3+
- name: Discord
4+
url: https://bntvllnt.com/discord
5+
about: Ask questions and get help on Discord.
6+
- name: X / Twitter
7+
url: https://bntvllnt.com/x
8+
about: Follow @bntvllnt for updates.

.github/ISSUE_TEMPLATE/feature.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Feature Request
2+
description: Suggest a new feature or improvement
3+
labels: ["enhancement"]
4+
body:
5+
- type: textarea
6+
id: problem
7+
attributes:
8+
label: Problem / Motivation
9+
description: What problem does this solve?
10+
validations:
11+
required: true
12+
- type: textarea
13+
id: solution
14+
attributes:
15+
label: Proposed Solution
16+
description: How should this work?
17+
validations:
18+
required: true
19+
- type: textarea
20+
id: alternatives
21+
attributes:
22+
label: Alternatives Considered
23+
description: What other approaches did you consider?
24+
validations:
25+
required: false

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
## Summary
2+
3+
<!-- What does this PR do and why? -->
4+
5+
## Checklist
6+
7+
- [ ] Tests added/updated (100% coverage maintained)
8+
- [ ] `pnpm typecheck` passes
9+
- [ ] `pnpm lint` passes
10+
- [ ] `pnpm test:coverage` passes
11+
- [ ] CHANGELOG updated (if user-facing)

.github/workflows/ci.yml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
lint:
15+
name: Lint
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v4
19+
- uses: pnpm/action-setup@v4
20+
- uses: actions/setup-node@v4
21+
with:
22+
node-version: 20
23+
cache: pnpm
24+
- run: pnpm install --frozen-lockfile
25+
- run: pnpm lint
26+
27+
typecheck:
28+
name: Typecheck
29+
runs-on: ubuntu-latest
30+
steps:
31+
- uses: actions/checkout@v4
32+
- uses: pnpm/action-setup@v4
33+
- uses: actions/setup-node@v4
34+
with:
35+
node-version: 20
36+
cache: pnpm
37+
- run: pnpm install --frozen-lockfile
38+
- run: pnpm typecheck:ci
39+
40+
test:
41+
name: Test
42+
runs-on: ubuntu-latest
43+
steps:
44+
- uses: actions/checkout@v4
45+
- uses: pnpm/action-setup@v4
46+
- uses: actions/setup-node@v4
47+
with:
48+
node-version: 20
49+
cache: pnpm
50+
- run: pnpm install --frozen-lockfile
51+
# Enforces the 100% coverage gate (thresholds live in vitest.config.mts).
52+
- run: pnpm test:coverage
53+
54+
build:
55+
name: Build
56+
runs-on: ubuntu-latest
57+
steps:
58+
- uses: actions/checkout@v4
59+
- uses: pnpm/action-setup@v4
60+
- uses: actions/setup-node@v4
61+
with:
62+
node-version: 20
63+
cache: pnpm
64+
- run: pnpm install --frozen-lockfile
65+
- run: pnpm build

.github/workflows/email-guard.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Email Guard
2+
# Fails the PR if any commit author OR committer email is not an allowed GitHub no-reply.
3+
# Add this job's check ("Commit email privacy") to the branch's required status checks so a
4+
# leaking commit can never reach the default branch.
5+
6+
on:
7+
pull_request:
8+
9+
jobs:
10+
email-guard:
11+
name: Commit email privacy
12+
runs-on: ubuntu-latest
13+
env:
14+
# Exact account only ("only my account"):
15+
ALLOWED_EMAIL_PATTERN: '^32437578\+bntvllnt@users\.noreply\.github\.com$'
16+
steps:
17+
- uses: actions/checkout@v4
18+
with:
19+
fetch-depth: 0
20+
21+
- name: Check commit author/committer emails
22+
run: |
23+
set -euo pipefail
24+
# Validate only the PR's own commits. On a pull_request build HEAD is
25+
# GitHub's synthetic merge commit (committed as noreply@github.com); the
26+
# base.sha..head.sha range excludes it and checks just the pushed commits.
27+
RANGE="${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}"
28+
emails=$(git log --format='%ae%n%ce' "$RANGE" | sort -u)
29+
echo "Emails in range $RANGE:"
30+
echo "$emails" | sed 's/^/ /'
31+
bad=$(echo "$emails" | grep -vE "$ALLOWED_EMAIL_PATTERN" || true)
32+
if [ -n "$bad" ]; then
33+
echo "::error::Disallowed commit email(s) — use your GitHub no-reply address:"
34+
echo "$bad" | while read -r e; do echo "::error:: $e"; done
35+
exit 1
36+
fi
37+
echo "All commit emails are allowed no-reply addresses."

.github/workflows/publish.yml

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
name: Publish
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- "src/**"
8+
- "package.json"
9+
- "pnpm-lock.yaml"
10+
- ".github/workflows/publish.yml"
11+
workflow_dispatch:
12+
inputs:
13+
bump:
14+
description: "Release strategy"
15+
required: true
16+
default: current
17+
type: choice
18+
options:
19+
- current
20+
- patch
21+
- minor
22+
- major
23+
24+
concurrency:
25+
group: publish-${{ github.event_name }}
26+
cancel-in-progress: true
27+
28+
permissions:
29+
contents: write
30+
id-token: write
31+
32+
jobs:
33+
quality:
34+
name: Quality Gates
35+
runs-on: ubuntu-latest
36+
steps:
37+
- uses: actions/checkout@v4
38+
- uses: pnpm/action-setup@v4
39+
- uses: actions/setup-node@v4
40+
with:
41+
node-version: 22
42+
cache: pnpm
43+
- run: pnpm install --frozen-lockfile
44+
- run: pnpm lint
45+
- run: pnpm typecheck:ci
46+
- run: pnpm test:coverage
47+
- run: pnpm build
48+
49+
canary:
50+
name: Publish Canary
51+
needs: quality
52+
if: github.event_name == 'push'
53+
runs-on: ubuntu-latest
54+
permissions:
55+
id-token: write
56+
contents: read
57+
steps:
58+
- uses: actions/checkout@v4
59+
- uses: pnpm/action-setup@v4
60+
- uses: actions/setup-node@v4
61+
with:
62+
node-version: 22
63+
cache: pnpm
64+
registry-url: https://registry.npmjs.org
65+
- run: pnpm install --frozen-lockfile
66+
- run: pnpm build
67+
- name: Publish canary
68+
run: |
69+
sed -i '/_authToken/d' "$NPM_CONFIG_USERCONFIG"
70+
unset NODE_AUTH_TOKEN
71+
72+
BASE_VERSION=$(node -p "require('./package.json').version")
73+
SHORT_SHA=$(echo "$GITHUB_SHA" | cut -c1-7)
74+
CANARY_VERSION="${BASE_VERSION}-canary.${SHORT_SHA}"
75+
npm version "$CANARY_VERSION" --no-git-tag-version --ignore-scripts
76+
npx -y npm@11 publish --tag canary --provenance --access public --ignore-scripts
77+
78+
release:
79+
name: Publish Release
80+
needs: quality
81+
if: github.event_name == 'workflow_dispatch'
82+
runs-on: ubuntu-latest
83+
permissions:
84+
contents: write
85+
id-token: write
86+
steps:
87+
- uses: actions/checkout@v4
88+
with:
89+
fetch-depth: 0
90+
token: ${{ github.token }}
91+
- uses: pnpm/action-setup@v4
92+
- uses: actions/setup-node@v4
93+
with:
94+
node-version: 22
95+
cache: pnpm
96+
registry-url: https://registry.npmjs.org
97+
- run: pnpm install --frozen-lockfile
98+
- run: pnpm build
99+
100+
- name: Prepare version
101+
id: version
102+
run: |
103+
if [ "${{ inputs.bump }}" = "current" ]; then
104+
VERSION=$(node -p "require('./package.json').version")
105+
else
106+
npm version ${{ inputs.bump }} --no-git-tag-version --ignore-scripts
107+
VERSION=$(node -p "require('./package.json').version")
108+
fi
109+
110+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
111+
112+
- name: Generate changelog
113+
id: changelog
114+
run: |
115+
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
116+
if [ -z "$LAST_TAG" ]; then
117+
RANGE="HEAD"
118+
else
119+
RANGE="${LAST_TAG}..HEAD"
120+
fi
121+
122+
{
123+
echo "body<<CHANGELOG_EOF"
124+
125+
FEATS=$(git log "$RANGE" --pretty=format:"%s" --grep="^feat" 2>/dev/null || true)
126+
if [ -n "$FEATS" ]; then
127+
echo "### Features"
128+
echo "$FEATS" | sed 's/^/- /'
129+
echo ""
130+
fi
131+
132+
FIXES=$(git log "$RANGE" --pretty=format:"%s" --grep="^fix" 2>/dev/null || true)
133+
if [ -n "$FIXES" ]; then
134+
echo "### Bug Fixes"
135+
echo "$FIXES" | sed 's/^/- /'
136+
echo ""
137+
fi
138+
139+
OTHERS=$(git log "$RANGE" --pretty=format:"%s" --invert-grep --grep="^feat" --grep="^fix" 2>/dev/null || true)
140+
if [ -n "$OTHERS" ]; then
141+
echo "### Other Changes"
142+
echo "$OTHERS" | sed 's/^/- /'
143+
echo ""
144+
fi
145+
146+
echo "CHANGELOG_EOF"
147+
} >> "$GITHUB_OUTPUT"
148+
149+
- name: Commit and tag
150+
run: |
151+
VERSION="${{ steps.version.outputs.version }}"
152+
153+
git config user.name "github-actions[bot]"
154+
git config user.email "github-actions[bot]@users.noreply.github.com"
155+
156+
if git rev-parse "refs/tags/v$VERSION" >/dev/null 2>&1; then
157+
echo "Tag v$VERSION already exists"
158+
exit 1
159+
fi
160+
161+
if ! git diff --quiet -- package.json; then
162+
git add package.json
163+
git commit -m "chore(release): v$VERSION"
164+
git push origin main
165+
fi
166+
167+
git tag -a "v$VERSION" -m "v$VERSION"
168+
git push origin "v$VERSION"
169+
170+
- name: Publish to npm
171+
run: |
172+
sed -i '/_authToken/d' "$NPM_CONFIG_USERCONFIG"
173+
unset NODE_AUTH_TOKEN
174+
npx -y npm@11 publish --tag latest --provenance --access public --ignore-scripts
175+
176+
- name: Create GitHub Release
177+
env:
178+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
179+
run: |
180+
gh release create "v${{ steps.version.outputs.version }}" \
181+
--title "@vllnt/convex-reactions v${{ steps.version.outputs.version }}" \
182+
--notes "${{ steps.changelog.outputs.body }}"

0 commit comments

Comments
 (0)