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

@logic-joe/logicforms-api

v0.0.35

Published

API client for LogicForms - TypeScript client for the LogicForms REST API

Readme

@logic-joe/logicforms-api

npm version License: MIT

TypeScript API client for the LogicForms REST API. A lightweight, fetch-based client with full type safety.

Installation

npm install @logic-joe/logicforms-api
# or
pnpm add @logic-joe/logicforms-api
# or
yarn add @logic-joe/logicforms-api

Quick Start

import { createFormServiceClient } from "@logic-joe/logicforms-api";

// Create a client
const client = createFormServiceClient({
  baseUrl: "https://logicforms.onrender.com",
  apiKey: "your-api-key",
});

// Get a published form
const form = await client.getFormPublic({ id: "form_abc123" });
console.log(form.name, form.fields);

// Submit form data
const result = await client.submitForm({
  formId: "form_abc123",
  data: {
    email: "[email protected]",
    name: "John Doe",
  },
});
console.log("Submission ID:", result.submissionId);

API Reference

createFormServiceClient(options)

Creates a new API client instance.

interface CreateClientOptions {
  baseUrl?: string; // Default: "https://logicforms.onrender.com"
  apiKey?: string; // Your API key
  credentials?: RequestCredentials; // Default: "omit"
}

Client Methods

getFormPublic({ id, locale? })

Fetches a published form by ID.

const form = await client.getFormPublic({
  id: "form_abc123",
  locale: "de", // Optional: request specific language
});

// Response
interface GetFormPublicResponse {
  id: string;
  name: string;
  description: string;
  fields: FormField[];
  layout: FormBlock[];
  settings: FormSettings;
  customCss: string;
  locale?: string; // Current locale
  sourceLocale?: string; // Original language
  availableLocales?: string[]; // All available translations
}

submitForm({ formId, data })

Submits form data.

const result = await client.submitForm({
  formId: "form_abc123",
  data: { email: "[email protected]" },
});

// Response
interface SubmitFormResponse {
  success: boolean;
  submissionId: string;
}

getUploadUrl(params)

Gets a presigned URL for file upload (quarantine bucket).

const upload = await client.getUploadUrl({
  formId: "form_abc123",
  fieldId: "field_xyz",
  filename: "document.pdf",
  contentType: "application/pdf",
  fileSize: 1024000,
});

// Response
interface GetUploadUrlResponse {
  fileId: string;
  uploadUrl: string;
}

confirmUploadComplete({ fileId })

Confirms file upload and triggers antivirus scan.

await client.confirmUploadComplete({ fileId: "file_123" });

getFileStatus({ fileId })

Gets current file scan status.

const status = await client.getFileStatus({ fileId: "file_123" });

// Response
interface FileStatusResponse {
  fileId: string;
  status: FileStatus; // "pending_upload" | "pending_scan" | "scanning" | "clean" | "infected" | "scan_failed"
  filename?: string;
}

getDownloadUrl({ fileId })

Gets a presigned download URL (only for clean files).

const download = await client.getDownloadUrl({ fileId: "file_123" });

// Response
interface GetDownloadUrlResponse {
  downloadUrl: string;
  filename: string;
}

File Upload Flow

Complete example of uploading a file with virus scanning:

import { createFormServiceClient } from "@logic-joe/logicforms-api";

const client = createFormServiceClient({ apiKey: "your-key" });

async function uploadFile(file: File, formId: string, fieldId: string) {
  // 1. Get presigned upload URL
  const { fileId, uploadUrl } = await client.getUploadUrl({
    formId,
    fieldId,
    filename: file.name,
    contentType: file.type,
    fileSize: file.size,
  });

  // 2. Upload file directly to S3 (quarantine bucket)
  await fetch(uploadUrl, {
    method: "PUT",
    body: file,
    headers: { "Content-Type": file.type },
  });

  // 3. Confirm upload and trigger AV scan
  await client.confirmUploadComplete({ fileId });

  // 4. Poll for scan result
  let status = await client.getFileStatus({ fileId });
  while (status.status === "pending_scan" || status.status === "scanning") {
    await new Promise((r) => setTimeout(r, 1000));
    status = await client.getFileStatus({ fileId });
  }

  if (status.status === "clean") {
    console.log("File is safe:", fileId);
    return fileId;
  } else {
    throw new Error(`File scan failed: ${status.status}`);
  }
}

