@narrative.io/data-collaboration-sdk-ts
v3.8.0
Published
[](https://www.npmjs.com/package/@narrative.io/data-collaboration-sdk-ts)
Readme
Narrative.io Data Collaboration SDK for TypeScript
The official TypeScript SDK for the Narrative.io Data Collaboration Platform. This SDK provides a simple and intuitive interface for interacting with Narrative's APIs, allowing you to manage datasets, subscriptions, data streams, and more.
Table of Contents
- Installation
- Quick Start
- API Overview
- Usage Examples
- Configuration
- TypeScript Support
- Error Handling
- API Reference
- Contributing
- License
Installation
Install the SDK using npm:
npm install @narrative.io/data-collaboration-sdk-tsOr using yarn:
yarn add @narrative.io/data-collaboration-sdk-tsOr using bun:
bun add @narrative.io/data-collaboration-sdk-tsQuick Start
import { NarrativeApi } from '@narrative.io/data-collaboration-sdk-ts';
// Initialize the SDK with your API key
const narrative = new NarrativeApi({
apiKey: 'your-api-key-here',
environment: 'prod' // 'prod' or 'dev'
});
// Make your first API call
async function getMyCompanyInfo() {
try {
const companyInfo = await narrative.getCompanyInfo();
console.log('Company:', companyInfo);
} catch (error) {
console.error('Error:', error);
}
}
getMyCompanyInfo();API Overview
The SDK provides access to the following Narrative.io API modules:
Core APIs
- Authentication - Manage API authentication
- Company Info - Retrieve company information
- Health Check - Check API health status
- Who Am I - Get current user information
Data Management
- Datasets - Create and manage datasets
- Data Streams - Configure real-time data streams
- Data Planes - Manage data plane configurations
- Subscriptions - Handle data subscriptions
- Uploads - Upload data files
Data Operations
- Queries - Execute data queries
- Forecast - Generate data forecasts
- NQL (Narrative Query Language) - Build and execute NQL queries
- Views - Create and manage data views
Marketplace & Collaboration
- Products - Browse and manage data products
- Contracts - Handle data contracts
- Connections - Manage data connections
- Installations - Track app installations
Advanced Features
- Attributes - Define data attributes
- Mappings - Configure data mappings
- Models - Work with ML models
- Model Training - Train custom models
- Rosetta Stone - Data transformation tools
- Access Rules - Set data access permissions
- Access Tokens - Manage API tokens
- Encryption Materials - Handle encryption keys
Usage Examples
Working with Datasets
// List all datasets
const datasets = await narrative.getDatasets();
console.log(`Found ${datasets.length} datasets`);
// Get a specific dataset
const datasetId = 'your-dataset-id';
const dataset = await narrative.getDataset(datasetId);
console.log('Dataset name:', dataset.name);
// Create a new dataset
const newDataset = await narrative.createDataset({
name: 'My New Dataset',
description: 'A dataset created via SDK',
schema: {
// Your schema definition
}
});Managing Subscriptions
// List active subscriptions
const subscriptions = await narrative.getSubscriptions();
subscriptions.forEach(sub => {
console.log(`Subscription: ${sub.name} - Status: ${sub.status}`);
});
// Create a subscription
const subscription = await narrative.createSubscription({
name: 'Daily Data Feed',
datasetId: 'dataset-id',
frequency: 'daily'
});Executing NQL Queries
// Build and execute an NQL query
const nqlQuery = `
SELECT *
FROM narrative.datasets
WHERE created_date >= '2024-01-01'
LIMIT 100
`;
const results = await narrative.executeNql(nqlQuery);
console.log('Query returned', results.rows.length, 'rows');Uploading Data
// Upload a file to a dataset
const upload = await narrative.createUpload({
datasetId: 'your-dataset-id',
fileName: 'data.csv',
fileSize: 1024000 // Size in bytes
});
// Get the upload URL and upload your file
console.log('Upload URL:', upload.uploadUrl);
// Use the uploadUrl to PUT your file dataConfiguration
Environment Configuration
The SDK supports multiple environments:
// Production environment (default)
const narrativeProd = new NarrativeApi({
apiKey: 'your-api-key'
});
// Development environment
const narrativeDev = new NarrativeApi({
apiKey: 'your-api-key',
environment: 'dev'
});Custom Headers
Add custom headers to all requests:
const narrative = new NarrativeApi({
apiKey: 'your-api-key',
headers: {
'X-Custom-Header': 'custom-value'
}
});API Key Management
Store your API key securely using environment variables:
// .env file
NARRATIVE_API_KEY=your-api-key-here
// Your code
import { NarrativeApi } from '@narrative.io/data-collaboration-sdk-ts';
const narrative = new NarrativeApi({
apiKey: process.env.NARRATIVE_API_KEY!
});TypeScript Support
The SDK is written in TypeScript and provides comprehensive type definitions:
import {
NarrativeApi,
Dataset,
Subscription,
DataStream,
NqlQuery
} from '@narrative.io/data-collaboration-sdk-ts';
// Type-safe API calls
const narrative = new NarrativeApi({
apiKey: 'your-api-key'
});
// TypeScript will provide intellisense and type checking
const dataset: Dataset = await narrative.getDataset('dataset-id');
const subscriptions: Subscription[] = await narrative.getSubscriptions();Working with Types
import type {
Config,
PaginationOptions,
Dataset,
CreateDatasetRequest
} from '@narrative.io/data-collaboration-sdk-ts';
// Use types for better code organization
const config: Config = {
apiKey: process.env.NARRATIVE_API_KEY!,
environment: 'prod'
};
const paginationOptions: PaginationOptions = {
limit: 100,
offset: 0
};Error Handling
The SDK provides detailed error information:
import { NarrativeApi } from '@narrative.io/data-collaboration-sdk-ts';
const narrative = new NarrativeApi({
apiKey: 'your-api-key'
});
try {
const dataset = await narrative.getDataset('non-existent-id');
} catch (error) {
if (error.response) {
// API returned an error response
console.error('API Error:', error.response.status);
console.error('Error Message:', error.response.data.message);
} else if (error.request) {
// Request was made but no response received
console.error('Network Error:', error.message);
} else {
// Something else happened
console.error('Error:', error.message);
}
}Common Error Patterns
// Handle specific error codes
try {
const result = await narrative.someApiCall();
} catch (error) {
if (error.response?.status === 401) {
console.error('Authentication failed. Check your API key.');
} else if (error.response?.status === 404) {
console.error('Resource not found.');
} else if (error.response?.status === 429) {
console.error('Rate limit exceeded. Please retry later.');
} else {
console.error('Unexpected error:', error);
}
}Centralized Error Handling
Instead of repeating try/catch normalization at every call site, you can register a
single errorTransformer on the client. It runs once per failed request — for both
non-2xx responses (as an HttpError) and native fetch/network rejections — after the
HttpError (with its parsed body) has been built. Whatever it returns is thrown in
its place, so you can map transport failures onto your own application error types.
The SDK only supplies the mechanism; your application decides what a failure means.
The SDK does not log out, retry, redirect, show a toast, or treat any status as fatal
on your behalf. A 500, for example, is not automatically application-fatal — that
policy is yours to define. This keeps the SDK framework-agnostic: no Vue, Nuxt, Pinia,
or other UI dependency is involved.
import {
NarrativeApi,
HttpError,
type HttpRequestContext,
} from '@narrative.io/data-collaboration-sdk-ts';
// Your application's own error types — the SDK does not define these.
class AuthenticationRequiredError extends Error {}
class ApiServerError extends Error {}
const narrative = new NarrativeApi({
apiKey: process.env.NARRATIVE_API_KEY!,
errorTransformer(error: unknown, context: HttpRequestContext) {
// Only HTTP responses carry a status; network rejections do not.
if (error instanceof HttpError) {
const status = error.response.status;
if (status === 401) {
return new AuthenticationRequiredError(
`Authentication required for ${context.method} ${context.url}`,
);
}
if (status >= 500) {
return new ApiServerError(`Server error (${status})`);
}
}
// Return `undefined` (or the original `error`) to rethrow it unchanged.
return undefined;
},
});Semantics:
- The transformer runs exactly once per failed request, always after the
HttpErrorand its parsedbodyare available. - Returning the original
errorpreserves its object identity. - Returning a replacement causes that value to be thrown instead.
- Returning
undefinedmeans "rethrow the original error unchanged" — identical to having no transformer. - If the transformer itself throws or rejects, that error propagates and the transformer is not invoked a second time.
contextintentionally exposes onlymethodandurl. Request bodies and headers (includingAuthorization) are never passed to the transformer.
Custom fetch Implementation
By default the SDK uses globalThis.fetch. You can supply your own implementation —
useful for tests, instrumentation, or non-browser runtimes:
const narrative = new NarrativeApi({
apiKey: process.env.NARRATIVE_API_KEY!,
fetch: myCustomFetch, // defaults to globalThis.fetch
});API Reference
For detailed API documentation, please visit the Narrative.io API Documentation.
Local Development: Use This SDK Locally in a Consumer App (No Publish Needed)
Link this SDK into another local app (e.g. a Nuxt 3 project) and iterate without publishing to npm. Both modes consume the SDK's built output in build/**, exactly like the published package — the only difference is how the bytes reach the app's node_modules:
- Linked mode (default) —
bun linksymlinks this repo into the app; withtsc -wrunning,src/**edits flow live. - Tarball mode —
bun pm pack→ the app installs the.tgz(exact publish parity, a snapshot).
The full flow (build → link/pack → install → verify resolution) is automated by two bun run scripts (backed by scripts/link-local.sh and scripts/unlink-local.sh). Both default the consumer app to ~/narrative/narrative-platform-ui (override with --app PATH or $NARRATIVE_UI_DIR). Pass flags after a -- so bun forwards them to the script.
bun run scripts
Set up — bun run link:local (build → register/pack → install into the app → verify it resolves into this repo):
# Linked mode into the default app, then verify resolution
bun run link:local
# A different consumer app
bun run link:local -- --app /abs/path/to/app
# Tarball mode (exact publish parity)
bun run link:local -- --mode tarball
# SDK side only (build + register/pack); prints the app-side command to run by hand
bun run link:local -- --sdk-onlyFor live edits in linked mode, keep the watcher running in this repo so src/** edits rebuild build/**:
bun run dev # tsc -w → continuously rewrites build/**Tear down — bun run unlink:local (stop the watcher → unlink from the app and reinstall the published package → deregister the global link):
# Undo everything for the default app
bun run unlink:local
# Preview without changing anything
bun run unlink:local -- --dry-runFlags: --app PATH, --no-reinstall (leave the SDK uninstalled), --keep-global-link, --no-kill-watcher, --dry-run.
Lowest level (plain bun, no scripts)
# Linked mode — SDK repo, then the app
bun install && bun run build && bun run link:global
bun link @narrative.io/data-collaboration-sdk-ts # in the app
# Tarball mode — SDK repo, then the app
bun run build && bun run pack:dist # → ./<name>-<version>.tgz
bun add /ABS/PATH/TO/<name>-<version>.tgz # in the app
# Verify from the app — must resolve into this SDK repo (linked) or the tarball
node -e "console.log(require.resolve('@narrative.io/data-collaboration-sdk-ts/package.json'))"
# Revert (in the app)
bun remove @narrative.io/data-collaboration-sdk-ts
bun add @narrative.io/data-collaboration-sdk-ts # or @<semver>Troubleshooting (Nuxt 3 / Vite / SSR)
“Cannot use import statement outside a module” (SSR): Inline the SDK so Nitro bundles it.
// nuxt.config.ts export default defineNuxtConfig({ nitro: { externals: { inline: ['@narrative.io/data-collaboration-sdk-ts'] } } })Build artifacts not updating: Ensure
bun run devis running in the SDK repo (TypeScript watch), and that the app is linked (or reinstalled from a fresh tarball).Accidental imports from
src/*: Consumers should import from the package root only. This SDK publishesbuild/**and definesmain/types(and may include anexportsmap) to preventsrc/*imports.Type/version drift (e.g., Zod): If your app and the SDK use different major versions of a library whose types appear in public APIs, align versions or declare that library as a
peerDependencyin the SDK.
