Official WOLS (WeMush Open Labeling Standard) library for specimen labeling and traceability
npm install @wemush/wolsOfficial TypeScript library for WOLS (WeMush Open Labeling Standard) - the open standard for biological specimen labeling and traceability in mycology.


- 🏷️ Create & Serialize - Generate WOLS-compliant specimen labels
- ✅ Validate - Schema validation with detailed error reporting
- 📜 Parse - Parse JSON/QR data back to typed specimens
- 📱 QR Codes - Generate QR codes for specimens (PNG, SVG, Data URL)
- 🔗 Compact URLs - Create short URLs for space-constrained labels
- 🔐 Encryption - AES-256-GCM encryption for sensitive data
``bash`
npm install @wemush/wolsor
bun add @wemush/wolsor
pnpm add @wemush/wols
For QR code generation, install the qrcode package:
`bash`
npm install qrcode
`typescript
import { createSpecimen, parseSpecimen, validateSpecimen } from '@wemush/wols';
// Create a specimen
const specimen = createSpecimen({
type: 'CULTURE',
species: 'Pleurotus ostreatus',
strain: 'Blue Oyster',
stage: 'COLONIZATION',
});
console.log(specimen.id); // "wemush:abc123..."
console.log(specimen['@context']); // "https://wemush.com/wols/v1"
`
Creates a new specimen with auto-generated ID and JSON-LD fields.
`typescript`
const specimen = createSpecimen({
type: 'SPAWN',
species: 'Hericium erinaceus',
strain: { name: "Lion's Mane", generation: 'F2' },
stage: 'INOCULATION',
batch: 'BATCH-2024-001',
organization: 'org_123',
custom: { substrate: 'hardwood' },
});
Parameters:
- type - Specimen type: 'CULTURE', 'SPAWN', 'SUBSTRATE', 'FRUITING', 'HARVEST'species
- - Scientific species namestrain
- - String (auto-expands to { name: string }) or full Strain objectstage
- - Growth stage: 'INOCULATION', 'COLONIZATION', 'FRUITING', 'HARVEST'batch
- - Batch identifierorganization
- - Organization IDcreator
- - Creator user IDcustom
- - Custom vendor-specific fields
Serializes a specimen to a JSON-LD string, suitable for QR encoding.
`typescript`
const json = serializeSpecimen(specimen);
// Output: {"@context":"https://wemush.com/wols/v1","@type":"Specimen",...}
Parses a JSON string into a validated Specimen object.
`typescript
const result = parseSpecimen(qrCodeContent);
if (result.success) {
console.log(result.data.species);
} else {
console.error(result.error.code, result.error.message);
}
`
Validates a specimen object against the WOLS schema.
`typescript
const result = validateSpecimen(specimen, { level: 'strict' });
if (!result.valid) {
for (const error of result.errors) {
console.log(${error.path}: ${error.message});`
}
}
Options:
- allowUnknownFields - Allow unknown fields in custom namespacelevel
- - Validation strictness: 'strict' or 'lenient'
Generate QR codes for specimens. Requires the qrcode peer dependency.
`typescript`
import { toQRCode, toQRCodeDataURL, toQRCodeSVG } from '@wemush/wols';
// Or import from submodule:
// import { toQRCode } from '@wemush/wols/qr';
Generate a QR code as a PNG buffer.
`typescript
import { writeFileSync } from 'fs';
const buffer = await toQRCode(specimen, {
size: 400,
errorCorrection: 'H',
});
writeFileSync('specimen.png', buffer);
`
Generate a QR code as a data URL for web embedding.
`typescript`
const dataUrl = await toQRCodeDataURL(specimen);
document.getElementById('qr').src = dataUrl;
Generate a QR code as an SVG string.
`typescript`
const svg = await toQRCodeSVG(specimen);
document.getElementById('qr-container').innerHTML = svg;
QR Options:
- size - Width/height in pixels (default: 300)errorCorrection
- - Error correction level: 'L', 'M', 'Q', 'H' (default: 'M')format
- - Encoding format: 'embedded' (full JSON) or 'compact' (URL)margin
- - Quiet zone modules (default: 1)color.dark
- - Dark module color (default: '#000000')color.light
- - Light module color (default: '#ffffff')
Use compact URLs for space-constrained labels:
`typescript
import { toCompactUrl, parseCompactUrl } from '@wemush/wols';
const url = toCompactUrl(specimen);
// Output: "wemush://v1/abc123?s=POSTR&st=COLONIZATION&ty=CULTURE"
const result = parseCompactUrl(url);
if (result.success) {
console.log(result.data.species); // "Pleurotus ostreatus"
}
`
Encrypt specimens using AES-256-GCM for secure data handling.
`typescript`
import { encryptSpecimen, decryptSpecimen, isEncrypted } from '@wemush/wols';
// Or import from submodule:
// import { encryptSpecimen } from '@wemush/wols/crypto';
Encrypt a specimen with a password or CryptoKey.
`typescript
const encrypted = await encryptSpecimen(specimen, {
key: 'my-secret-password',
});
console.log(encrypted);
// { encrypted: true, payload: "...", iv: "...", algorithm: "AES-256-GCM" }
`
Decrypt an encrypted specimen.
`typescript
const result = await decryptSpecimen(encrypted, {
key: 'my-secret-password',
});
if (result.success) {
console.log(result.data.species);
} else {
console.error('Decryption failed:', result.error.message);
}
`
Check if a value is an encrypted specimen.
`typescript`
if (isEncrypted(data)) {
// Handle encrypted specimen
}
Encryption Options:
- key - Password string (uses PBKDF2) or CryptoKeyfields
- - Encrypt only specific fields (partial encryption)
All types are exported for TypeScript users:
`typescript`
import type {
Specimen,
SpecimenInput,
SpecimenId,
SpecimenType,
GrowthStage,
Strain,
ParseResult,
ValidationResult,
ValidationError,
EncryptedSpecimen,
EncryptionOptions,
QRCodeOptions,
} from '@wemush/wols';
All errors include a stable error code for programmatic handling:
`typescript
import { WolsErrorCode } from '@wemush/wols';
const result = parseSpecimen(invalidJson);
if (!result.success) {
switch (result.error.code) {
case WolsErrorCode.INVALID_JSON:
console.error('Invalid JSON syntax');
break;
case WolsErrorCode.REQUIRED_FIELD:
console.error('Missing required field');
break;
case WolsErrorCode.INVALID_ID_FORMAT:
console.error('Invalid specimen ID format');
break;
}
}
``
This library implements WOLS v1.1.0. For the full specification, see the WOLS Specification.