# nx-remote-json

> A unified API to read, write, and mirror JSON objects across disk, S3-compatible storage, and MongoDB

Latest version **1.0.8** (published 2026-01-09) · MIT license · 0 weekly downloads

## Install

```sh
npm install nx-remote-json
pnpm add nx-remote-json
yarn add nx-remote-json
bun add nx-remote-json
```

## Health

**Score 50/100 (C)** — status: stable.

Positive: has types; no vulnerabilities.

Warnings: low downloads; no esm support.

## Facts

| | |
|---|---|
| Version | 1.0.8 |
| Published | 2026-01-09 |
| First published | 2025-11-23 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Node | >=18.0.0 |
| Dependencies | 2 |
| Unpacked size | 74.6 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | nx-intelligence |
| Maintainers | nx-morpheus |
| Keywords | json, storage, s3, mongodb, filesystem, remote |

## Links

- npm: https://www.npmjs.com/package/nx-remote-json
- Repository: https://github.com/nx-intelligence/remote-json
- Homepage: https://github.com/nx-intelligence/remote-json#readme
- Issues: https://github.com/nx-intelligence/remote-json/issues
- npm.io page: https://npm.io/package/nx-remote-json

## Dependencies (2)

- [mongodb](https://npm.io/package/mongodb.md) ^6.3.0
- [@aws-sdk/client-s3](https://npm.io/package/@aws-sdk/client-s3.md) ^3.490.0

## Alternatives

- [@mapbox/jsonlint-lines-primitives](https://npm.io/package/@mapbox/jsonlint-lines-primitives.md) — 5.3M weekly downloads
- [reftools](https://npm.io/package/reftools.md) — 3.5M weekly downloads
- [@hey-api/openapi-ts](https://npm.io/package/@hey-api/openapi-ts.md) — 3.5M weekly downloads
- [@mapbox/geojson-rewind](https://npm.io/package/@mapbox/geojson-rewind.md) — 2.4M weekly downloads
- [turbo-stream](https://npm.io/package/turbo-stream.md) — 1.7M weekly downloads

## Recent versions

- 1.0.8 (latest) — 2026-01-09
- 1.0.7 — 2026-01-09
- 1.0.6 — 2026-01-09
- 1.0.5 — 2026-01-09
- 1.0.4 — 2026-01-09
- 1.0.3 — 2026-01-09
- 1.0.2 — 2025-11-23
- 1.0.1 — 2025-11-23
- 1.0.0 — 2025-11-23

## README

# remote-json

A unified TypeScript SDK for reading, writing, and mirroring JSON objects across multiple backends: local filesystem (disk), S3-compatible object storage, and MongoDB.

## Package Information

- **Package**: `nx-remote-json`
- **Version**: 1.0.2
- **Runtime**: Node.js 18+
- **Language**: TypeScript 5+

## Features

- **Unified API**: Single interface for three different storage backends
- **Type-safe**: Full TypeScript support with comprehensive type definitions
- **Flexible routing**: Map logical routers to backend-specific locations
- **Mirroring**: Sync JSON objects between backends
- **Atomic operations**: Safe file writes and upsert operations

## Installation

```bash
npm install nx-remote-json
```

## Requirements

- Node.js 18+
- TypeScript 5+

## Quick Start

```typescript
import { 
  createRemoteJsonClient,
  type RemoteJsonConfig 
} from "nx-remote-json";

const config = {
  disk: {
    rootLocation: "/data/remote-json",
    defaultExtension: ".json",
    mapping: [
      { jsonRouter: "settings", folder: "settings" },
      { jsonRouter: "dashboards", folder: "dashboards" }
    ]
  }
};

const client = createRemoteJsonClient(config);

// Read
const settings = await client.read({
  mode: "disk",
  jsonRouter: "settings",
  jsonKey: "user-123"
});

// Write
await client.write({
  mode: "disk",
  jsonRouter: "settings",
  jsonKey: "user-123",
  payload: { theme: "dark", language: "en" }
});
```

## Configuration

### Disk Backend

```typescript
{
  disk: {
    rootLocation: "/data/remote-json",  // Base directory
    defaultExtension: ".json",          // Optional, defaults to ".json"
    mapping: [
      { jsonRouter: "settings", folder: "settings" },
      { jsonRouter: "dashboards", folder: "dashboards" }
    ]
  }
}
```

**Path resolution**: `rootLocation/folder/jsonKey.json`

### Storage Backend (S3-compatible)

```typescript
{
  storage: {
    region: "eu-central-1",
    endpoint: "https://s3.example.com",
    forcePathStyle: true,
    accessKey: "ACCESS_KEY",
    secretKey: "SECRET_KEY",
    bucket: "my-remote-json",
    defaultExtension: ".json",
    mapping: [
      { jsonRouter: "settings", folder: "settings" },
      { jsonRouter: "dashboards", folder: "dashboards" }
    ]
  }
}
```

**Object key resolution**: `folder/jsonKey.json`

### Database Backend (MongoDB)

```typescript
{
  database: {
    mongoUri: "mongodb://user:pass@localhost:27017",
    mongoDb: "remote_json",
    mapping: [
      { jsonRouter: "settings", collectionName: "settings" },
      { jsonRouter: "dashboards", collectionName: "dashboards" }
    ],
    queryFilters: [
      {
        field: "router",
        operator: "eq",
        valueSource: "literal",
        literalValue: "settings"
      },
      {
        field: "key",
        operator: "eq",
        valueSource: "jsonKey",
        transform: "none"
      }
    ]
  }
}
```

**Filter construction**: Filters are built from `queryFilters` templates and combined with `$and`. At least one filter must use `valueSource: "jsonKey"`.

**Write behavior**: Filter fields are automatically injected into documents during writes, ensuring the same `jsonKey` can always re-find the document.

## Type Exports

The package exports the following TypeScript types:

```typescript
import type {
  RemoteJsonConfig,        // Main configuration type
  RemoteJsonMode,          // "disk" | "storage" | "database"
  RemoteJsonClient,        // Client interface
  ReadRequest,             // Read operation request
  WriteRequest,            // Write operation request
  MirrorRequest,           // Mirror operation request
  MirrorResult,            // Mirror operation result
  DiskBackendConfig,       // Disk backend configuration
  StorageBackendConfig,    // Storage backend configuration
  DatabaseBackendConfig,   // Database backend configuration
  RemoteJsonError,         // Error class
  RemoteJsonErrorCode,     // Error code type
} from "nx-remote-json";
```

**Important:** The main configuration type is `RemoteJsonConfig`, not `RemoteJsonClientConfig`.

## API Reference

### `read<T>(req: ReadRequest): Promise<T | null>`

Reads a JSON object from the specified backend.

```typescript
const data = await client.read<MyType>({
  mode: "disk",
  jsonRouter: "settings",
  jsonKey: "user-123"
});

if (data === null) {
  console.log("Not found");
}
```

### `write<T>(req: WriteRequest<T>): Promise<void>`

Writes a JSON object to the specified backend.

```typescript
await client.write({
  mode: "storage",
  jsonRouter: "dashboards",
  jsonKey: "team-A",
  payload: {
    title: "Team A Dashboard",
    widgets: []
  }
});
```

### `mirror(req: MirrorRequest): Promise<MirrorResult>`

Mirrors JSON objects from a master backend to target backends.

```typescript
// Mirror one object
const result = await client.mirror({
  masterMode: "disk",
  jsonRouter: "settings",
  jsonKey: "user-123",
  targetModes: ["storage", "database"],
  overwriteExisting: true
});

// Mirror all objects in a router
const result = await client.mirror({
  masterMode: "disk",
  jsonRouter: "settings",
  targetModes: ["storage"]
});

// Mirror all routers
const result = await client.mirror({
  masterMode: "disk",
  targetModes: ["storage", "database"]
});
```

**Mirror options:**
- `masterMode`: Source backend (required)
- `jsonRouter`: Optional, limits to specific router
- `jsonKey`: Optional, limits to specific key
- `targetModes`: Optional, defaults to all configured modes except master
- `overwriteExisting`: Optional, defaults to `true`

**Result structure:**
```typescript
{
  items: [
    {
      jsonRouter: "settings",
      jsonKey: "user-123",
      sourceMode: "disk",
      targetMode: "storage",
      status: "created" | "updated" | "skipped" | "failed",
      error?: string
    }
  ]
}
```

## Error Handling

All methods throw `RemoteJsonError` with the following error codes:

- `CONFIG_ERROR`: Configuration is invalid
- `MAPPING_NOT_FOUND`: No mapping found for the specified jsonRouter
- `BACKEND_NOT_CONFIGURED`: Requested backend is not configured
- `SERIALIZATION_ERROR`: Failed to serialize JSON payload
- `DESERIALIZATION_ERROR`: Failed to parse JSON response
- `BACKEND_IO_ERROR`: Backend I/O operation failed

```typescript
import { RemoteJsonError } from "nx-remote-json";

try {
  await client.write({ ... });
} catch (err) {
  if (err instanceof RemoteJsonError) {
    console.error(`Error code: ${err.code}`);
    console.error(`Message: ${err.message}`);
    if (err.cause) {
      console.error(`Cause:`, err.cause);
    }
  }
}
```

## Examples

### Multi-backend Configuration

```typescript
const config = {
  disk: {
    rootLocation: "./data",
    mapping: [
      { jsonRouter: "settings", folder: "settings" }
    ]
  },
  storage: {
    region: "us-east-1",
    endpoint: "https://s3.amazonaws.com",
    forcePathStyle: false,
    accessKey: process.env.AWS_ACCESS_KEY_ID!,
    secretKey: process.env.AWS_SECRET_ACCESS_KEY!,
    bucket: "my-bucket",
    mapping: [
      { jsonRouter: "settings", folder: "settings" }
    ]
  },
  database: {
    mongoUri: process.env.MONGODB_URI!,
    mongoDb: "app_db",
    mapping: [
      { jsonRouter: "settings", collectionName: "settings" }
    ],
    queryFilters: [
      {
        field: "key",
        operator: "eq",
        valueSource: "jsonKey"
      }
    ]
  }
};

const client = createRemoteJsonClient(config);
```

### MongoDB with ObjectId

```typescript
{
  database: {
    // ... other config
    queryFilters: [
      {
        field: "_id",
        operator: "eq",
        valueSource: "jsonKey",
        transform: "objectId"  // Converts jsonKey to ObjectId
      }
    ]
  }
}
```

### Mirroring with Skip Existing

```typescript
// Only create new objects, skip existing ones
const result = await client.mirror({
  masterMode: "disk",
  jsonRouter: "settings",
  overwriteExisting: false  // Skip if already exists
});

const created = result.items.filter(i => i.status === "created");
const skipped = result.items.filter(i => i.status === "skipped");
```

## License

MIT

---
_Source: https://npm.io/package/nx-remote-json · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
