open-index/open-npm huggingface dataset:
npm package: @pojagi/sanjaya-api
Description: TypeSpec definitions for the Sanjaya Dynamic Reporting API
Author: Tom Brennan
Latest version: 0.1.2

# @pojagi/sanjaya-api

TypeSpec definitions for the **Sanjaya Dynamic Reporting API**.

## Quick start — generate OpenAPI locally

```bash
cd api
pnpm install
pnpm build          # emits tsp-output/@typespec/openapi3/openapi.yaml
```

## Using in another TypeSpec project

### 1. Install the package

```bash
# peer dependencies are required
npm install @pojagi/sanjaya-api @typespec/compiler @typespec/http
# or
pnpm add @pojagi/sanjaya-api @typespec/compiler @typespec/http
```

### 2. Import models

The package exposes its entry point via the `tspMain` field in `package.json`,
so you can import it by package name.  All data models live under the `Models`
namespace and the REST routes live under `Rest.Api.V1`.

```typespec
import "@pojagi/sanjaya-api";

using Models;

// Now you can reference any exported model, enum, or union:
// ColumnType, FilterGroup, DynamicReport, AggFunc, etc.
```

### 3. Import individual files

If you only need a subset of the definitions you can import specific files
instead of the top-level entry point:

```typespec
// Models only (no REST routes)
import "@pojagi/sanjaya-api/models/dynamic-reports.tsp";

// Error models only
import "@pojagi/sanjaya-api/models/errors.tsp";
```

### 4. Extend or compose

Because these are plain TypeSpec definitions you can extend models, intersect
them, or reference them in your own service definition:

```typespec
import "@pojagi/sanjaya-api";
import "@typespec/http";

using TypeSpec.Http;
using Models;

@service(#{ title: "My Reporting Service" })
namespace MyService;

model MyCustomReport {
  ...DynamicReport;           // spread all fields
  tenantId: string;           // add your own
}

@route("/custom-reports")
@get op list(): MyCustomReport[];
```

## Namespaces

| Namespace | Description |
|---|---|
| `Models` | All data models, enums, and error types |
| `Rest.Api.V1` | HTTP operations grouped by resource |

## Peer dependencies

| Package | Version |
|---|---|
| `@typespec/compiler` | `^1.9.0` |
| `@typespec/http` | `^1.9.0` |

## License

MIT
npm package: @pojo-router/react-browser-pathname
Description: A react hooks wrapper around the browser's pathname
Author: William Klancnik
Latest version: 0.4.3

