types: Abstract inline interfaces to @plunk/types
This commit is contained in:
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Express.js type augmentation for Plunk platform
|
||||
* Extends Express Response.locals to include typed auth property
|
||||
*/
|
||||
|
||||
import type {AuthResponse} from './index.js';
|
||||
|
||||
declare global {
|
||||
namespace Express {
|
||||
interface Locals {
|
||||
/**
|
||||
* Authentication context for the current request
|
||||
* Set by auth middleware (requireAuth, requireSecretKey, requirePublicKey)
|
||||
*/
|
||||
auth: AuthResponse;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Authentication and authorization types
|
||||
*/
|
||||
|
||||
/**
|
||||
* Authentication response data attached to Express Response.locals
|
||||
* Contains authentication context for the current request
|
||||
*/
|
||||
export interface AuthResponse {
|
||||
/** Authentication method used (JWT cookie or API key) */
|
||||
type: 'jwt' | 'apiKey';
|
||||
|
||||
/** User ID (only present for JWT authentication) */
|
||||
userId?: string;
|
||||
|
||||
/** Project ID associated with this request */
|
||||
projectId: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type guard to check if auth is JWT-based
|
||||
*/
|
||||
export function isJwtAuth(auth: AuthResponse): auth is AuthResponse & {userId: string} {
|
||||
return auth.type === 'jwt' && !!auth.userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type guard to check if auth is API key-based
|
||||
*/
|
||||
export function isApiKeyAuth(auth: AuthResponse): auth is AuthResponse & {userId: undefined} {
|
||||
return auth.type === 'apiKey';
|
||||
}
|
||||
@@ -12,6 +12,9 @@ export * from './jobs/index.js';
|
||||
// API service types
|
||||
export * from './api/index.js';
|
||||
|
||||
// Authentication types
|
||||
export * from './auth/index.js';
|
||||
|
||||
// Notification types
|
||||
export * from './notifications/index.js';
|
||||
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Type-safe utilities for working with Prisma JSON fields
|
||||
*
|
||||
* Prisma's JSON types are intentionally loose to support the dynamic nature of JSON.
|
||||
* These helpers provide a safer interface while acknowledging the runtime limitations.
|
||||
*/
|
||||
|
||||
import {Prisma} from '@plunk/db';
|
||||
|
||||
/**
|
||||
* Safely convert a value to Prisma.InputJsonValue for storing in JSON fields
|
||||
*
|
||||
* This helper provides better type safety than direct casting while acknowledging
|
||||
* that Prisma cannot validate the JSON structure at compile time.
|
||||
*
|
||||
* @template T - The type being stored (for documentation purposes)
|
||||
* @param value - The value to convert to Prisma JSON format
|
||||
* @returns The value as Prisma.InputJsonValue
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // Filter condition (complex nested object)
|
||||
* const condition: FilterCondition = { logic: 'AND', groups: [...] };
|
||||
* await prisma.segment.create({
|
||||
* data: {
|
||||
* condition: toPrismaJson(condition)
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* // Simple object
|
||||
* const headers = { 'X-Custom': 'value' };
|
||||
* await prisma.email.create({
|
||||
* data: {
|
||||
* headers: toPrismaJson(headers)
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function toPrismaJson<T>(value: T | null | undefined): Prisma.InputJsonValue {
|
||||
// Prisma.InputJsonValue accepts: string | number | boolean | null | JsonObject | JsonArray
|
||||
// We trust that T is JSON-serializable at runtime (including null)
|
||||
return value as unknown as Prisma.InputJsonValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely convert Prisma.JsonValue to a typed value when reading from JSON fields
|
||||
*
|
||||
* IMPORTANT: This does NOT perform runtime validation. It's a type-safe way to
|
||||
* document what type you expect, but the caller must validate if needed.
|
||||
*
|
||||
* @template T - The expected type
|
||||
* @param value - The JSON value from Prisma
|
||||
* @returns The value as type T
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const segment = await prisma.segment.findUnique({ where: { id } });
|
||||
* const condition = fromPrismaJson<FilterCondition>(segment.condition);
|
||||
* // condition is now typed as FilterCondition (but not validated)
|
||||
* ```
|
||||
*/
|
||||
export function fromPrismaJson<T>(value: Prisma.JsonValue): T {
|
||||
return value as unknown as T;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional version of fromPrismaJson that handles null/undefined
|
||||
*
|
||||
* @template T - The expected type
|
||||
* @param value - The JSON value from Prisma (may be null/undefined)
|
||||
* @returns The value as type T or undefined
|
||||
*/
|
||||
export function fromPrismaJsonOptional<T>(value: Prisma.JsonValue | null | undefined): T | undefined {
|
||||
if (value === null || value === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
return value as unknown as T;
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
export * from './extended.js';
|
||||
export * from './helpers.js';
|
||||
|
||||
Reference in New Issue
Block a user