https://github.com/kopexa-grc/krn-js
Kopexa Resource Names (KRN) - TypeScript implementation following Google's Resource Name Design
https://github.com/kopexa-grc/krn-js
compliance grc kopexa krn npm resource-names typescript
Last synced: 3 months ago
JSON representation
Kopexa Resource Names (KRN) - TypeScript implementation following Google's Resource Name Design
- Host: GitHub
- URL: https://github.com/kopexa-grc/krn-js
- Owner: kopexa-grc
- License: apache-2.0
- Created: 2026-01-14T17:43:45.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2026-01-14T19:39:26.000Z (5 months ago)
- Last Synced: 2026-01-14T22:54:34.218Z (5 months ago)
- Topics: compliance, grc, kopexa, krn, npm, resource-names, typescript
- Language: TypeScript
- Homepage: https://kopexa.com
- Size: 78.1 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
- Codeowners: .github/CODEOWNERS
- Security: SECURITY.md
Awesome Lists containing this project
README
# @kopexa/krn - Kopexa Resource Names
**Part of the [Kopexa](https://kopexa.com) GRC Platform**
[](https://www.npmjs.com/package/@kopexa/krn)
[](https://github.com/kopexa-grc/krn-js/actions/workflows/ci.yml)
[](https://opensource.org/licenses/Apache-2.0)
A TypeScript package for working with Kopexa Resource Names (KRN), following [Google's Resource Name Design](https://cloud.google.com/apis/design/resource_names).
## Installation
```bash
npm install @kopexa/krn
# or
pnpm add @kopexa/krn
# or
yarn add @kopexa/krn
```
## KRN Specification
### Format
```
//kopexa.com/{collection}/{resource-id}[/{collection}/{resource-id}][@{version}]
//{service}.kopexa.com/{collection}/{resource-id}[/{collection}/{resource-id}][@{version}]
```
### Components
| Component | Description | Example |
|-----------|-------------|---------|
| Service | Optional service subdomain | `catalog`, `isms`, `policy` |
| Domain | Always `kopexa.com` | `kopexa.com` |
| Collection | Resource type (plural) | `frameworks`, `controls`, `tenants` |
| Resource ID | Unique identifier | `iso27001`, `5.1.1`, `acme-corp` |
| Version | Optional version tag | `@v1`, `@v1.2.3`, `@latest`, `@draft` |
### Examples
```
//kopexa.com/frameworks/iso27001
//kopexa.com/frameworks/iso27001/controls/5.1.1
//catalog.kopexa.com/frameworks/iso27001
//catalog.kopexa.com/frameworks/iso27001/controls/5.1.1@v2
//isms.kopexa.com/tenants/acme-corp/workspaces/main
```
## Usage
### Parsing KRNs
```typescript
import { KRN } from "@kopexa/krn";
// Parse a KRN string
const k = KRN.parse("//kopexa.com/frameworks/iso27001");
// Parse without throwing (returns null on error)
const k2 = KRN.tryParse("//kopexa.com/frameworks/iso27001");
if (k2) {
console.log(k2.basename());
}
// Check if a string is a valid KRN
if (KRN.isValid(s)) {
// ...
}
```
### Building KRNs
```typescript
import { krn } from "@kopexa/krn";
// Build a simple KRN
const k = krn()
.resource("frameworks", "iso27001")
.build();
// Result: //kopexa.com/frameworks/iso27001
// Build a nested KRN with version
const k2 = krn()
.resource("frameworks", "iso27001")
.resource("controls", "a-5-1")
.version("v2")
.build();
// Result: //kopexa.com/frameworks/iso27001/controls/a-5-1@v2
// Build a KRN with service
const k3 = krn()
.service("catalog")
.resource("frameworks", "iso27001")
.build();
// Result: //catalog.kopexa.com/frameworks/iso27001
// Build without throwing (returns null on error)
const k4 = krn().resource("frameworks", "iso27001").tryBuild();
```
### Creating Child KRNs
```typescript
const parent = KRN.parse("//kopexa.com/frameworks/iso27001");
// Create a child KRN
const child = parent.child("controls", "a-5-1");
// Result: //kopexa.com/frameworks/iso27001/controls/a-5-1
```
### Extracting Information
```typescript
const k = KRN.parse("//catalog.kopexa.com/frameworks/iso27001/controls/5.1.1@v1");
k.service; // "catalog"
k.hasService(); // true
k.fullDomain(); // "catalog.kopexa.com"
k.path(); // "frameworks/iso27001/controls/5.1.1"
k.version; // "v1"
k.hasVersion(); // true
k.basename(); // "5.1.1"
k.basenameCollection(); // "controls"
k.depth(); // 2
// Get resource ID by collection
const frameworkId = k.resourceId("frameworks"); // "iso27001"
const controlId = k.tryResourceId("controls"); // "5.1.1" or null
// Check if a collection exists
k.hasResource("frameworks"); // true
k.hasResource("policies"); // false
// Get all segments
for (const seg of k.segments()) {
console.log(`${seg.collection}: ${seg.resourceId}`);
}
```
### Working with Parents
```typescript
const k = KRN.parse("//kopexa.com/frameworks/iso27001/controls/a-5-1");
const parent = k.parent();
// Result: //kopexa.com/frameworks/iso27001
// Root resources return null
const root = KRN.parse("//kopexa.com/frameworks/iso27001");
root.parent(); // null
```
### Version Manipulation
```typescript
const k = KRN.parse("//kopexa.com/frameworks/iso27001");
// Add version
const versioned = k.withVersion("v1.2.3");
// Result: //kopexa.com/frameworks/iso27001@v1.2.3
// Remove version
const k2 = KRN.parse("//kopexa.com/frameworks/iso27001@v1");
const unversioned = k2.withoutVersion();
// Result: //kopexa.com/frameworks/iso27001
```
### Service Manipulation
```typescript
const k = KRN.parse("//kopexa.com/frameworks/iso27001");
// Add service
const withService = k.withService("catalog");
// Result: //catalog.kopexa.com/frameworks/iso27001
// Remove service
const k2 = KRN.parse("//catalog.kopexa.com/frameworks/iso27001");
const withoutService = k2.withoutService();
// Result: //kopexa.com/frameworks/iso27001
```
### Comparison
```typescript
const k1 = KRN.parse("//kopexa.com/frameworks/iso27001");
const k2 = KRN.parse("//kopexa.com/frameworks/iso27001");
k1.equals(k2); // true
k1.equalsString("//kopexa.com/frameworks/iso27001"); // true
```
### Framework Versioning
Compliance frameworks often have different editions (e.g., ISO 27001:2013 vs ISO 27001:2022).
Include the edition year or version number in the framework resource ID:
```typescript
// ISO 27001:2022
const k1 = KRN.parse("//catalog.kopexa.com/frameworks/iso27001-2022/controls/5.1.1");
// NIST CSF 2.0
const k2 = KRN.parse("//catalog.kopexa.com/frameworks/nist-csf-2.0/controls/GV.OC-01");
// CIS AWS Benchmark v1.4.0
const k3 = KRN.parse("//catalog.kopexa.com/frameworks/cis-aws-1.4.0/controls/1.1.1");
```
**Naming conventions:**
- Use lowercase with hyphens: `iso27001-2022`, `nist-csf-2.0`
- Include the year or version: `iso27001-2022`, `cis-aws-1.4.0`
- Keep it readable: `pci-dss-4.0` not `pcidssv4.0`
**Note:** The `@version` suffix (e.g., `@v1`, `@draft`) is for versioning the KRN content itself
(like draft vs published mappings), not for framework editions.
### Utility Functions
```typescript
import {
getResource,
isValidResourceId,
isValidVersion,
isValidService,
safeResourceId
} from "@kopexa/krn";
// Quick resource extraction from string
const id = getResource("//kopexa.com/frameworks/iso27001", "frameworks");
// Result: "iso27001"
// Validate resource IDs
isValidResourceId("valid-id"); // true
isValidResourceId("-invalid"); // false
// Validate versions
isValidVersion("v1.2.3"); // true
isValidVersion("latest"); // true
isValidVersion("invalid"); // false
// Validate service names
isValidService("catalog"); // true
isValidService("Catalog"); // false (must be lowercase)
isValidService("1svc"); // false (can't start with number)
// Convert strings to valid resource IDs
safeResourceId("Hello World!"); // "Hello-World"
```
## Service Name Rules
Service names must follow DNS label rules:
- Length: 1-63 characters
- Allowed characters: `a-z`, `0-9`, `-`
- Must start with a letter
- Cannot end with `-`
## Resource ID Rules
Resource IDs must follow these rules:
- Length: 1-200 characters
- Allowed characters: `a-z`, `A-Z`, `0-9`, `-`, `_`, `.`
- Cannot start or end with `-` or `.`
## Version Formats
Supported version formats:
- Semantic: `v1`, `v1.2`, `v1.2.3`
- Keywords: `latest`, `draft`
## Error Handling
The package exports a `KRNError` class with error codes:
```typescript
import { KRN, KRNError, KRNErrorCode } from "@kopexa/krn";
try {
const k = KRN.parse(input);
} catch (err) {
if (err instanceof KRNError) {
switch (err.code) {
case KRNErrorCode.EMPTY_KRN:
// Handle empty input
break;
case KRNErrorCode.INVALID_KRN:
// Handle invalid format
break;
case KRNErrorCode.INVALID_DOMAIN:
// Handle wrong domain
break;
case KRNErrorCode.INVALID_RESOURCE_ID:
// Handle invalid resource ID
break;
case KRNErrorCode.INVALID_VERSION:
// Handle invalid version format
break;
case KRNErrorCode.RESOURCE_NOT_FOUND:
// Handle missing resource
break;
}
}
}
```
## Related Packages
- [github.com/kopexa-grc/krn](https://github.com/kopexa-grc/krn) - Go implementation (source of truth)
- [krn-fixtures](https://github.com/kopexa-grc/krn-fixtures) - Shared test fixtures
## About Kopexa
[Kopexa](https://kopexa.com) is a modern GRC (Governance, Risk, and Compliance) platform that helps organizations manage their compliance requirements efficiently.
- **Website**: [kopexa.com](https://kopexa.com)
- **Documentation**: [docs.kopexa.com](https://docs.kopexa.com)
## License
Copyright (c) [Kopexa GRC](https://kopexa.com)
Licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for details.