
Research
/Security News
10 npm Typosquatted Packages Deploy Multi-Stage Credential Harvester
Socket researchers found 10 typosquatted npm packages that auto-run on install, show fake CAPTCHAs, fingerprint by IP, and deploy a credential stealer.
HATAORI is a SWC plugin that implements a content-addressed function management system similar to Unison in the TypeScript/JavaScript ecosystem.
npm install hataori
Create a .swcrc file:
{
"jsc": {
"experimental": {
"plugins": [
["hataori", {
"enableCapabilities": true,
"hashAlgorithm": "blake3",
"storeBackend": "memory"
}]
]
}
}
}
// Pure function - automatically content-addressed
export const add = (a: number, b: number): number => a + b;
// Function using capabilities
type Capabilities = { clock: { now(): number } };
export const getTimestamp = (A: Capabilities) => () =>
A.clock.now();
import { RuntimeExecutor } from 'hata';
// Execute function by hash address
const executor = new RuntimeExecutor(context);
const result = await executor.execute('u#abc123...', [1, 2]);
HATAORI consists of the following process network:
Source Code → AST Parse → Function Extract → Normalize → Dependency Analysis
↓ ↓ ↓ ↓ ↓
Hash Gen → CAS Store → Name Resolve → Linker → Runtime Execute
CAS is a hash-based storage system that operates within the SWC plugin:
// CAS operation within plugin
const cas = new MemoryCAS(); // Created per file compilation
// Store function by hash
await cas.store(functionHash, functionDefinition);
// Retrieve dependency from CAS
const dependency = await cas.retrieve(dependencyHash);
CAS operation within SWC plugin:
// 1. Create new CAS for each file compilation
Program(program) {
const cas = new MemoryCAS(); // Per-session
// 2. Store functions in CAS during processing
const functions = extractFunctions(program);
for (const func of functions) {
const hash = generateHash(func);
await cas.store(hash, func); // Store by hash
}
// 3. Retrieve dependencies from CAS
const dependencies = await resolveDependencies(func.dependencies, cas);
// 4. CAS discarded after compilation (in-memory)
}
HATAORI controls side effects through explicit "capabilities":
// Predefined capabilities
interface Clock { now(): number; sleep(ms: number): Promise<void> }
interface Random { generate(): number; seed(s: number): void }
interface Http { get(url: string): Promise<string> }
interface Console { log(...args: any[]): void }
// Usage example
export const logTime = (A: { clock: Clock; console: Console }) => () => {
const time = A.clock.now();
A.console.log(`Current time: ${time}`);
};
CAS operates within the SWC plugin runtime and provides independent storage for each compilation session:
// .swcrc
{
"jsc": {
"experimental": {
"plugins": [
["hataori", {
"storeBackend": "memory" // Create new CAS per file
}]
]
}
}
}
// For each .ts file compilation:
// 1. Create new CAS instance
// 2. Store functions in CAS
// 3. Resolve dependencies from CAS
// 4. Discard CAS after compilation
Using persistence options allows CAS sharing across compilation sessions:
const plugin = hata({
storeBackend: 'file' // or 'ipfs'
});
// In this case, CAS is shared across multiple .ts files,
// enabling function definition reuse and dependency resolution
// Original function
export const oldName = (x: number) => x * 2;
// After renaming, hash remains unchanged, references auto-resolved
export const newName = (x: number) => x * 2;
// Test with mock abilities
const testExecutor = executor.createTestContext();
const result = await testExecutor.execute(address, args);
import { hata } from 'hataori';
// Use as SWC plugin
const plugin = hata({
enableCapabilities: true,
hashAlgorithm: 'blake3',
storeBackend: 'memory' // 'memory' | 'file' | 'ipfs'
});
// CAS Backend Options:
// - 'memory': Temporary storage per compilation session (default)
// - 'file': File system-based persistent storage
// - 'ipfs': Distributed storage (IPFS)
CAS content can be exported as programmable Jsonnet format:
// Export CAS content as Jsonnet
const jsonnetOutput = await cas.exportToJsonnet({
includeMetadata: true,
includeComments: true,
compactAST: true,
version: '1.0.0',
});
// Save as Jsonnet file
fs.writeFileSync('cas-export.jsonnet', jsonnetOutput);
Generated Jsonnet files include the following utility functions:
// Search by function name
local cas = import "cas-export.jsonnet";
local addFunc = cas.getFunctionByName("add");
// Get all function names
local allNames = cas.getAllFunctionNames(); // ["add", "multiply", ...]
// Get exported functions only
local exports = cas.getExportedFunctions();
// Get dependency graph
local deps = cas.getDependencyGraph(); // { "add": [], "compute": ["add", "multiply"] }
await cas.exportToJsonnet({
includeMetadata: true, // Include version and timestamp
includeComments: true, // Include comments
compactAST: true, // Compact AST for size reduction
version: '1.0.0', // Version information
filterFunctions: (func) => func.isExported // Specific functions only
});
# Export CAS content as Jsonnet
npm run generate-examples
# Manipulate generated Jsonnet files
jsonnet -e 'local cas = import "examples/cas-compact-export.jsonnet"; cas.getFunctionByName("add")'
# Display dependency graph
jsonnet -e 'local cas = import "examples/cas-compact-export.jsonnet"; cas.getDependencyGraph()'
import { RuntimeExecutor } from 'hata';
const executor = new RuntimeExecutor(context);
// Execute function
const result = await executor.execute('u#hash...', args);
// Create test context
const testExecutor = executor.createTestContext();
git checkout -b feature/AmazingFeature)git commit -m 'Add some AmazingFeature')git push origin feature/AmazingFeature)Distributed under the Apache License, Version 2.0. See LICENSE for more information.
CAS functions as part of the compilation process with the following characteristics:
// CAS Lifecycle
Program(program) {
// 1. Create CAS when plugin execution starts
const cas = new CAS();
// 2. Use CAS during compilation
processFunctions(program, cas);
// 3. Discard CAS when plugin execution ends
// (auto-discarded for in-memory, saved for persistent)
}
HATAORI - Functions by hash, purity by capabilities, distribution by network.
FAQs
HATAORI - TypeScript Merkle Lambda Linker SWC Plugin
We found that hataori 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
Socket researchers found 10 typosquatted npm packages that auto-run on install, show fake CAPTCHAs, fingerprint by IP, and deploy a credential stealer.

Product
Socket Firewall Enterprise is now available with flexible deployment, configurable policies, and expanded language support.

Security News
Open source dashboard CNAPulse tracks CVE Numbering Authorities’ publishing activity, highlighting trends and transparency across the CVE ecosystem.