npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@zanecoder/zc-sign-editor

v0.1.11

Published

Embeddable ZC Sign field editor and send shell for host apps (e.g. Retail Origination)

Readme

@zanecoder/zc-sign-editor

Embeddable Vue Send Document UI for host apps (Retail Origination, etc.). Upload a PDF, add recipients, place signature / initials / date fields, and prepare a send payload — without an iframe.

UI matches zc-sign’s send page. Creating a signing session still goes through the zc-sign backend. This package only prepares the document; your host BFF talks to zc-sign.

Source: github.com/zaneCoder/zc-sign-fe → packages/zc-sign-editor

Changelog (recent)

0.1.10

  • Bug fix: PDF field placement stays aligned after scroll/zoom (fields stored in base viewport coords).
  • Bug fix: Adjust Field Sizes resizes placed fields; removed hidden second PDF load that caused OOM on large docs.

0.1.9

  • Multi-signer / sequential: Only the active signer’s fields can be dragged (other signers’ fields stay red / click-to-reassign). New drops follow Assign new fields to. Preview pageLayouts sync into prepare so metadata ownership matches /send.

0.1.8

  • Feature: Click a placed field on the PDF → Selected field assignee appears in the sidebar so you can move that field to another signer (was broken: selection lived only inside the nested editor).

0.1.7

  • Bug fix: Dragging Signature / Initials / Date onto the PDF no longer hangs the browser tab (“Aw, Snap!”). Field (and recipient) v-model sync now uses equality guards so Vue cannot infinite-loop updates between ZcSignSend and ZcSignEditor.

0.1.6

  • Optional host theme (forwarded into editor empty state + chrome)
  • Sharper HiDPI PDF preview without shifting field coordinates

Do I need integration keys?

Yes for the overall flow — but not inside this SDK / not in the browser.

| | Needs keys? | Where | | --- | --- | --- | | This package (ZcSignSend) | No | Browser Vue UI only | | Your host BFF / server | Yes | Server env only | | zc-sign API | Validates keys | POST /api/integration/send-document |

Host server env:

| Env | Used for | | --- | --- | | ZC_SIGN_PUBLIC_KEY | Header ZC-SIGN-PUB-KEY | | ZC_SIGN_SECRET_KEY | Header ZC-SIGN-SECRET-KEY | | ZC_SIGN_API_URL | zc-sign API base URL | | ZC_SIGN_FRONTEND_URL | Signer links |

Never put pub/secret keys in this package, Vue client code, or NUXT_PUBLIC_* / Vite VITE_* vars.

How it works

