{"_id":"@021.is/spine-actions","_rev":"2-491b036809e65ba26befde194e5e037a","name":"@021.is/spine-actions","dist-tags":{"latest":"0.4.3"},"versions":{"0.4.0":{"name":"@021.is/spine-actions","version":"0.4.0","license":"MIT","_id":"@021.is/spine-actions@0.4.0","maintainers":[{"name":"edvone","email":"edvard@edvone.dev"}],"homepage":"https://github.com/021is/spine-ts#readme","bugs":{"url":"https://github.com/021is/spine-ts/issues"},"dist":{"shasum":"fc6b57d3078b675b2ae9a5753e1ee518c5e9d008","tarball":"https://registry.npmjs.org/@021.is/spine-actions/-/spine-actions-0.4.0.tgz","fileCount":4,"integrity":"sha512-OTE8ytBwrJWKm3SC9GUxQ2Scgh+igwZI6yagzL0kPM8rZq5/hGDJ56fsaw8ZsTRgkTlflgccbXFtkJg1IvX0ww==","signatures":[{"sig":"MEYCIQCsJC5r8zklZGkVbMvRB55Z9F4b4mvsYB/TKrVzXidg1wIhAIiGP7rZ9m4HVES5X7WFgQiEK6dg7u2K5RH2qDENm3gK","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":5986},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"e4434c6f59db8f586e0f05ffdb3b88a96e68e67b","scripts":{"build":"tsup src/index.ts --format esm --dts --clean","typecheck":"tsc --noEmit"},"_npmUser":{"name":"edvone","email":"edvard@edvone.dev"},"repository":{"url":"git+https://github.com/021is/spine-ts.git","type":"git","directory":"packages/actions"},"_npmVersion":"10.9.4","description":"Type-safe server-action helper: zod input validation + auth check + audit + auto revalidatePath, returning ResponseDto.","directories":{},"_nodeVersion":"22.22.0","dependencies":{"zod":"^3.23.8","@021.is/spine-errors":"^0.4.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/spine-actions_0.4.0_1779981926109_0.876263720460035","host":"s3://npm-registry-packages-npm-production"}},"0.4.3":{"name":"@021.is/spine-actions","version":"0.4.3","license":"MIT","description":"Type-safe server-action helper: zod input validation + auth check + audit + auto revalidatePath, returning ResponseDto.","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"build":"tsup src/index.ts --format esm --dts --clean","typecheck":"tsc --noEmit"},"dependencies":{"@021.is/spine-errors":"^0.4.3","zod":"^3.23.8"},"repository":{"type":"git","url":"git+https://github.com/021is/spine-ts.git","directory":"packages/actions"},"publishConfig":{"access":"public"},"_id":"@021.is/spine-actions@0.4.3","gitHead":"b9f9333776fa55686cc2feb05f851aa6000b0e05","bugs":{"url":"https://github.com/021is/spine-ts/issues"},"homepage":"https://github.com/021is/spine-ts#readme","_nodeVersion":"22.22.0","_npmVersion":"10.9.4","dist":{"integrity":"sha512-DAV8Qjz3AfiNu9G/FNEZgZDgiruzqnJYsyVFly0xfglF/RprbC4n+ZDa8wwZ4bIW3NWkNYvFAEnJR7MahwaONQ==","shasum":"a9a18875f103d5a2db9fc346a877671926126159","tarball":"https://registry.npmjs.org/@021.is/spine-actions/-/spine-actions-0.4.3.tgz","fileCount":5,"unpackedSize":7730,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCICi2ccyBdwzX/T0CsIuQeTPh0wELejP1UuPVrhhwmLvcAiB34MngNbv7aycgMomAc45cMEBZBuzQ1mrPWUHpoelbZg=="}]},"_npmUser":{"name":"edvone","email":"edvard@edvone.dev"},"directories":{},"maintainers":[{"name":"edvone","email":"edvard@edvone.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/spine-actions_0.4.3_1779995220252_0.2898364152327675"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-28T15:25:25.980Z","modified":"2026-05-28T19:07:00.506Z","0.4.0":"2026-05-28T15:25:26.254Z","0.4.3":"2026-05-28T19:07:00.398Z"},"bugs":{"url":"https://github.com/021is/spine-ts/issues"},"license":"MIT","homepage":"https://github.com/021is/spine-ts#readme","repository":{"type":"git","url":"git+https://github.com/021is/spine-ts.git","directory":"packages/actions"},"description":"Type-safe server-action helper: zod input validation + auth check + audit + auto revalidatePath, returning ResponseDto.","maintainers":[{"name":"edvone","email":"edvard@edvone.dev"}],"readme":"# @021.is/spine-actions\n\nType-safe server-action helper. Bakes zod input validation + auth + audit + `revalidatePath` into one wrapper. Always returns `ResponseDto<T | null>`.\n\n## Use\n\n```ts\n\"use server\";\nimport { defineAction } from \"@021.is/spine-actions\";\nimport { z } from \"zod\";\nimport { requireUser } from \"@/lib/auth\";\nimport { publishEvent } from \"@/feature/event\";\n\nexport const publishEventAction = defineAction({\n  input: z.object({ eventId: z.string().min(1) }),\n  auth: requireUser,\n  audit: (input, principal) => ({\n    action: \"event.publish\",\n    targetId: input.eventId,\n    actorId: principal.sub,\n  }),\n  auditor: async (row) => db.audit.create({ data: row }),\n  revalidate: (input) => [`/events/${input.eventId}`, \"/events\"],\n  onRevalidate: revalidatePath,\n  handler: async ({ input, principal }) => publishEvent(input, { userId: principal.sub }),\n}).run;\n```\n\nWhat the wrapper does in order: parse zod → run `auth` → run `handler` → audit on success → call `onRevalidate` for every returned path → wrap result in `ok(...)`. Any thrown spine-errors exception (`BadRequestException`, `ForbiddenException`, etc.) maps to the correct `ResponseDto` envelope.\n\n## Why\n\n- One pattern for every server action across your app\n- Zod parsing failures become `400 BadRequest` with translation keys, not raw stack traces\n- Audit happens only on success (no half-states)\n- Revalidation hook makes \"force-dynamic\" pages refresh after writes\n- Tested in isolation: `await action.run({ ... })` returns a typed `ResponseDto`, no Next.js context needed\n","readmeFilename":"README.md"}