# @pojo-router/react-browser-pathname
<!--[![CircleCI](https://circleci.com/gh/notwillk/pojo-router.svg?style=shield)](https://circleci.com/gh/notwillk/pojo-router)-->
[![npm downloads](https://img.shields.io/npm/dm/@pojo-router/react-browser-pathname.svg?style=flat-square)](https://www.npmjs.com/package/@pojo-router/react-browser-pathname)
[![bundle size](https://img.shields.io/bundlephobia/minzip/@pojo-router/react-browser-pathname?style=flat-square)](https://bundlephobia.com/result?p=@pojo-router/react-browser-pathname)
[![npm version](https://img.shields.io/npm/v/@pojo-router/react-browser-pathname.svg?style=flat-square)](https://www.npmjs.com/package/@pojo-router/react-browser-pathname)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)

Browser controls for pojo router

# API
npm package: @pokapali/blocks
Description: Encrypted snapshot encoding and versioning for pokapali documents
Author: g. nicholas d'andrea
Latest version: 0.1.2

# @pokapali/blocks

```sh
npm install @pokapali/blocks
```

Snapshot encoding, decoding, verification, and chain
walking for Pokapali's IPFS persistence layer. Each
snapshot is a DAG-CBOR block containing the full encrypted
state of every subdocument, linked into an append-only
chain via `prev` CID pointers. Snapshots are signed with
Ed25519 for structural validation by pinners.

## Quick Example

```ts
import {
  encodeSnapshot,
  decodeSnapshot,
  decryptSnapshot,
  validateSnapshot,
} from "@pokapali/blocks";
import { deriveDocKeys, ed25519KeyPairFromSeed } from "@pokapali/crypto";

// Derive keys (normally done by @pokapali/core)
const keys = await deriveDocKeys(secret, "my-app", ["content"]);
const signingKey = await ed25519KeyPairFromSeed(keys.ipnsKeyBytes);

// Encode a snapshot from subdoc state
const block = await encodeSnapshot(
  { content: contentBytes, _meta: metaBytes },
  keys.readKey,
  null, // prev CID (null for first snapshot)
  1, // seq
  Date.now(), // ts
  signingKey,
);

// Validate structure + signature (returns boolean)
const isValid = await validateSnapshot(block);
console.log("valid:", isValid);

// Decode and decrypt
const node = decodeSnapshot(block);
const plaintext = await decryptSnapshot(node, keys.readKey);
// plaintext.content, plaintext._meta
```

## Key Exports

- **`encodeSnapshot(plaintext, readKey, prev, seq, ts,
signingKey)`** — encrypts subdoc state and produces a
  signed DAG-CBOR block
- **`decodeSnapshot(bytes)`** — parses a block into a
  `SnapshotNode`
- **`decryptSnapshot(node, readKey)`** — decrypts the
  subdoc payloads
- **`validateSnapshot(block)`** — verifies CBOR schema
  and Ed25519 signature (no key authorization check)
- **`walkChain(tipCid, getter)`** — async iterator that
  follows `prev` links
- **`SnapshotNode`** — interface: `subdocs`, `prev`,
  `seq`, `ts`, `signature`, `publicKey`

Also re-exports `CID`, `sha256`, and `dagCborCode` for
convenience.

## Links

- [Root README](https://github.com/gnidan/pokapali#readme)
- [Architecture — Snapshot Chain](https://github.com/gnidan/pokapali/tree/main/docs/internals)
npm package: @pokapali/capability
Description: Capability-based access control for pokapali documents
Author: g. nicholas d'andrea
Latest version: 0.1.2

# @pokapali/capability

```sh
npm install @pokapali/capability
```

Capability URL encoding, decoding, and access level
inference. A capability URL's fragment contains a
version-prefixed, labeled key set — which keys are present
determines the access level (admin, writer, read-only).
This package handles serialization and provides
`narrowCapability` for generating lower-privilege URLs.

## Usage

```typescript
import {
  buildUrl,
  parseUrl,
  inferCapability,
  narrowCapability,
} from "@pokapali/capability";

// Build a capability URL from keys
const url = await buildUrl("https://my-app.com", ipnsName, keys);
// → "https://my-app.com/doc/<ipnsName>#<encoded-keys>"

// Parse a capability URL back into its parts
const { base, ipnsName, keys } = await parseUrl(url);

// Determine what this key set can do
const cap = inferCapability(keys, ["content", "comments"]);
console.log(cap.isAdmin); // true if rotationKey present
console.log(cap.canPushSnapshots); // true if ipnsKeyBytes present
console.log(cap.channels); // Set of writable channel names

// Generate a lower-privilege URL for sharing
const writeKeys = narrowCapability(keys, {
  channels: ["content"],
  canPushSnapshots: true,
});
const writeUrl = await buildUrl(base, ipnsName, writeKeys);
// writeUrl grants content-channel write access only
```

## Key Exports

- **`CapabilityKeys`** — interface for the optional key
  set (readKey, ipnsKeyBytes, rotationKey, channelKeys,
  awarenessRoomPassword)
- **`Capability`** — inferred access level (channels,
  canPushSnapshots, isAdmin)
- **`inferCapability(keys)`** — determines access level
  from which keys are present
- **`buildUrl(base, ipnsName, keys)`** — encodes keys
  into a capability URL
- **`parseUrl(url)`** — decodes a capability URL into
  base, ipnsName, and keys
- **`narrowCapability(keys, grant)`** — produces a
  subset of keys for a lower-privilege URL
- **`CapabilityGrant`** — specifies which channels
  and whether `canPushSnapshots` to include

## Links

- [Root README](https://github.com/gnidan/pokapali#readme)
- [Architecture — Capability URLs](https://github.com/gnidan/pokapali/tree/main/docs/internals)
npm package: @pokapali/comments
Description: Anchored, attributed, threaded comments for Yjs documents
Author: g. nicholas d'andrea
Latest version: 0.1.2

# @pokapali/comments

```sh
npm install @pokapali/comments
```

Anchored, attributed, threaded comments for Yjs
documents. Generic over app-defined comment data `T`.
Does **not** depend on `@pokapali/core` — works with
any Yjs setup.

## Quick Start

```typescript
import { comments } from "@pokapali/comments";
import type { Feed } from "@pokapali/comments";
import * as Y from "yjs";

const commentsDoc = new Y.Doc();
const contentDoc = new Y.Doc();
contentDoc.getText("default").insert(0, "Hello world");

// In a real app, pass doc.clientIdMapping from
// @pokapali/core. For standalone usage, provide a
// Feed-compatible object:
const emptyMapping: Feed<Map<number, unknown>> = {
  getSnapshot: () => new Map(),
  subscribe: () => () => {},
};

const c = comments<{ status: "open" | "resolved" }>(commentsDoc, contentDoc, {
  author: "alice-pubkey",
  clientIdMapping: emptyMapping,
});

// Add a comment anchored to "Hello".
const id = c.add({
  content: "Fix this greeting.",
  anchor: c.createAnchor(0, 5),
  data: { status: "open" },
});

// Subscribe to the reactive comment list.
c.feed.subscribe(() => {
  console.log(c.feed.getSnapshot());
});
```

## Key Exports

- **`comments<T>(commentsDoc, contentDoc, options)`** —
  factory returning a `Comments<T>` instance
- **`CommentsOptions`** — `author`, `clientIdMapping`
  (reactive Feed), optional `contentType` for
  XmlFragment/Tiptap
- **`Comments<T>`** — `feed`, `createAnchor()`,
  `add()`, `update()`, `delete()`, `destroy()`
- **`Comment<T>`** — projected comment with `id`,
  `author`, `authorVerified`, `content`, `ts`,
  `anchor`, `parentId`, `children`, `data`
- **`Anchor`** — opaque encoded RelativePosition pair
- **`ResolvedAnchor`** — `"resolved"` (with indices),
  `"orphaned"`, or `"pending"`
- **`anchorFromRelativePositions(start, end)`** —
  build an Anchor from pre-existing RelativePositions
  (for y-prosemirror / Tiptap integration)
- **`Feed<T>`** — reactive value container compatible
  with React's `useSyncExternalStore`
- **`ClientIdMapping`** / **`ClientIdentityInfo`** —
  types for author verification

## Features

- **Anchoring** — comments track text positions via
  Y.RelativePosition; anchors survive concurrent edits
- **Generic content type** — works with Y.Text (default)
  or Y.XmlFragment (Tiptap/ProseMirror) via the
  `contentType` option
- **Author verification** — cross-references Yjs
  clientID against a pubkey mapping to verify authorship
- **One-level threading** — replies nest under parents;
  reply-to-reply is disallowed
- **Reactive feed** — `feed.getSnapshot()` /
  `feed.subscribe()` for UI binding
- **CRDT sync** — comments live in a Y.Map and merge
  across peers automatically

## Links

- [Root README](https://github.com/gnidan/pokapali#readme)
npm package: @pokapali/crypto
Description: Cryptographic primitives for pokapali
Author: g. nicholas d'andrea
Latest version: 0.1.1

# @pokapali/crypto

```sh
npm install @pokapali/crypto
```

Cryptographic primitives for Pokapali. Derives all document
keys from a single admin secret via HKDF (RFC 5869), with
the `appId` baked into the `info` parameter to prevent
cross-app key collisions. Uses `@noble/ed25519` for signing
and the Web Crypto API for AES-GCM encryption.

## Quick Example

```ts
import {
  generateAdminSecret,
  deriveDocKeys,
  signBytes,
  verifyBytes,
  generateIdentityKeypair,
} from "@pokapali/crypto";

// Generate a new admin secret and derive all keys
const secret = generateAdminSecret();
const keys = await deriveDocKeys(secret, "my-app", ["content"]);

// keys.readKey       — AES-GCM key for encryption
// keys.ipnsKeyBytes  — IPNS signing seed
// keys.channelKeys   — per-channel write keys

// Sign and verify with an identity keypair
const identity = await generateIdentityKeypair();
const data = new TextEncoder().encode("hello");
const sig = await signBytes(identity, data);
const ok = await verifyBytes(identity.publicKey, sig, data);
// ok === true
```

## Key Exports

- **`generateAdminSecret()`** — generates a random
  base64url-encoded admin secret
- **`deriveDocKeys(secret, appId, channels)`** —
  derives all keys (readKey, ipnsKeyBytes, rotationKey,
  channel keys, awarenessRoomPassword)
- **`DocKeys`** — interface for the full key set
- **`ed25519KeyPairFromSeed(seed)`** — Ed25519 keypair
  from a 32-byte seed
- **`signBytes(keyPair, data)`** / **`verifyBytes(
publicKey, signature, data)`** — Ed25519 sign/verify
- **`encryptSubdoc(readKey, data)`** /
  **`decryptSubdoc(readKey, ciphertext)`** — AES-GCM
  encrypt/decrypt
- **`bytesToHex(bytes)`** / **`hexToBytes(hex)`** —
  hex encoding utilities

## Links

- [Root README](https://github.com/gnidan/pokapali#readme)
- [Architecture — Key Derivation](https://github.com/gnidan/pokapali/tree/main/docs/internals)
npm package: @pokapali/log
Description: Structured logging for pokapali packages
Author: g. nicholas d'andrea
Latest version: 0.1.1

# @pokapali/log

```sh
npm install @pokapali/log
```

Zero-dependency structured logging for Pokapali. Provides
a `createLogger(module)` factory that produces a `Logger`
with level-filtered `debug`, `info`, `warn`, and `error`
methods. Output is prefixed with `[pokapali:<module>]`.
Placed as a separate leaf package to avoid dependency
cycles between `@pokapali/core` and `@pokapali/sync`.

## Key Exports

- **`createLogger(module)`** — returns a `Logger`
  instance for the given module name
- **`Logger`** — interface with `debug()`, `info()`,
  `warn()`, `error()` methods
- **`LogLevel`** — `"debug"` | `"info"` | `"warn"` |
  `"error"`

## Configuration

Set the log level via environment variable:

```sh
POKAPALI_LOG_LEVEL=debug npx pokapali ...
```

Or programmatically at runtime:

```ts
import { setLogLevel } from "@pokapali/log";
setLogLevel("debug");
```

Default level is `"info"`.

## Links

- [Root README](https://github.com/gnidan/pokapali#readme)
npm package: @pokapali/node
Description: Node.js relay and pinner for pokapali networks
Author: g. nicholas d'andrea
Latest version: 0.1.4

# @pokapali/node

```sh
npm install @pokapali/node
```

Node.js server components for Pokapali: a generic relay
for GossipSub mesh connectivity, a zero-knowledge pinner
for snapshot ingestion and IPNS republishing, and an HTTP
server for health monitoring. Provides the `pokapali` CLI
for running relay + pinner nodes on a VPS.

## Key Exports

- **`startRelay(config)`** — starts a Helia node with
  libp2p, client-mode DHT, GossipSub, autoTLS, persistent
  key/datastore, and `FsBlockstore` for persistent block
  storage. Broadcasts node capabilities on
  `pokapali._node-caps._p2p._pubsub` every 30 seconds
- **`createPinner(config)`** — subscribes to announce
  topics, fetches and validates snapshots, maintains a
  24-hour history window, republishes IPNS records.
  State (`knownNames`, `tips`, `nameToAppId`) is persisted
  to `state.json` with dirty-flag debounced writes
- **`startHttpServer(config)`** — HTTP server with
  `GET /healthz` and `GET /status` endpoints
- **`createRateLimiter(config)`** — per-IPNS-name rate
  limiting for pinner ingestion
- **`createHistoryTracker()`** — time-windowed snapshot
  history with pruning

## CLI

```sh
npx pokapali \
  --relay \
  --pin my-app-id \
  --port 3001 \
  --storage-path /var/lib/pokapali
```

## Links

- [Root README](https://github.com/gnidan/pokapali#readme)
- [Architecture — Pinning Servers](https://github.com/gnidan/pokapali/tree/main/docs/internals)
npm package: @pokapali/snapshot
Description: Encrypted snapshot encoding and versioning for pokapali documents
Author: g. nicholas d'andrea
Latest version: 0.1.2

# @pokapali/snapshot

```sh
npm install @pokapali/snapshot
```

Snapshot encoding, decoding, verification, and chain
walking for Pokapali's IPFS persistence layer. Each
snapshot is a DAG-CBOR block containing the full encrypted
state of every subdocument, linked into an append-only
chain via `prev` CID pointers. Snapshots are signed with
Ed25519 for structural validation by pinners.

## Quick Example

```ts
import {
  encodeSnapshot,
  decodeSnapshot,
  decryptSnapshot,
  validateSnapshot,
} from "@pokapali/snapshot";
import { deriveDocKeys, ed25519KeyPairFromSeed } from "@pokapali/crypto";

// Derive keys (normally done by @pokapali/core)
const keys = await deriveDocKeys(secret, "my-app", ["content"]);
const signingKey = await ed25519KeyPairFromSeed(keys.ipnsKeyBytes);

// Encode a snapshot from subdoc state
const block = await encodeSnapshot(
  { content: contentBytes, _meta: metaBytes },
  keys.readKey,
  null, // prev CID (null for first snapshot)
  1, // seq
  Date.now(), // ts
  signingKey,
);

// Validate structure + signature (returns boolean)
const isValid = await validateSnapshot(block);
console.log("valid:", isValid);

// Decode and decrypt
const node = decodeSnapshot(block);
const plaintext = await decryptSnapshot(node, keys.readKey);
// plaintext.content, plaintext._meta
```

## Key Exports

- **`encodeSnapshot(plaintext, readKey, prev, seq, ts,
signingKey)`** — encrypts subdoc state and produces a
  signed DAG-CBOR block
- **`decodeSnapshot(bytes)`** — parses a block into a
  `SnapshotNode`
- **`decryptSnapshot(node, readKey)`** — decrypts the
  subdoc payloads
- **`validateSnapshot(block)`** — verifies CBOR schema
  and Ed25519 signature (no key authorization check)
- **`walkChain(tipCid, getter)`** — async iterator that
  follows `prev` links
- **`SnapshotNode`** — interface: `subdocs`, `prev`,
  `seq`, `ts`, `signature`, `publicKey`

Also re-exports `CID`, `sha256`, and `dagCborCode` for
convenience.

## Links

- [Root README](https://github.com/gnidan/pokapali#readme)
- [Architecture — Snapshot Chain](https://github.com/gnidan/pokapali/tree/main/docs/internals)
npm package: @pokapali/subdocs
Description: Multi-channel Yjs subdocument management for pokapali
Author: g. nicholas d'andrea
Latest version: 0.1.2

# @pokapali/subdocs

```sh
npm install @pokapali/subdocs
```

Yjs subdocument manager with channel isolation. Creates
and manages one `Y.Doc` per channel, tracks dirty state
(whether local changes exist since the last snapshot), and
handles snapshot application with origin markers so
snapshot-sourced updates can be distinguished from local
edits.

## Quick Example

```ts
import { createSubdocManager, SNAPSHOT_ORIGIN } from "@pokapali/subdocs";

// Create a manager with two channels
const mgr = createSubdocManager("doc-ipns-name", ["content", "comments"]);

// Access a channel's Y.Doc
const contentDoc = mgr.subdoc("content");
const ytext = contentDoc.getText("body");
ytext.insert(0, "Hello!");

// Check dirty state (local edits since last snapshot)
console.log(mgr.isDirty); // true

// Encode all subdocs for snapshotting
const encoded = mgr.encodeAll();
// { content: Uint8Array, comments: Uint8Array,
//   _meta: Uint8Array }

// Apply a remote snapshot
mgr.applySnapshot(remoteData);
// Updates are applied with SNAPSHOT_ORIGIN so
// dirty tracking ignores them

mgr.destroy();
```

## Key Exports

- **`createSubdocManager(channels)`** — factory that
  initializes a `Y.Doc` per channel with IndexedDB
  persistence and dirty tracking
- **`SubdocManager`** — interface with `subdoc(name)`,
  `encodeAll()`, `applySnapshot()`, `dirty`, `destroy()`
- **`SNAPSHOT_ORIGIN`** — transaction origin marker for
  snapshot-applied updates

## Links

- [Root README](https://github.com/gnidan/pokapali#readme)
- [Architecture — Channel Isolation](https://github.com/gnidan/pokapali/tree/main/docs/internals)
npm package: @pokapali/sync
Description: WebRTC sync provider for pokapali documents
Author: g. nicholas d'andrea
Latest version: 0.1.2

# @pokapali/sync

```sh
npm install @pokapali/sync
```

WebRTC room setup for real-time Yjs sync. Creates one
y-webrtc room per writable channel (password-protected
with the channel access key) and a shared awareness room
for cursor presence. Signaling is handled via a GossipSub
adapter over the libp2p mesh — no external WebSocket
signaling servers required.

## Usage

```typescript
import {
  setupNamespaceRooms,
  setupAwarenessRoom,
  createGossipSubSignaling,
} from "@pokapali/sync";

// 1. Set up per-channel WebRTC sync rooms
const syncManager = setupNamespaceRooms(
  ipnsName,
  subdocManager,
  { content: channelKey }, // channel name → key
  signalingUrls,
);

// Monitor connection status
syncManager.onStatusChange((status) => {
  console.log(status); // "connecting" | "connected" | "disconnected"
});

// Connect additional channels on demand
syncManager.connectChannel("comments");

// 2. Set up shared awareness room for cursors
const { awareness, destroy: destroyAwareness } = setupAwarenessRoom(
  ipnsName,
  awarenessPassword,
  signalingUrls,
);

// 3. Use GossipSub for P2P signaling (no WebSocket
//    signaling server needed)
const signaling = createGossipSubSignaling(pubsub);

// Pass pubsub via SyncOptions to enable it
const syncWithGossip = setupNamespaceRooms(
  ipnsName,
  subdocManager,
  { content: channelKey },
  [], // no WebSocket signaling URLs needed
  { pubsub },
);

// Clean up
syncManager.destroy();
destroyAwareness();
```

## Key Exports

- **`setupNamespaceRooms()`** — creates WebrtcProvider
  instances for each writable channel
- **`setupAwarenessRoom()`** — creates the shared
  awareness room (all capability levels join)
- **`createGossipSubSignaling()`** — GossipSub-based
  signaling adapter that integrates with y-webrtc's
  WebrtcProvider for peer discovery
- **`SyncManager`** — interface for connection status,
  cleanup, and `onStatusChange(cb)` for reacting to
  y-webrtc provider status events (e.g. after PBKDF2
  key derivation completes)
- **`SyncOptions`** — configuration (ICE servers, peer
  options)
- **`PubSubLike`** — minimal pubsub interface for
  GossipSub integration

## Links

- [Root README](https://github.com/gnidan/pokapali#readme)
- [Architecture](https://github.com/gnidan/pokapali/tree/main/docs/internals)
npm package: @pokapali/test-utils
Description: Networking and peer-simulation utilities for testing pokapali applications
Author: g. nicholas d'andrea
Latest version: 0.1.4

# @pokapali/test-utils

```sh
npm install @pokapali/test-utils
```

Yjs-level sync harness for testing multi-peer
scenarios. Fully synchronous — no timers, no
flakiness.

## Quick Start

```typescript
import { createTestNetwork } from "@pokapali/test-utils";

const net = createTestNetwork({
  channels: ["content"],
});

const alice = net.peer("alice");
const bob = net.peer("bob");

// Edits propagate instantly.
alice.channel("content").getMap("d").set("key", "val");
bob.channel("content").getMap("d").get("key"); // "val"

// Simulate network partition.
net.disconnect("alice", "bob");
alice.channel("content").getMap("d").set("a", 1);
bob.channel("content").getMap("d").set("b", 2);

// Reconnect merges diverged state.
net.reconnect("alice", "bob");
alice.channel("content").getMap("d").get("b"); // 2
bob.channel("content").getMap("d").get("a"); // 1

net.destroy();
```

## Key Exports

- **`createTestNetwork(options)`** — factory returning
  a `TestNetwork` instance
- **`TestNetworkOptions`** — `channels: string[]`,
  `latency?: LatencyOptions`
- **`LatencyOptions`** — `ms: number`,
  `jitter?: number` (simulates network delay)
- **`TestNetwork`** — `peer()`, `disconnect()`,
  `reconnect()`, `partition()`, `heal()`,
  `isConverged()`, `settle()`, `destroy()`
- **`TestPeer`** — `name`, `channel(name)` (returns
  Y.Doc)
- **`createTestRelay(options?)`** — async factory for
  a minimal libp2p relay (E2E tests)
- **`TestRelay`** — `multiaddr`, `peerId`, `stop()`
- **`TestRelayOptions`** — `port?: number`

## Features

- **Synchronous sync** — Y.Doc update observers
  propagate edits immediately, no async gaps
- **Disconnect / reconnect** — suppress sync between
  peers, then flush pending state on reconnect
- **Partition / heal** — isolate groups of peers;
  `heal()` reconnects everyone and merges state
- **Convergence check** — `isConverged()` compares
  state vectors across all peers and channels
- **Settle** — `settle()` waits for all pending
  delayed updates when latency simulation is active
- **Late join** — new peers receive existing state
  on creation
- **Multi-channel** — each peer gets one Y.Doc per
  channel, all synced independently

## Links

- [Root README](https://github.com/gnidan/pokapali#readme)
npm package: @pokash/n8n-nodes-azure-blob
Description: n8n community node for Azure Blob Storage operations
Author: POKASH
Latest version: 1.0.9

# n8n-nodes-azure-blob

This is an n8n community node that allows you to interact with Azure Blob Storage in your n8n workflows.

## Configuration

### Credentials Setup
1. Go to **Settings** → **Credentials** in your n8n instance
2. Click **Add credential** and select **Azure Blob Storage API**
3. Choose your authentication method and fill in the required fields:

#### Account Key Method
- **Account Name**: Your Azure Storage account name
- **Account Key**: Your storage account access key

#### Connection String Method
- **Connection String**: Complete connection string from Azure portal

#### SAS Token Method
- **Account Name**: Your Azure Storage account name
- **SAS Token**: Shared Access Signature token

## Usage Examples

### Upload a File
1. Add the **Azure Blob Storage** node to your workflow
2. Select **Upload** operation
3. Set the **Container Name**
4. Configure the **Binary Property** (usually 'data')
5. Optionally set a custom **Blob Name**
6. Set **Content Type** if needed

### Download a File
1. Add the **Azure Blob Storage** node
2. Select **Download** operation
3. Set the **Container Name**
4. Specify the **Blob Name** to download
5. Set the **Binary Property Name** for the output

### List Blobs
1. Add the **Azure Blob Storage** node
2. Select **List** operation
3. Set the **Container Name**
4. Optionally set a **Prefix** to filter results
5. Set **Max Results** limit

### Delete a Blob
1. Add the **Azure Blob Storage** node
2. Select **Delete** operation
3. Set the **Container Name**
4. Specify the **Blob Name** to delete

## Advanced Options

### Upload Options
- **Metadata**: Add custom metadata key-value pairs
- **Tags**: Add blob index tags for searching and filtering
- **Overwrite**: Control whether to overwrite existing blobs
- **Content Type**: Set custom MIME type

### Security Features
- Support for all Azure authentication methods
- Secure credential storage
- Connection testing capabilities

## Error Handling

The node includes comprehensive error handling:
- Invalid credentials detection
- Missing container/blob validation
- Network connectivity issues
- Permission-related errors
npm package: @pokash/n8n-nodes-azure-servicebus
Description: Azure Service Bus nodes for n8n with full session support using official @azure/service-bus
Author: Lukasz Gabrysiak
Latest version: 1.7.7

# Azure Service Bus Node for n8n

Niestandardowy węzeł n8n do pracy z Azure Service Bus wykorzystujący oficjalną bibliotekę `@azure/service-bus`.

## Funkcje

- ✅ Wysyłanie wiadomości do kolejek (queues)
- ✅ Wysyłanie wiadomości do tematów (topics)
- ✅ Odbieranie wiadomości z kolejek
- ✅ Obsługa właściwości niestandardowych
- ✅ Różne tryby odbierania (Peek Lock, Receive and Delete)
- ✅ Obsługa Azure Service Bus Connection String

## Konfiguracja

### Dodaj dane uwierzytelniające w n8n:

Connection String:
```
Endpoint=sb://xxx.servicebus.windows.net/;SharedAccessKeyName=xxx;SharedAccessKey=xxx;EntityPath=xxx
```

### Używanie węzła:

1. Wybierz Resource: Queue
2. Queue Name: `xxx`
3. Operation: Send Message lub Receive Messages

## Przykład użycia:

```json
{
  "messageBody": "{\"productId\": 123, \"name\": \"Test Product\"}",
  "contentType": "application/json"
}
```
npm package: @pokash/n8n-nodes-erpxt
Description: n8n nodes for Comarch ERP XT (Betterfly) integration - invoices, customers, products
Author: POKASH
Latest version: 0.5.7

# n8n-nodes-erpxt

Node n8n do integracji z **Comarch ERP XT** (Betterfly).

## Funkcjonalności

### Faktury
- **Utwórz** - tworzenie nowej faktury sprzedaży
- **Pobierz** - pobranie faktury po ID
- **Pobierz wszystkie** - pobranie listy faktur (z opcjonalnym filtrem po numerze)
- **Aktualizuj** - aktualizacja istniejącej faktury
- **Zatwierdź** - zatwierdzenie faktury
- **Usuń** - usunięcie faktury

## Instalacja

```bash
# W katalogu ~/.n8n/custom
npm install n8n-nodes-erpxt

# Lub globalnie
npm install -g n8n-nodes-erpxt
```

## Konfiguracja

1. W Comarch ERP XT przejdź do: **Moje konto → Zarządzaj kontem**
2. Wygeneruj **Client ID** i **Client Secret**
3. W n8n dodaj credentials typu **ERP XT API** i wprowadź wygenerowane dane

## Wymagane pola przy tworzeniu faktury

- **ID Nabywcy** (`PurchasingPartyId`) - identyfikator kontrahenta
- **ID Formy Płatności** (`PaymentTypeId`) - identyfikator formy płatności

## Struktura pozycji faktury

Każda pozycja wymaga:
- `ProductId` - identyfikator produktu
- `Quantity` - ilość
- `ProductCurrencyPrice` - cena jednostkowa

Opcjonalnie:
- `ProductDescription` - opis produktu
- `VatRateId` - stawka VAT (wymagane dla OSS)

## Przykład użycia

### Tworzenie faktury

```json
{
  "PurchasingPartyId": "123",
  "PaymentTypeId": "1",
  "InvoiceType": 0,
  "Items": [
    {
      "ProductId": "456",
      "Quantity": 2,
      "ProductCurrencyPrice": 100.00
    }
  ]
}
```

## Dokumentacja API

- [Uwierzytelnianie](https://pomoc.comarchbetterfly.pl/dokumentacja/api-uwierzytelnianie/)
- [Faktury sprzedaży](https://pomoc.comarchbetterfly.pl/dokumentacja/api-faktura-sprzedazy/)
npm package: @pokash/n8n-nodes-optima-rest-api
Description: n8n node for Comarch Optima REST API integration
Author: POKASH.PL Sp. z o. o.
Latest version: 1.7.0

# n8n-nodes-optima-rest-api

Node n8n do integracji z Comarch Optima ERP poprzez REST API Gateway.

## Instalacja

### Community Node (n8n Cloud lub Self-hosted)

W n8n przejdź do **Settings > Community Nodes** i zainstaluj:

```
n8n-nodes-optima-rest-api
```

### Manualna instalacja (Development)

1. Przejdź do folderu z custom nodes:
   ```bash
   cd ~/.n8n/custom
   ```

2. Sklonuj lub skopiuj ten folder

3. Zainstaluj zależności:
   ```bash
   npm install
   ```

4. Zbuduj projekt:
   ```bash
   npm run build
   ```

5. Zrestartuj n8n

## Konfiguracja

### Credentials

Utwórz credentials typu **Optima REST API**:

- **Gateway URL**: URL adres serwera Gateway (np. `http://localhost:5000`)
- **Username**: Nazwa użytkownika Optima
- **Password**: Hasło użytkownika
- **Company**: Kod firmy w Optima (np. `FIRMA01`)
- **Modules**: Moduły Optima (np. `KP` dla księgowości, `CDN` dla handlu)

## Dostępne operacje

### Customer (Kontrahent)

- **Get**: Pobierz kontrahenta po ID
- **Get All**: Pobierz wszystkich kontrahentów
- **Create**: Utwórz nowego kontrahenta
- **Update**: Zaktualizuj kontrahenta
- **Delete**: Usuń kontrahenta

### Document (Dokument)

- **Create Invoice**: Utwórz fakturę sprzedaży lub zakupu

### Product (Towar)

- **Get**: Pobierz towar po ID
- **Get All**: Pobierz wszystkie towary

### Print (Wydruk)

- **Print Document**: Wygeneruj PDF dokumentu

## Przykłady użycia

### Utworzenie kontrahenta

```json
{
  "akronim": "KLIENT01",
  "nazwa": "Firma Example Sp. z o.o.",
  "nip": "1234567890",
  "ulica": "Główna 1",
  "kod": "00-001",
  "miasto": "Warszawa"
}
```

### Utworzenie faktury sprzedaży

```json
{
  "platnik": {
    "akronim": "KLIENT01"
  },
  "pozycje": [
    {
      "kod": "PROD01",
      "ilosc": 2,
      "cena": 100.00
    }
  ]
}
```

### Wydruk dokumentu do PDF

Parametry:
- **Document ID**: 123 (ID dokumentu w Optima)
- **Format ID**: 1 (ID formatu wydruku z Optima)

Alternatywnie można użyć **SQL Filter**:
```
TrN_TrnId = 123
```

## Development

### Build

```bash
npm run build
```

### Watch mode

```bash
npm run dev
```

### Linting

```bash
npm run lint
npm run lintfix
```

### Format code

```bash
npm run format
```

## Licencja

MIT

## Autor

POKASH.PL Sp. z o. o. (hello@pokash.cloud)

## Links

- [GitHub Repository](https://github.com/pokash-pl/n8n-nodes-optima-rest-api)
- [npm Package](https://www.npmjs.com/package/@pokash/n8n-nodes-optima-rest-api)
npm package: @pokayoke/prettier-config
Description: <div align="center"> <h1>@pokayoke/prettier-config 🎨</h1> </div>
Author: Matt Hamil
Latest version: 1.0.0

<div align="center">
<h1>@pokayoke/prettier-config 🎨</h1>
</div>

---

## Installation

Add this package to your project's `devDependencies`:

```
yarn add -D @pokayoke/prettier-config
```

## Usage

Use this config in one of the following ways:

Reference this package in your `package.json`:

```json
{
  "prettier": "@pokayoke/prettier-config"
}
```

Or, use any of the [supported extensions](https://prettier.io/docs/en/configuration.html) (e.g. `.prettierrc.json`) to export a string:

```
"@pokayoke/prettier-config"
```

## Overriding or Extending Config

Import this package in a `.prettierrc.js` file and add your own config options:

```js
module.exports = {
  ...require("@pokayoke/prettier-config"),
  semi: false,
};
```