Types & Constants

Field Types

import { FieldType } from "@logic-joe/logicforms-api";

FieldType.TEXT; // "TEXT"
FieldType.EMAIL; // "EMAIL"
FieldType.NUMBER; // "NUMBER"
FieldType.TEXTAREA; // "TEXTAREA"
FieldType.SELECT; // "SELECT"
FieldType.CHECKBOX; // "CHECKBOX"
FieldType.RADIO; // "RADIO"
FieldType.DATE; // "DATE"
FieldType.FILE; // "FILE"

Block Types

import { BlockType } from "@logic-joe/logicforms-api";

BlockType.FIELD; // "FIELD"
BlockType.HEADING; // "HEADING"
BlockType.TEXT; // "TEXT"
BlockType.DIVIDER; // "DIVIDER"
BlockType.ROW; // "ROW"

Core Interfaces

interface FormField {
  id: string;
  name: string;
  label: string;
  type: FieldType;
  required: boolean;
  placeholder: string;
  defaultValue: string;
  options: FieldOption[];
  validation: Record<string, string>;
  order: number;
}

interface FormBlock {
  id: string;
  type: BlockType;
  fieldId?: string;
  content?: string;
  level?: number;
  columns?: number;
  children?: FormBlock[];
}

interface FormSettings {
  submitButtonText: string;
  successMessage: string;
  redirectUrl: string;
  submitAction?: "message" | "redirect";
  theme?: ThemeSettings;
  honeypotEnabled?: boolean;
  recaptcha?: RecaptchaSettings;
  turnstile?: TurnstileSettings;
}

Utility Modules

Date Format Utilities

import {
  toISO,
  fromISO,
  parseDate,
  isValidFormat,
  DATE_FORMATS,
} from "@logic-joe/logicforms-api/dateFormat";

// Convert custom format to ISO
toISO("25/12/2024", "DD/MM/YYYY"); // "2024-12-25"

// Convert ISO to custom format
fromISO("2024-12-25", "DD.MM.YYYY"); // "25.12.2024"

// Parse date string
parseDate("25/12/2024", "DD/MM/YYYY"); // Date object

// Available formats
DATE_FORMATS; // Array of { value, label } options

HTML Sanitization

import { sanitizeHtml, stripHtml } from "@logic-joe/logicforms-api/sanitize";

// Sanitize HTML (keeps safe tags)
sanitizeHtml("<p>Hello <script>bad</script></p>"); // "<p>Hello </p>"

// Strip all HTML tags
stripHtml("<p>Hello <strong>World</strong></p>"); // "Hello World"

Error Handling

import {
  createFormServiceClient,
  ApiClientError,
} from "@logic-joe/logicforms-api";

const client = createFormServiceClient({ apiKey: "your-key" });

try {
  const form = await client.getFormPublic({ id: "invalid" });
} catch (error) {
  if (error instanceof ApiClientError) {
    console.log("Status:", error.statusCode);
    console.log("Message:", error.message);
  }
}

TypeScript Support

This package is written in TypeScript and provides full type definitions. All types are exported:

import type {
  FormField,
  FormBlock,
  FormSettings,
  FieldType,
  BlockType,
  GetFormPublicResponse,
  SubmitFormResponse,
  GetUploadUrlResponse,
  FileStatusResponse,
  ThemeSettings,
  RecaptchaSettings,
  TurnstileSettings,
} from "@logic-joe/logicforms-api";

License

MIT