Host UI (Retail, etc.)
  └─ <ZcSignSend />                 ← this package
       • pick PDF, recipients, fields
       • tokenize PDF (@signature#id, …)
       • build metadata JSON
       └─ submit(payload)           ← you provide this callback
            └─ Host BFF             ← auth + server keys
                 • upload PDF
                 • POST zc-sign /api/integration/send-document
                      headers: ZC-SIGN-PUB-KEY, ZC-SIGN-SECRET-KEY
                 └─ session uuid
Signers open zc-sign FE
  /signature-signing?session=…&email=…
Webhook → your host (e.g. /api/webhooks/zc-sign)

| Layer | Responsibility | | --- | --- | | SDK (ZcSignSend) | UI, place fields, prepare PDF + metadata, call submit | | Host BFF | Auth, storage, call zc-sign with server keys, save session | | zc-sign BE | Session, emails, signing order, completed PDF | | zc-sign FE | Actual signing experience (not this package) |

What this SDK prepares

  • Tokenized PDF (@signature#id, @initials#id, @date#id baked in)
  • Recipient list + field layout / size metadata (integration FormData shape)

What stays on zc-sign

  • Session UUID, signing links, email queue, sequential / parallel delivery
  • Signer UI, completed PDF, webhooks back to your host

If you omit the submit prop, the SDK only emits a prepared event — still no keys; your app must send to the BFF afterward.

Install

npm install @zanecoder/zc-sign-editor

Peer dependency: Vue ^3.4.

import { ZcSignSend, ZcSignEditor } from '@zanecoder/zc-sign-editor'
import '@zanecoder/zc-sign-editor/style.css'

Quick usage

<script setup lang="ts">
import { ref } from 'vue'
import { ZcSignSend, createRecipient } from '@zanecoder/zc-sign-editor'
import type { ZcSignPreparedSend, ZcSignRecipient, ZcSignSendResult } from '@zanecoder/zc-sign-editor'
import '@zanecoder/zc-sign-editor/style.css'

const recipients = ref<ZcSignRecipient[]>([createRecipient(1)])

async function submit(payload: ZcSignPreparedSend): Promise<ZcSignSendResult> {
  // Browser → your BFF only (never call zc-sign with secret from the client)
  const form = new FormData()
  form.append('file', payload.pdf, payload.documentName || 'document.pdf')
  form.append('metadata', JSON.stringify(payload.metadata))
  form.append('documentName', payload.documentName)
  form.append('subject', payload.subject)
  form.append('message', payload.message)
  form.append('signingMode', payload.signingMode)

  const res = await fetch('/api/your-create-signing-session', {
    method: 'POST',
    body: form,
  })
  return res.json()
}
</script>

<template>
  <ZcSignSend v-model:recipients="recipients" :submit="submit" />
</template>

ZcSignSend props

| Prop | Type | Default | Description | | --- | --- | --- | --- | | recipients | ZcSignRecipient[] | required | Signers / viewers (use v-model:recipients) | | submit | (payload) => Promise<ZcSignSendResult> | — | Host callback; if omitted, only prepared is emitted | | file | File \| null | null | Optional preloaded PDF | | documentName | string | '' | Document title | | subject | string | '' | Email subject | | message | string | '' | Email message | | signingMode | 'default' \| 'sequential' \| 'parallel' | 'sequential' | Signing order mode | | initialFields | ZcSignField[] | [] | Pre-placed fields |

Also supports v-model:documentName, v-model:message, v-model:signingMode, v-model:fields.

ZcSignSend events

| Event | Payload | When | | --- | --- | --- | | prepared | ZcSignPreparedSend | PDF + metadata ready (always before/alongside send) | | sent | ZcSignSendResult \| ZcSignPreparedSend | After submit resolves, or prepared-only flow | | cancel | — | User cancels | | error | { code: string; message: string } | Prepare / submit failure | | update:recipients | ZcSignRecipient[] | Recipients changed | | update:fields | ZcSignField[] | Fields changed | | update:documentName | string | Name changed | | update:message | string | Message changed | | update:signingMode | ZcSignSigningMode | Mode changed |

ZcSignPreparedSend shape

What submit / prepared receive:

interface ZcSignPreparedSend {
  pdf: Blob                 // tokenized PDF (not the original upload alone)
  documentName: string
  subject: string
  message: string
  signingMode: 'default' | 'sequential' | 'parallel'
  recipients: ZcSignRecipient[]
  metadata: ZcSignMetadataItem[]  // per-recipient field layouts for zc-sign
  fields: ZcSignField[]           // editor field list
}

interface ZcSignRecipient {
  id: string
  name: string
  email: string
  signeeType: 'signer' | 'viewer' | 'approver' | 'client'
}

interface ZcSignMetadataItem {
  name: string
  email: string
  signee_type: ZcSignRecipient['signeeType']
  signing_order: number
  field_sizes: Record<'signature' | 'initials' | 'date', { width: number; height: number }>
  field_ids: string[]
  field_layouts: ZcSignFieldLayout[]
  signatory_variable?: '@signature'
  initial_variable?: '@initials'
  date_variable?: '@date'
}

Helper: appendZcSignMetadata(formData, payload.metadata) appends the metadata field your BFF / zc-sign expect.

Host BFF checklist

Use this on the server (Retail, etc.):

  1. Auth the logged-in user before accepting the upload
  2. Accept PDF (payload.pdf) + metadata JSON (+ name / subject / message / mode)
  3. Store the PDF (your storage / bucket) if required by your app
  4. Call zc-sign:
POST {ZC_SIGN_API_URL}/api/integration/send-document
ZC-SIGN-PUB-KEY: {ZC_SIGN_PUBLIC_KEY}
ZC-SIGN-SECRET-KEY: {ZC_SIGN_SECRET_KEY}
Content-Type: multipart/form-data
  1. Persist returned session uuid / signing links in your DB
  2. Return { sessionUuid } (or your shape) to the SDK submit promise
  3. Handle webhooks from zc-sign when signing completes

| Do | Don't | | --- | --- | | Keep keys in server env / secrets manager | Put keys in the Vue app or this SDK | | Send FormData from browser → your BFF only | Call zc-sign directly from the browser with the secret | | Validate recipients + PDF size / type on BFF | Trust client-only checks |

Exports

| Export | Role | | --- | --- | | ZcSignSend | Full send shell (recipients + field placement) | | ZcSignEditor | Field editor surface alone | | useZcSignSend / useZcSignEditor | Composables for custom UIs | | createRecipient | Build a default recipient row | | prepareZcSignPdf | Bake field tokens into the PDF | | buildZcSignMetadata / appendZcSignMetadata | Build / attach integration metadata | | configurePdfJsWorker | Optional PDF.js worker override | | resolveZcSignThemeStyle / ZcSignTheme | Optional host brand colors for Send / Editor |

Styles: @zanecoder/zc-sign-editor/style.css

Theme (optional)

Pass any valid CSS colors (including host tokens like hsl(var(--company-primary))):

<ZcSignSend
  :recipients="recipients"
  :theme="{
    primary: 'hsl(var(--company-primary))',
    primaryHover: 'hsl(var(--company-secondary))',
    background: 'hsl(var(--company-background))',
    border: 'hsl(var(--company-border-soft) / 0.35)',
    contrast: 'hsl(var(--company-primary-contrast))',
  }"
  :submit="submitPrepared"
/>

Keys: primary, primaryHover, accent, background, border, contrast.
If theme is omitted (or a key is blank), the built-in zc-sign palette is used (ZC_SIGN_DEFAULT_THEME).
ZcSignSend forwards theme into the nested ZcSignEditor (empty state + document preview chrome).

FAQ

| Question | Answer | | --- | --- | | Does create-session go through zc-sign? | Yes — via your host BFF | | Does the SDK need integration keys? | No — only your server does | | Keys in the browser? | Never | | Iframe? | No — native Vue components | | Where do signers sign? | zc-sign FE, not inside this package | | Can I use helpers without the UI? | Yes — prepareZcSignPdf, metadata utils, composables | | PDF preview “Cannot read from private field”? | Fixed in 0.1.4+ — single host pdfjs-dist + non-reactive PDF.js handles; upgrade the package | | Worker “Failed to fetch … jsdelivr …”? | Use a same-origin worker (?url or /pdfjs/pdf.worker.min.mjs); fixed default in 0.1.5+ | | PDF preview looks blurry on Retina? | Preview paints at capped devicePixelRatio; field coords stay CSS pixels — rebuild/upgrade after HiDPI canvas fix | | Tab hangs / “Aw, Snap!” when dragging Signature/Date fields? | Fixed in 0.1.7+ — field (and recipient) prop sync used to infinite-loop Vue updates; upgrade and pin ^0.1.7 | | Can’t change which signer owns a placed field? | Fixed in 0.1.8+ — click the field, then use Selected field assignee in the sidebar | | Signer 1 can place/move Signer 2’s fields? | Fixed in 0.1.9+ — use Assign new fields to; other signers’ fields are locked (click to reassign only) |

PDF.js worker

Under Nuxt, prefer a same-origin Nitro/static worker URL via configurePdfJsWorker('/api/…/pdf-worker'). Vite ?worker is often broken by dep optimization (missing default export); CDN and workerSrc pointing at node_modules / @fs often fail too.

Retail: app/utils/signing/setupZcSignPdfJsWorker.ts (called from CreateSigningSessionPanel).

import * as pdfjsLib from 'pdfjs-dist'
import PdfWorker from 'pdfjs-dist/build/pdf.worker.min.mjs?worker'
import { configurePdfJsWorker } from '@zanecoder/zc-sign-editor'

pdfjsLib.GlobalWorkerOptions.workerPort = new PdfWorker()
configurePdfJsWorker()

Call this on the client before mounting ZcSignSend.

Links

| | | | --- | --- | | npm | https://www.npmjs.com/package/@zanecoder/zc-sign-editor | | GitHub | https://github.com/zaneCoder/zc-sign-fe/tree/developv3/packages/zc-sign-editor | | How it works (detail) | docs/how-it-works.md | | SDK overview | docs/zc-sign-send-sdk.md | | Publish / versioning | docs/publish.md |

License

UNLICENSED — internal / proprietary use under Zanecoder.