feat: add constants, types, and shared schemas

This commit is contained in:
2026-03-30 13:52:29 +02:00
parent d98ed5733d
commit 033a29077e
3 changed files with 142 additions and 0 deletions
+24
View File
@@ -0,0 +1,24 @@
export const DEFAULT_API_BASE_URL = "https://api.novu.co";
export const CHARACTER_LIMIT = 25_000;
export const DEFAULT_PAGE_LIMIT = 20;
export const MAX_PAGE_LIMIT = 100;
export enum ResponseFormat {
MARKDOWN = "markdown",
JSON = "json",
}
export function getApiBaseUrl(): string {
return process.env.NOVU_API_URL || DEFAULT_API_BASE_URL;
}
export function getApiKey(): string {
const key = process.env.NOVU_SECRET_KEY;
if (!key) {
throw new Error(
"NOVU_SECRET_KEY environment variable is required. " +
"Get your API key from the Novu Dashboard: https://dashboard.novu.co"
);
}
return key;
}
+52
View File
@@ -0,0 +1,52 @@
import { z } from "zod";
import {
ResponseFormat,
MAX_PAGE_LIMIT,
DEFAULT_PAGE_LIMIT,
} from "../constants.js";
/** Offset-based pagination for v1 API */
export const PaginationV1Schema = {
limit: z
.number()
.int()
.min(1)
.max(MAX_PAGE_LIMIT)
.default(DEFAULT_PAGE_LIMIT)
.describe("Maximum number of results to return (1-100)"),
offset: z
.number()
.int()
.min(0)
.default(0)
.describe("Number of results to skip for pagination"),
};
/** Cursor-based pagination for v2 API (Topics) */
export const PaginationV2Schema = {
limit: z
.number()
.int()
.min(1)
.max(MAX_PAGE_LIMIT)
.default(DEFAULT_PAGE_LIMIT)
.describe("Maximum number of results to return (1-100)"),
after: z
.string()
.optional()
.describe("Cursor for fetching the next page of results"),
before: z
.string()
.optional()
.describe("Cursor for fetching the previous page of results"),
};
/** Response format param */
export const ResponseFormatSchema = {
response_format: z
.nativeEnum(ResponseFormat)
.default(ResponseFormat.JSON)
.describe(
"Output format: 'json' for structured data or 'markdown' for human-readable"
),
};
+66
View File
@@ -0,0 +1,66 @@
/** Standard v1 paginated list response wrapper */
export interface PaginatedListV1<T> {
data: T[];
totalCount: number;
pageSize: number;
page: number;
hasMore: boolean;
}
/** Standard v2 cursor-based paginated response (used by Topics) */
export interface PaginatedListV2<T> {
data: T[];
next: string | null;
previous: string | null;
totalCount: number;
totalCountCapped: boolean;
}
/** Subscriber shape from Novu API */
export interface Subscriber {
id?: string;
subscriberId?: string;
firstName?: string | null;
lastName?: string | null;
email?: string | null;
phone?: string | null;
avatar?: string | null;
locale?: string | null;
timezone?: string | null;
data?: Record<string, unknown> | null;
isOnline?: boolean | null;
lastOnlineAt?: string | null;
createdAt?: string;
updatedAt?: string;
}
/** Topic shape */
export interface Topic {
_id: string;
key: string;
name?: string;
createdAt?: string;
updatedAt?: string;
}
/** Workflow shape */
export interface Workflow {
id?: string;
name?: string;
description?: string;
active?: boolean;
draft?: boolean;
tags?: string[];
steps?: unknown[];
triggers?: unknown[];
createdAt?: string;
updatedAt?: string;
}
/** Trigger event response */
export interface TriggerResponse {
acknowledged: boolean;
status: string;
error?: string[];
transactionId?: string;
}