
Research
/Security News
Malicious npm Packages Target WhatsApp Developers with Remote Kill Switch
Two npm packages masquerading as WhatsApp developer libraries include a kill switch that deletes all files if the phone number isnβt whitelisted.
typesense-ts
Advanced tools
An unofficial Typesense client for Node.js written in TypeScript, designed to be fully typesafe
Β
Β Note: Although I maintain both this library and the main client, this library is unofficial and a passion project. For official support, please refer to the Typesense documentation.
# Using npm
npm install typesense-ts@latest
# Using pnpm
pnpm add typesense-ts@latest
# Using yarn
yarn add typesense-ts@latest
import { configure, setDefaultConfiguration } from "typesense-ts";
// Configure and set as default
setDefaultConfiguration({
apiKey: "xyz",
nodes: [
{ url: "http://localhost:8108" },
// Or specify host/port/protocol separately:
{ host: "example.com", port: 8108, protocol: "https", path: "/typesense" },
],
// Optional parameters
retryIntervalSeconds: 2,
numRetries: 3,
healthcheckIntervalSeconds: 30,
additionalHeaders: { "Custom-Header": "value" },
});
import { collection } from "typesense-ts";
// Define a type-safe collection schema
const booksSchema = collection({
name: "books",
fields: [
{ name: "title", type: "string" },
{ name: "authors", type: "string[]" },
{ name: "publication_year", type: "int32", sort: true },
{ name: "ratings_count", type: "int32", facet: true },
{ name: "average_rating", type: "float", facet: true },
{ name: "categories", type: "string[]", facet: true },
],
default_sorting_field: "publication_year",
});
// Register the collection globally for type safety
declare module "typesense-ts" {
interface Collections {
books: typeof booksSchema.schema;
}
}
// Create the collection in Typesense
await booksSchema.create();
// Type-safe search with full autocomplete and validation
const searchResults = await booksSchema.search({
q: "harry potter",
query_by: ["title", "authors", "categories"], // β
Fully typed field names
sort_by: "average_rating:desc", // β
Compile-time sort validation
filter_by: "publication_year:>=2000 && average_rating:>=4", // β
Filter validation
facet_by: ["categories", "average_rating"], // β
Only facetable fields allowed
group_by: ["categories"], // β
Only facetable fields allowed
page: 1,
per_page: 10,
highlight_fields: ["title", "authors"], // β
Only searchable fields allowed
});
// Access strongly-typed results
searchResults.hits.forEach((hit) => {
console.log(hit.document.title); // β
Typed as string
console.log(hit.document.publication_year); // β
Typed as number
console.log(hit.highlight.title); // β
Access highlighted snippets
});
import { multisearch, multisearchEntry } from "typesense-ts";
const { results } = await multisearch({
searches: [
multisearchEntry({
collection: "books",
q: "harry",
query_by: ["title", "authors"],
filter_by: "average_rating:>=4",
}),
multisearchEntry({
collection: "books",
q: "potter",
query_by: ["title", "authors"],
filter_by: "average_rating:>=4.5",
}),
],
});
// Each result is fully typed based on its collection schema
const firstResults = results[0]; // β
Type-safe access
// Create documents with type safety
await booksSchema.documents.create({
title: "The TypeScript Handbook",
authors: ["Microsoft Team"],
publication_year: 2023,
ratings_count: 1250,
average_rating: 4.8,
categories: ["Programming", "Web Development"],
});
// Bulk import with error handling
try {
const results = await booksSchema.documents.import(
[
{
title: "Book 1",
authors: ["Author 1"],
publication_year: 2023,
ratings_count: 100,
average_rating: 4.5,
categories: ["Fiction"],
},
{
title: "Book 2",
authors: ["Author 2"],
publication_year: 2024,
ratings_count: 200,
average_rating: 4.2,
categories: ["Non-Fiction"],
},
],
{ return_doc: true },
);
console.log(`Imported ${results.length} documents`);
} catch (error) {
if (error.name === "DocumentImportError") {
console.log(`Failed documents:`, error.failedDocuments);
}
}
// Update collection schema
import { validateCollectionUpdate } from "typesense-ts";
const updateFields = validateCollectionUpdate(booksSchema.schema, {
fields: [
{ name: "publisher", type: "string" },
// To drop a field:
{ name: "old_field", drop: true },
],
});
await booksSchema.update(updateFields);
// Retrieve collection info
const collectionInfo = await booksSchema.retrieve();
console.log(`Collection has ${collectionInfo.num_documents} documents`);
import { alias, override } from "typesense-ts";
// Create an alias
const booksAlias = alias({
name: "popular_books",
collection_name: "books",
});
await booksAlias.upsert();
// Create search overrides
const topBooksOverride = override("featured_books", {
collection: "books",
rule: { query: "bestseller", match: "exact" },
includes: [{ id: "book_123", position: 1 }],
remove_matched_tokens: false,
});
await topBooksOverride.upsert();
import { analyticsRule, stopword } from "typesense-ts";
// Create analytics rules
const popularQueriesRule = analyticsRule({
name: "popular_searches",
type: "popular_queries",
params: {
source: { collections: ["books"] },
destination: { collection: "analytics" },
},
});
await popularQueriesRule.upsert();
// Manage stopwords
const commonStopwords = stopword("english_stopwords", {
stopwords: ["the", "and", "or", "but"],
locale: "en",
});
await commonStopwords.upsert();
const config = configure({
apiKey: "your-api-key",
nodes: [
{ url: "http://node1:8108" },
{ host: "node2.example.com", port: 8108, protocol: "https" },
],
nearestNode: { url: "http://nearest:8108" }, // Optional for geo-distributed setups
numRetries: 5, // Number of retries (default: nodes.length + 1)
retryIntervalSeconds: 2, // Delay between retries (default: 1)
healthcheckIntervalSeconds: 60, // Health check interval (default: 60)
connectionTimeoutSeconds: 10, // Connection timeout (default: system)
timeoutSeconds: 30, // Request timeout (default: system)
additionalHeaders: {
// Custom headers
Authorization: "Bearer token",
},
});
// Embedding fields for vector search
const articlesSchema = collection({
name: "articles",
fields: [
{ name: "title", type: "string" },
{ name: "content", type: "string" },
{
name: "title_embedding",
type: "float[]",
embed: {
from: ["title"],
model_config: { model_name: "ts/e5-small" },
},
},
],
});
// Nested objects
const usersSchema = collection({
name: "users",
fields: [
{ name: "name", type: "string" },
{ name: "profile", type: "object" },
{ name: "profile.age", type: "int32" },
{ name: "profile.location", type: "geopoint" },
],
enable_nested_fields: true,
});
// Reference fields for JOINs
const ordersSchema = collection({
name: "orders",
fields: [
{ name: "order_id", type: "string" },
{ name: "user_id", type: "string", reference: "users.id" },
{ name: "total", type: "float" },
],
});
# Clone the repository
git clone https://github.com/yourusername/typesense-ts.git
cd typesense-ts
# Install dependencies
pnpm install
# Start Typesense for development
docker-compose up -d
# Build the library
pnpm build
# Run tests
pnpm test
# Run tests with coverage
pnpm test --coverage
# Type checking
pnpm type-check
# Linting
pnpm lint
# Format code
pnpm format
# Development mode with watch
pnpm dev
The test suite includes integration tests that run against a real Typesense instance:
# Run all tests (starts Typesense automatically)
pnpm test
# Run specific test file
pnpm test tests/search.test.ts
# Run tests in CI mode (skips Docker setup)
CI=true pnpm test
src/
βββ collection/ # Collection schema and operations
βββ document/ # Document CRUD operations
βββ analytics/ # Analytics rules and events
βββ lexer/ # Type-level parsers for filters, sorts, etc.
βββ http/ # HTTP client and request handling
βββ config/ # Configuration management
βββ index.ts # Main exports
tests/ # Test suite
docker-compose.yml # Typesense development instance
tsup.config.ts # Build configuration
We welcome contributions! Please follow these guidelines:
# Create a feature branch
git checkout -b feature/amazing-feature
# Make your changes and add tests
# ...
# Run tests and type checking
pnpm test
pnpm type-check
pnpm lint
# Commit your changes
git commit -m "Add amazing feature"
# Push and create a pull request
git push origin feature/amazing-feature
This project is licensed under the Apache 2.0 License - see the LICENSE file for details.
FAQs
An unofficial Typesense client for Node.js written in TypeScript, designed to be fully typesafe
The npm package typesense-ts receives a total of 433 weekly downloads. As such, typesense-ts popularity was classified as not popular.
We found that typesense-ts demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Β It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
/Security News
Two npm packages masquerading as WhatsApp developer libraries include a kill switch that deletes all files if the phone number isnβt whitelisted.
Research
/Security News
Socket uncovered 11 malicious Go packages using obfuscated loaders to fetch and execute second-stage payloads via C2 domains.
Security News
TC39 advances 11 JavaScript proposals, with two moving to Stage 4, bringing better math, binary APIs, and more features one step closer to the ECMAScript spec.