Remove AuthProvider interface from World and associated implementations (#49)

* Remove `AuthProvider` interface from `World` and associated implementations

The `getAuthInfo()` and `checkHealth()` were never being used. Let's
from from the World interface to simplify things for implementors.

* .

* .
This commit is contained in:
Nathan Rajlich
2025-10-25 12:43:51 -07:00
committed by GitHub
parent d3a4ed34f4
commit 7868434a42
11 changed files with 15 additions and 152 deletions
+8
View File
@@ -0,0 +1,8 @@
---
"@workflow/world-postgres": patch
"@workflow/world-vercel": patch
"@workflow/world-local": patch
"@workflow/world": patch
---
Remove `AuthProvider` interface from `World` and associated implementations
-20
View File
@@ -1,20 +0,0 @@
import type { AuthProvider } from '@workflow/world';
export const auth: AuthProvider = {
async getAuthInfo() {
return {
ownerId: 'embedded-owner',
projectId: 'embedded-project',
environment: 'embedded',
userId: 'embedded-user',
};
},
async checkHealth() {
return {
success: true,
data: { healthy: true },
message: 'Embedded backend is healthy',
};
},
};
+1 -3
View File
@@ -1,12 +1,11 @@
import type { World } from '@workflow/world';
import { auth } from './auth.js';
import { config } from './config.js';
import { createQueue } from './queue.js';
import { createStorage } from './storage.js';
import { createStreamer } from './streamer.js';
/**
* Creates an embedded world instance that combines queue, storage, streamer, and authentication functionalities.
* Creates an embedded world instance that combines queue, storage, and streamer functionalities.
*
* @param dataDir - The directory to use for storage. If not provided, the default data dir will be used.
* @param port - The port to use for the queue. If not provided, the default port will be used.
@@ -24,6 +23,5 @@ export function createEmbeddedWorld({
...createQueue(queuePort),
...createStorage(dir),
...createStreamer(dir),
...auth,
};
}
+1 -42
View File
@@ -1,4 +1,4 @@
import type { AuthProvider, Storage, World } from '@workflow/world';
import type { Storage, World } from '@workflow/world';
import PgBoss from 'pg-boss';
import createPostgres from 'postgres';
import type { PostgresWorldConfig } from './config.js';
@@ -21,45 +21,6 @@ function createStorage(drizzle: Drizzle): Storage {
};
}
function createAuthProvider(
_config: PostgresWorldConfig,
boss: PgBoss
): AuthProvider {
return {
async getAuthInfo() {
return {
environment: 'postgres',
ownerId: 'postgres',
projectId: 'postgres',
};
},
async checkHealth() {
try {
if (!(await boss.isInstalled())) {
throw new Error('Postgres Boss is not installed properly');
}
} catch (err) {
return {
success: false,
data: { healthy: false },
message:
err &&
typeof err === 'object' &&
'message' in err &&
typeof err.message === 'string'
? err.message
: String(err),
};
}
return {
success: true,
message: 'Postgres connection is healthy',
data: { healthy: true },
};
},
};
}
export function createWorld(
config: PostgresWorldConfig = {
connectionString:
@@ -79,12 +40,10 @@ export function createWorld(
const queue = createQueue(boss, config);
const storage = createStorage(drizzle);
const streamer = createStreamer(postgres, drizzle);
const auth = createAuthProvider(config, boss);
return {
...storage,
...streamer,
...auth,
...queue,
async start() {
await queue.start();
-37
View File
@@ -1,37 +0,0 @@
import {
type AuthInfo,
AuthInfoSchema,
type AuthProvider,
type HealthCheckResponse,
HealthCheckResponseSchema,
} from '@workflow/world';
import type { APIConfig } from './utils.js';
import { makeRequest } from './utils.js';
// Functions
export async function getAuthInfo(config?: APIConfig): Promise<AuthInfo> {
return makeRequest({
endpoint: '/v1',
options: { method: 'GET' },
config,
schema: AuthInfoSchema,
});
}
export async function checkHealth(
config?: APIConfig
): Promise<HealthCheckResponse> {
return makeRequest({
endpoint: '/v1/health',
options: { method: 'GET' },
config,
schema: HealthCheckResponseSchema,
});
}
export function createAuth(config?: APIConfig): AuthProvider {
return {
checkHealth: () => checkHealth(config),
getAuthInfo: () => getAuthInfo(config),
};
}
+2 -8
View File
@@ -1,11 +1,9 @@
import type { AuthProvider, Storage, Streamer } from '@workflow/world';
import type { Storage, Streamer } from '@workflow/world';
import { createStorage } from './storage.js';
import { createStreamer } from './streamer.js';
import type { APIConfig } from './utils.js';
export function createVercel(
config?: APIConfig
): Streamer & Storage & AuthProvider {
export function createVercel(config?: APIConfig): Streamer & Storage {
const storage = createStorage(config);
const streamer = createStreamer(config);
@@ -15,10 +13,6 @@ export function createVercel(
closeStream: streamer.closeStream,
readFromStream: streamer.readFromStream,
// AuthProvider interface
getAuthInfo: storage.getAuthInfo,
checkHealth: storage.checkHealth,
// Storage interface with namespaced methods
runs: storage.runs,
steps: storage.steps,
-2
View File
@@ -1,5 +1,4 @@
import type { World } from '@workflow/world';
import { createAuth } from './auth.js';
import { createQueue } from './queue.js';
import { createStorage } from './storage.js';
import { createStreamer } from './streamer.js';
@@ -14,7 +13,6 @@ export function createVercelWorld(config?: APIConfig): World {
return {
...createQueue(),
...createStorage(config),
...createAuth(config),
...createStreamer(config),
};
}
+2 -7
View File
@@ -1,5 +1,4 @@
import type { AuthProvider, Storage } from '@workflow/world';
import { checkHealth, getAuthInfo } from './auth.js';
import type { Storage } from '@workflow/world';
import { createWorkflowRunEvent, getWorkflowRunEvents } from './events.js';
import {
createHook,
@@ -25,12 +24,8 @@ import {
} from './steps.js';
import type { APIConfig } from './utils.js';
export function createStorage(config?: APIConfig): Storage & AuthProvider {
export function createStorage(config?: APIConfig): Storage {
return {
// AuthProvider interface
getAuthInfo: () => getAuthInfo(config),
checkHealth: () => checkHealth(config),
// Storage interface with namespaced methods
runs: {
create: (data) => createWorkflowRun(data, config),
-23
View File
@@ -1,23 +0,0 @@
import { z } from 'zod';
// Auth schemas
export const AuthInfoSchema = z.object({
ownerId: z.string(),
projectId: z.string(),
environment: z.string(),
userId: z.string().optional(),
});
export const HealthCheckResponseSchema = z.object({
success: z.boolean(),
data: z
.object({
healthy: z.boolean(),
})
.and(z.record(z.string(), z.any())),
message: z.string(),
});
// Inferred types
export type AuthInfo = z.infer<typeof AuthInfoSchema>;
export type HealthCheckResponse = z.infer<typeof HealthCheckResponseSchema>;
-2
View File
@@ -1,5 +1,3 @@
export type * from './auth.js';
export { AuthInfoSchema, HealthCheckResponseSchema } from './auth.js';
export type * from './events.js';
export {
BaseEventSchema,
+1 -8
View File
@@ -1,4 +1,3 @@
import type { AuthInfo, HealthCheckResponse } from './auth.js';
import type {
CreateEventParams,
CreateEventRequest,
@@ -41,11 +40,6 @@ export interface Streamer {
): Promise<ReadableStream<Uint8Array>>;
}
export interface AuthProvider {
getAuthInfo(): Promise<AuthInfo>;
checkHealth(): Promise<HealthCheckResponse>;
}
export interface Storage {
runs: {
create(data: CreateWorkflowRunRequest): Promise<WorkflowRun>;
@@ -101,9 +95,8 @@ export interface Storage {
/**
* The "World" interface represents how Workflows are able to communicate with the outside world.
* This means persistence, queuing and serialization.
*/
export interface World extends Queue, Storage, AuthProvider, Streamer {
export interface World extends Queue, Storage, Streamer {
/**
* A function that will be called to start any background tasks needed by the World implementation.
* For example, in the case of a queue backed World, this would start the queue processing.