npm package: @quicore/resource-id
Description: Deterministic and compact ID generation for API resources using pluggable hashing.
Author: quicore
Latest version: 1.0.0

# @quicore/resource-id

A lightweight, pluggable utility for generating compact, deterministic, and integration-scoped resource identifiers using flexible components. Ideal for APIs, FHIR systems, and cross-service data referencing.

---

## ✨ Features

- 🔐 Compact deterministic ID generation using Blake2b + Base62
- 🧩 Component-based customization (resourceType, resourceId, integrationId)
- 📦 Works with any API data (not just FHIR)
- ⚙️ Chainable and extensible class structure
- 💾 MongoDB-friendly (22-character Base62 IDs by default)

---

## 📦 Installation

```bash
npm install @quicore/resource-id
````

---

## 🚀 Quick Start

```js
import { ResourceIDGenerator } from '@quicore/resource-id';

const id = new ResourceIDGenerator()
  .setIntegrationId('my-app')
  .setResourceType('Invoice')
  .setResourceId('INV-12345')
  .generate();

console.log(id); // Compact, consistent ID (e.g., "004f83akdT3mJLhFtVNckT")
```

---

## 🔄 Use Case

While originally designed for [FHIR](https://hl7.org/fhir/) resources, `ResourceIDGenerator` is **generic** and can be used for any API data:

* `resourceId` = the **unique identifier** of your data object
* `resourceType` = the **type/category** of your object (`"User"`, `"Invoice"`, `"Post"`, etc.)
* `integrationId` = a **scoping prefix** to prevent ID collisions across systems

---

## 📘 API Reference

### `class ResourceIDGenerator`

Extends `IDGenerator` and is ready to use out of the box.

#### `.setIntegrationId(id: string)`

Sets a prefix to scope the generated ID by system/environment.

#### `.setResourceType(type: string)`

Sets the type/category of the data object (e.g., `'User'`, `'Appointment'`).

#### `.setResourceId(id: string)`

Sets the primary unique identifier (e.g., a database or API ID).

#### `.setIdLength(length: number)`

(Optional) Set the output ID length (minimum 10, default 22).

#### `.generate() → string`

Returns a compact, Base62-encoded ID derived from all components.

---

### `class IDGenerator`

The base abstract class for deterministic ID generation. To extend:

```js
class MyCustomGenerator extends IDGenerator {
  createCanonicalString() {
    return `${this.components.a}-${this.components.b}`;
  }

  validateComponents() {
    if (!this.components.a || !this.components.b) {
      throw new Error('Missing required components');
    }
  }
}
```

---

## 🧬 Output Format

Internally, IDs are created by hashing this structure:

```
<integrationId>::<resourceType>::<resourceId>
```

Then encoded into a compact **Base62** string using `blake2b`.

---

## 🔐 Why Deterministic IDs?

* Guarantees the same input always gives the same ID
* Useful for deduplication, data sync, upserts, or ID federation
* Scope-aware via `integrationId` to prevent overlap

---

## 🔧 FHIR Support (Optional)

For FHIR-specific use, the package includes:

### `class FHIRIDGenerator`

```js
import { FHIRIDGenerator } from '@quicore/resource-id';

const resource = {
  id: 'abc123',
  resourceType: 'Patient'
};

const id = new FHIRIDGenerator(resource)
  .setIntegrationId('epic')
  .generate();

console.log(id); // e.g., "A81dskf9e3rKW2ThjL9bc3"
```

---

## 📄 License
MIT