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

@aligntrue/schema

v0.9.3

Published

JSON Schema validation, canonicalization, and integrity hashing for AlignTrue Align aligns.

Downloads

79

Readme

@aligntrue/schema

JSON Schema validation, canonicalization, and integrity hashing for AlignTrue Align aligns.

Overview

This package provides the core validation and canonicalization utilities for Align Spec v2-preview:

  • JSON Schema validation using Ajv in strict mode
  • JCS (RFC 8785) canonicalization for lockfile and catalog publishing only
  • SHA-256 integrity hashing with verification
  • TypeScript types for Align align structure

Canonicalization Strategy

Important: Canonicalization is ONLY performed at boundaries where determinism is required:

  • Lockfile generation (aligntrue lock in team mode)
  • Catalog publishing (aligntrue publish - removed from roadmap)

NOT used during: init, sync, export, import, or normal file operations.

Why: Solo developers don't need canonicalization overhead for local files. Team mode only needs determinism for lockfile-based drift detection. Running canonicalization on every operation adds unnecessary cost.

Installation

pnpm add @aligntrue/schema

API Reference

Canonicalization

parseYamlToJson(yaml: string): unknown

Parse YAML string to JavaScript object. Resolves anchors and aliases.

import { parseYamlToJson } from "@aligntrue/schema";

const yaml = 'id: "aligns/test/example"\nversion: "1.0.0"';
const obj = parseYamlToJson(yaml);

canonicalizeJson(obj: unknown): string

Apply JCS (RFC 8785) canonicalization to produce stable JSON string with deterministic key ordering.

import { canonicalizeJson } from "@aligntrue/schema";

const obj = { z: 1, a: 2, m: 3 };
const canonical = canonicalizeJson(obj);
// Result: '{"a":2,"m":3,"z":1}'

computeHash(data: string): string

Compute SHA-256 hash of a string and return hex-encoded result.

import { computeHash } from "@aligntrue/schema";

const hash = computeHash("hello world");
// Result: 'b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9'

computeAlignHash(alignYaml: string): string

Compute integrity hash for an Align align YAML document. This function:

  1. Parses YAML to object
  2. Sets integrity.value to "<pending>"
  3. Applies JCS canonicalization
  4. Computes SHA-256 hash
import { computeAlignHash } from "@aligntrue/schema";

const yaml = `
id: "aligns/test/example"
version: "1.0.0"
profile: "align"
spec_version: "1"
...
integrity:
  algo: "jcs-sha256"
  value: "<computed>"
`;

const hash = computeAlignHash(yaml);
// Result: hex-encoded SHA-256 hash (64 characters)

verifyAlignHash(alignYaml: string, storedHash: string): boolean

Verify that a stored hash matches the computed hash.

import { verifyAlignHash } from "@aligntrue/schema";

const isValid = verifyAlignHash(alignYaml, storedHash);

Validation

validateAlignSchema(obj: unknown): ValidationResult

Validate an Align align object against the JSON Schema.

import { validateAlignSchema } from "@aligntrue/schema";

const result = validateAlignSchema(alignObject);
if (!result.valid) {
  console.error("Schema validation failed:", result.errors);
}

ValidationResult:

interface ValidationResult {
  valid: boolean;
  errors?: ValidationError[];
}

interface ValidationError {
  path: string;
  message: string;
  keyword?: string;
  params?: Record<string, unknown>;
}

validateAlignIntegrity(alignYaml: string): IntegrityResult

Validate the integrity hash of an Align align.

import { validateAlignIntegrity } from "@aligntrue/schema";

const result = validateAlignIntegrity(alignYaml);
if (!result.valid) {
  console.error("Hash mismatch!");
  console.error(`Stored:   ${result.storedHash}`);
  console.error(`Computed: ${result.computedHash}`);
}

IntegrityResult:

interface IntegrityResult {
  valid: boolean;
  storedHash?: string;
  computedHash?: string;
  error?: string;
}

validateAlign(alignYaml: string)

Validate both schema and integrity of an Align align in one call.

import { validateAlign } from "@aligntrue/schema";

const result = validateAlign(alignYaml);
if (!result.schema.valid) {
  console.error("Schema errors:", result.schema.errors);
}
if (!result.integrity.valid) {
  console.error("Integrity error:", result.integrity.error);
}

TypeScript Types

Export types for Align align structure:

import type {
  Align,
  AlignScope,
  AlignSection,
  AlignIntegrity,
} from "@aligntrue/schema";

const align: Align = {
  id: "aligns/test/example",
  version: "1.0.0",
  spec_version: "1",
  summary: "Example align",
  tags: ["test"],
  sections: [
    {
      id: "section-1",
      heading: "Getting started",
      level: 1,
      content: "Introduction to the align",
    },
  ],
  integrity: {
    algo: "jcs-sha256",
    value: "<computed>",
  },
};

CLI Scripts

Validate an Align align

pnpm validate path/to/rule.md

Output shows schema validation, integrity validation, and overall status.

Compute hashes for multiple files

node --import tsx --no-warnings scripts/compute-basealign-hashes.ts

This script processes all .yaml files in the basealigns/ directory and updates their integrity hashes.

JSON Utilities

cloneDeep<T>(obj: T): T

Deep clone an object using native structuredClone(). Preferred over JSON.parse(JSON.stringify()).

import { cloneDeep } from "@aligntrue/schema";

const original = { nested: { value: 1 }, arr: [1, 2] };
const cloned = cloneDeep(original);
cloned.nested.value = 2; // original.nested.value still 1

Benefits:

  • Uses native structuredClone() for better performance
  • Handles more types (Date, Map, Set, etc.)
  • Explicit intent in code

parseJsonSafe(str: string): Result<unknown, Error>

Parse JSON string with type-safe error handling. Returns Result type instead of throwing.

import { parseJsonSafe } from "@aligntrue/schema";

const result = parseJsonSafe('{"valid": "json"}');
if (result.ok) {
  console.log(result.value);
} else {
  console.error(result.error.message);
}

stringifyCanonical(obj: unknown): string

Stringify object using canonical JSON (JCS/RFC 8785).

import { stringifyCanonical } from "@aligntrue/schema";

const canonical = stringifyCanonical({ b: 2, a: 1 });
// Result: '{"a":1,"b":2}'

computeContentHash(obj: unknown): string

Convenience wrapper combining canonicalization and hashing for objects.

import { computeContentHash } from "@aligntrue/schema";

const hash = computeContentHash({ rules: [...] });
// Returns: hex-encoded SHA-256 hash

compareCanonical(a: unknown, b: unknown): boolean

Compare two objects using canonical JSON. More reliable than deep equality.

import { compareCanonical } from "@aligntrue/schema";

compareCanonical({ b: 2, a: 1 }, { a: 1, b: 2 }); // true

type Result<T, E>

Result type for operations that may fail.

import type { Result } from "@aligntrue/schema";

type ParseResult = Result<unknown, Error>;

Development

Run tests

pnpm test

Watch mode

pnpm test:watch

Type check

pnpm typecheck

Build

pnpm build

Determinism Guarantees

This package ensures deterministic hashing through:

  1. JCS canonicalization (RFC 8785): Stable key ordering, precise float representation
  2. YAML normalization: Anchors and aliases resolved before hashing
  3. Placeholder handling: integrity.value set to "<pending>" during hash computation
  4. UTF-8 encoding: Consistent byte representation

The same Align align content will always produce the same hash, regardless of:

  • Key ordering in YAML
  • Whitespace or formatting
  • YAML anchors vs explicit duplication
  • Machine or environment

References

License

MIT