@uploadista/adapters-express 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/.turbo/turbo-build.log +19 -2
  2. package/dist/index.cjs +1 -0
  3. package/dist/index.d.cts +136 -0
  4. package/dist/index.d.cts.map +1 -0
  5. package/dist/index.d.ts +135 -3
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +2 -2
  8. package/dist/index.js.map +1 -0
  9. package/package.json +9 -8
  10. package/tsdown.config.ts +11 -0
  11. package/dist/adapter-layer.d.ts +0 -22
  12. package/dist/adapter-layer.d.ts.map +0 -1
  13. package/dist/adapter-layer.js +0 -3
  14. package/dist/error-types.d.ts +0 -24
  15. package/dist/error-types.d.ts.map +0 -1
  16. package/dist/error-types.js +0 -65
  17. package/dist/flow-adapter.d.ts +0 -19
  18. package/dist/flow-adapter.d.ts.map +0 -1
  19. package/dist/flow-adapter.js +0 -80
  20. package/dist/flow-http-handlers.d.ts +0 -9
  21. package/dist/flow-http-handlers.d.ts.map +0 -1
  22. package/dist/flow-http-handlers.js +0 -133
  23. package/dist/http-handlers.d.ts +0 -7
  24. package/dist/http-handlers.d.ts.map +0 -1
  25. package/dist/http-handlers.js +0 -78
  26. package/dist/upload-http-handlers.d.ts +0 -9
  27. package/dist/upload-http-handlers.d.ts.map +0 -1
  28. package/dist/upload-http-handlers.js +0 -113
  29. package/dist/uploadista-adapter-layer.d.ts +0 -24
  30. package/dist/uploadista-adapter-layer.d.ts.map +0 -1
  31. package/dist/uploadista-adapter-layer.js +0 -4
  32. package/dist/uploadista-adapter.d.ts +0 -78
  33. package/dist/uploadista-adapter.d.ts.map +0 -1
  34. package/dist/uploadista-adapter.js +0 -297
  35. package/dist/uploadista-websocket-handler.d.ts +0 -9
  36. package/dist/uploadista-websocket-handler.d.ts.map +0 -1
  37. package/dist/uploadista-websocket-handler.js +0 -132
  38. package/dist/websocket-handler.d.ts +0 -8
  39. package/dist/websocket-handler.d.ts.map +0 -1
  40. package/dist/websocket-handler.js +0 -82
@@ -1,5 +1,22 @@
1
1
 
2
2
  
3
- > @uploadista/adapters-express@0.0.2 build /Users/denislaboureyras/Documents/uploadista/dev/uploadista-workspace/uploadista-sdk/packages/servers/adapters-express
4
- > tsc -b
3
+ > @uploadista/adapters-express@0.0.3 build /Users/denislaboureyras/Documents/uploadista/dev/uploadista-workspace/uploadista-sdk/packages/servers/adapters-express
4
+ > tsdown
5
5
 
6
+ ℹ tsdown v0.15.9 powered by rolldown v1.0.0-beta.44
7
+ ℹ Using tsdown config: /Users/denislaboureyras/Documents/uploadista/dev/uploadista-workspace/uploadista-sdk/packages/servers/adapters-express/tsdown.config.ts
8
+ ℹ entry: src/index.ts
9
+ ℹ tsconfig: tsconfig.json
10
+ ℹ Build start
11
+ ℹ Cleaning 7 files
12
+ ℹ [CJS] dist/index.cjs 13.34 kB │ gzip: 4.19 kB
13
+ ℹ [CJS] 1 files, total: 13.34 kB
14
+ ℹ [ESM] dist/index.js 12.21 kB │ gzip: 3.97 kB
15
+ ℹ [ESM] dist/index.js.map 55.41 kB │ gzip: 12.43 kB
16
+ ℹ [ESM] dist/index.d.ts.map  4.05 kB │ gzip: 1.53 kB
17
+ ℹ [ESM] dist/index.d.ts  6.83 kB │ gzip: 1.56 kB
18
+ ℹ [ESM] 4 files, total: 78.51 kB
19
+ ℹ [CJS] dist/index.d.cts.map 4.05 kB │ gzip: 1.53 kB
20
+ ℹ [CJS] dist/index.d.cts 6.82 kB │ gzip: 1.56 kB
21
+ ℹ [CJS] 2 files, total: 10.88 kB
22
+ ✔ Build complete in 4555ms
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`@uploadista/core/flow`);c=s(c);let l=require(`@uploadista/core/types`);l=s(l);let u=require(`@uploadista/core/upload`);u=s(u);let d=require(`@uploadista/core/utils`);d=s(d);let f=require(`@uploadista/event-broadcaster-memory`);f=s(f);let p=require(`@uploadista/event-emitter-websocket`);p=s(p);let m=require(`@uploadista/observability`);m=s(m);let h=require(`@uploadista/server`);h=s(h);let g=require(`effect`);g=s(g);let _=require(`@uploadista/core/errors`);_=s(_);const v=(e,t)=>{e.status(t.statusCode).json((0,h.createErrorResponseBody)(t))},y=(e,t)=>{e.status(t.status).json((0,h.createUploadistaErrorResponseBody)(t))},b=e=>t=>{if(console.error(t),t instanceof h.AdapterError)return g.Effect.sync(()=>v(e,t));if(typeof t==`object`&&t&&`code`in t&&`status`in t&&`body`in t)return g.Effect.sync(()=>y(e,t));let n=`Internal server error`,r=`UNKNOWN_ERROR`,i=500;if(typeof t==`object`&&t){let e=t;`message`in e&&typeof e.message==`string`&&(n=e.message),`code`in e&&typeof e.code==`string`&&(r=e.code),`status`in e&&typeof e.status==`number`&&(i=e.status)}return g.Effect.sync(()=>{e.status(i).json({error:n,code:r,timestamp:new Date().toISOString()})})},x=(e,t,n)=>g.Effect.gen(function*(){let r=yield*(yield*h.AuthContextService).getClientId(),i=(0,h.getLastSegment)(new URL(e.url,`http://${e.get(`host`)}`).pathname);if(!i){t.status(400).json({error:`No id`});return}let a=yield*n.getFlowData(i,r);t.status(200).json(a)}).pipe(g.Effect.catchAll(b(t))),S=(e,t,n)=>g.Effect.gen(function*(){let r=yield*h.AuthContextService,i=yield*h.AuthCacheService,a=yield*r.getClientId(),o=e.url.split(`/`),s=o.pop(),c=o.pop();if(!c){t.status(400).json({error:`No id`});return}if(!s){t.status(400).json({error:`No storage id`});return}let l=e.body;a?(console.log(`[Flow] Executing flow: ${c}, storage: ${s}, client: ${a}`),console.log(JSON.stringify(l,null,2))):(console.log(`Flow execution params: ${c} ${s}`),console.log(JSON.stringify(l,null,2)));let u=yield*n.runFlow({flowId:c,storageId:s,clientId:a,inputs:l.inputs}),d=yield*r.getAuthContext();d&&(yield*i.set(u.id,d)),a&&console.log(`[Flow] Flow started with jobId: ${u.id}, client: ${a}`),t.status(200).json(u)}).pipe(g.Effect.catchAll(b(t))),C=(e,t,n)=>g.Effect.gen(function*(){let r=e.url.split(`/`),i=r[r.length-2];if(!i){t.status(400).json({error:`No job id`});return}let a=yield*n.getJobStatus(i);t.status(200).json(a)}).pipe(g.Effect.catchAll(b(t))),w=(e,t,n)=>g.Effect.gen(function*(){let r=yield*(yield*h.AuthContextService).getClientId(),i=new URL(e.url,`http://${e.get(`host`)}`).pathname.split(`/`),a=i[i.length-3],o=i[i.length-1];if(!a){console.error(`No job id`),t.status(400).json({error:`No job id`});return}if(!o){console.error(`No node id`),t.status(400).json({error:`No node id`});return}let s=e.get(`Content-Type`),c;if(s?.includes(`application/octet-stream`))c=new ReadableStream({start(t){e.on(`data`,e=>{t.enqueue(e)}),e.on(`end`,()=>{t.close()}),e.on(`error`,e=>{t.error(e)})}});else if(s?.includes(`application/json`)){let n=e.body;if(n.newData===void 0){console.error(`Missing newData`),t.status(400).json({error:`Missing newData`});return}c=n.newData}else{t.status(415).json({error:`Unsupported Content-Type`});return}let l=yield*n.continueFlow({jobId:a,nodeId:o,newData:c,clientId:r});t.status(200).json(l)}).pipe(g.Effect.catchAll(b(t))),T=(e,t,n)=>g.Effect.gen(function*(){let r=yield*h.AuthContextService,i=yield*h.AuthCacheService,a=yield*r.getClientId();a&&console.log(`[Upload] Creating upload for client: ${a}`);let o=e.body;if(!o)return yield*g.Effect.fail(new h.BadRequestError(`Invalid JSON payload`));let s=yield*g.Effect.sync(()=>l.inputFileSchema.safeParse(o));if(!s.success)return yield*g.Effect.fail(new h.ValidationError(`Invalid input file schema`));let c=yield*n.createUpload(s.data,a),u=yield*r.getAuthContext();u&&(yield*i.set(c.id,u)),a&&console.log(`[Upload] Upload created: ${c.id} for client: ${a}`),t.status(200).json(c)}).pipe(g.Effect.catchAll(b(t))),E=(e,t,n)=>g.Effect.gen(function*(){let r=yield*(yield*h.AuthContextService).getClientId(),i=new URL(e.url,`http://${e.get(`host`)}`),a=i.pathname.split(`/`).filter(Boolean),o=a[a.length-1];if(o===`capabilities`){let e=i.searchParams.get(`storageId`)||a[a.length-2];if(!e)return yield*g.Effect.fail(new h.BadRequestError(`storageId is required for capabilities`));let o=yield*n.getCapabilities(e,r);t.status(200).json({storageId:e,capabilities:o,timestamp:new Date().toISOString()});return}if(!o)return yield*g.Effect.fail(new h.BadRequestError(`Upload ID is required`));let s=yield*n.getUpload(o);t.status(200).json(s)}).pipe(g.Effect.catchAll(b(t))),D=(e,t,n)=>g.Effect.gen(function*(){let r=yield*h.AuthContextService,i=yield*h.AuthCacheService,a=yield*m.MetricsService,o=e.url.split(`/`).pop();if(!o)return yield*g.Effect.fail(new h.BadRequestError(`Upload ID is required`));let s=yield*r.getClientId(),c=yield*r.getMetadata();if(!s){let e=yield*i.get(o);s=e?.clientId??null,c=e?.metadata??{}}s&&console.log(`[Upload] Uploading chunk for upload: ${o}, client: ${s}`);let l=new ReadableStream({start(t){e.on(`data`,e=>{t.enqueue(e)}),e.on(`end`,()=>{t.close()}),e.on(`error`,e=>{t.error(e)})}}),u=yield*n.uploadChunk(o,s,l);u.size&&u.offset>=u.size&&(yield*i.delete(o),s&&console.log(`[Upload] Upload completed, cleared auth cache: ${o}`),s&&u.size?(console.log(`[Upload] Recording metrics for org: ${s}, size: ${u.size}`),yield*g.Effect.forkDaemon(a.recordUpload(s,u.size,c))):console.warn(`[Upload] Cannot record metrics - missing organizationId or size`)),s&&console.log(`[Upload] Chunk uploaded for upload: ${o}, client: ${s}`),t.status(200).json(u)}).pipe(g.Effect.catchAll(b(t)));var O=class extends g.Context.Tag(`ExpressUploadistaAdapterService`)(){};const k=(e,t,n)=>(r,i)=>{let a=r.url||``;if(!a.includes(`${e}/ws/`))return i.send(JSON.stringify({type:`error`,message:`WebSocket path must start with ${e}/ws/`})),i.close(1e3,`Invalid path`),{onMessage:()=>{},onClose:()=>{},onError:()=>{}};let o=a.replace(`${e}/ws/`,``).split(`/`).filter(Boolean),s=o.includes(`upload`),c=o.includes(`flow`),l=N(a,`jobId`),u=N(a,`uploadId`);if(!l&&!u&&o.length>=2){let e=o[0],t=o[1];e===`flow`?l=t:e===`upload`&&(u=t)}let d=l||u;console.log(`Uploadista websocket handler`,{jobId:l,uploadId:u,eventId:d});let f=g.Effect.gen(function*(){c&&l&&(yield*n.subscribeToFlowEvents(l,i)),s&&u&&(yield*t.subscribeToUploadEvents(u,i)),i.send(JSON.stringify({type:`connection`,message:`Uploadista WebSocket connected`,id:d,jobId:l,uploadId:u,timestamp:new Date().toISOString()}))}).pipe(g.Effect.catchAll(e=>g.Effect.sync(()=>{console.error(`Error subscribing to events:`,e);let t=e instanceof _.UploadistaError?e.body:`Failed to subscribe to events`;i.send(JSON.stringify({type:`error`,message:t,code:e instanceof _.UploadistaError?e.code:`SUBSCRIPTION_ERROR`}))})));return g.Effect.runFork(f),{onMessage:A(t,n,u,l,i),onClose:j(t,n,u,l),onError:M(d)}},A=(e,t,n,r,i)=>e=>{try{JSON.parse(e).type===`ping`&&i.send(JSON.stringify({type:`pong`,timestamp:new Date().toISOString()}))}catch(e){console.error(`Error handling WebSocket message:`,e),i.send(JSON.stringify({type:`error`,message:`Invalid message format`}))}},j=(e,t,n,r)=>()=>{let i=g.Effect.gen(function*(){r&&(yield*t.unsubscribeFromFlowEvents(r)),n&&(yield*e.unsubscribeFromUploadEvents(n))}).pipe(g.Effect.catchAll(e=>g.Effect.sync(()=>{console.error(`Error unsubscribing from events:`,e instanceof _.UploadistaError?e.body:e)})));g.Effect.runFork(i)},M=e=>t=>{console.error(`WebSocket error for event ${e}:`,t)};function N(e,t){let n=RegExp(`[?&]${t}=([^&]*)`),r=e.match(n);return r?.[1]?decodeURIComponent(r[1]):void 0}const P=(e,t,n,r)=>g.Layer.effect(O,g.Effect.gen(function*(){let i=yield*u.UploadServer,a=yield*c.FlowServer,o=(0,h.AuthCacheServiceLive)(n);return{handler:(n,s)=>g.Effect.gen(function*(){let c=null;if(t){let e=yield*g.Effect.tryPromise({try:()=>t(n,s),catch:e=>(console.error(`Auth middleware error:`,e),{_tag:`AuthError`,error:e})}).pipe(g.Effect.timeout(`5 seconds`),g.Effect.catchAll(e=>e&&typeof e==`object`&&`_tag`in e&&e._tag===`TimeoutException`?(console.error(`Auth middleware timeout exceeded (5 seconds)`),g.Effect.succeed({_tag:`TimeoutError`})):g.Effect.succeed(null)));if(e&&typeof e==`object`&&`_tag`in e&&e._tag===`TimeoutError`){s.status(503).json({error:`Authentication service unavailable`,message:`Authentication took too long to respond. Please try again.`});return}if(e===null){s.status(401).json({error:`Unauthorized`,message:`Invalid credentials`});return}if(e&&typeof e==`object`&&`_tag`in e&&e._tag===`AuthError`){s.status(500).json({error:`Internal Server Error`,message:`An error occurred during authentication`});return}c=e}let l=(0,h.AuthContextServiceLive)(c),u=g.Layer.mergeAll(l,o,r??m.NoOpMetricsServiceLive),d=new URL(n.url,`http://${n.get(`host`)}`);if(!d.pathname.includes(`${e}/api/`)){s.status(404).json({error:`Not found`});return}let f=d.pathname.replace(`${e}/api/`,``).split(`/`).filter(Boolean);if((f.includes(`upload`)&&n.method===`POST`||f.includes(`flow`)&&n.method===`POST`||f.includes(`continue`)&&n.get(`Content-Type`)?.includes(`application/json`))&&!n.body&&(yield*g.Effect.tryPromise({try:async()=>{let e=[];for await(let t of n)e.push(t);let t=Buffer.concat(e).toString();n.body=JSON.parse(t)},catch:e=>e})),f.includes(`upload`))switch(n.method){case`POST`:return yield*T(n,s,i).pipe(g.Effect.provide(u));case`GET`:return yield*E(n,s,i).pipe(g.Effect.provide(u));case`PATCH`:return yield*D(n,s,i).pipe(g.Effect.provide(u));default:s.status(405).json({error:`Method not allowed`});return}else if(f.includes(`flow`))switch(n.method){case`GET`:return yield*x(n,s,a).pipe(g.Effect.provide(u));case`POST`:return yield*S(n,s,a).pipe(g.Effect.provide(u));default:s.status(405).json({error:`Method not allowed`});return}else if(f.includes(`jobs`)){if(n.method===`GET`&&d.pathname.endsWith(`/status`))return yield*C(n,s,a).pipe(g.Effect.provide(u));if(n.method===`PATCH`&&f.includes(`continue`))return yield*w(n,s,a).pipe(g.Effect.provide(u));s.status(405).json({error:`Method not allowed`});return}else{s.status(404).json({error:`Not found`});return}}).pipe(g.Effect.catchAll(()=>g.Effect.sync(()=>{s.status(500).json({error:`Internal server error`})}))),websocketHandler:k(e,i,a)}})),F=({baseUrl:e,flowProvider:t,eventEmitter:n,dataStore:r,bufferedDataStore:i,kvStore:a,generateId:o=d.GenerateIdLive,authMiddleware:s,authCacheConfig:c,metricsLayer:l})=>{let u=(0,h.createUploadServerLayer)({kvStore:a,eventEmitter:n,dataStore:r,bufferedDataStore:i,generateId:o}),f=(0,h.createFlowServerLayer)({kvStore:a,eventEmitter:n,flowProvider:t,uploadServer:u}),p=g.Layer.provide(P(e,s,c,l),g.Layer.mergeAll(u,f));return g.Effect.gen(function*(){let e=yield*O;return{handler:(t,n)=>e.handler(t,n),websocketHandler:(t,n)=>e.websocketHandler(t,n),uploadServer:u,flowServer:f}}).pipe(g.Effect.provide(p))},I=(e,t)=>t?g.Effect.runPromise(e.pipe(g.Effect.provide(m.NodeSdkLive))):g.Effect.runPromise(e),L=async({baseUrl:e,flowProvider:t,plugins:n,eventEmitter:r,dataStore:i,bufferedDataStore:a,kvStore:o,withTracing:s=!1,authMiddleware:c,authCacheConfig:l,metricsLayer:u})=>{let d=await g.Effect.runPromise(F({baseUrl:e,flowProvider:t,eventEmitter:r,dataStore:i,bufferedDataStore:a,kvStore:o,authMiddleware:c,authCacheConfig:l,metricsLayer:u})),f=g.Layer.mergeAll(d.uploadServer,...n??[]);return{baseUrl:e,handler:(e,t,n)=>{I(d.handler(e,t).pipe(g.Effect.provide(f)),s).catch(e=>{console.error(`Express adapter error:`,e),n&&n(e)})},websocketHandler:(e,t)=>d.websocketHandler(e,t),websocketConnectionHandler:(t,n)=>{if(!n.url?.startsWith(`/${e}/ws/`)){t.close(1008,`Invalid WebSocket path`);return}console.log(`📡 WebSocket connected: ${n.url}`);let r={id:`conn_${Date.now()}_${Math.random().toString(36).substring(2,11)}`,send:e=>{t.readyState===t.OPEN&&t.send(e)},close:(e,n)=>t.close(e,n),readyState:t.readyState},i=d.websocketHandler(n,r);t.on(`message`,e=>{i.onMessage(e.toString())}),t.on(`close`,()=>{i.onClose()}),t.on(`error`,e=>{i.onError(e)})}}},R=async({baseUrl:e=`uploadista`,flows:t,plugins:n=[],eventEmitter:r,eventBroadcaster:i=f.memoryEventBroadcaster,dataStore:a,bufferedDataStore:o,kvStore:s,generateId:u=d.GenerateIdLive,authMiddleware:m,authCacheConfig:h,metricsLayer:_})=>{let v=g.Effect.succeed({getFlow:(e,n)=>t(e,n)});return L({baseUrl:e,flowProvider:g.Layer.effect(c.FlowProvider,v),plugins:n,eventEmitter:r??(0,p.webSocketEventEmitter)(i),dataStore:await(0,l.createDataStoreLayer)(a),bufferedDataStore:o,kvStore:s,generateId:u,authMiddleware:m,authCacheConfig:h,metricsLayer:_})};exports.createExpressUploadistaAdapter=R,exports.createExpressUploadistaServer=F,exports.createInternalExpressUploadistaAdapter=L,exports.createUploadistaWebSocketHandler=k,exports.createWebSocketCloseHandler=j,exports.createWebSocketErrorHandler=M,exports.createWebSocketMessageHandler=A;
@@ -0,0 +1,136 @@
1
+ import { IncomingMessage } from "node:http";
2
+ import { EventBroadcasterService, UploadFileDataStores, UploadistaError } from "@uploadista/core";
3
+ import { Flow, FlowProvider, FlowServer, FlowServerShape } from "@uploadista/core/flow";
4
+ import { BaseEventEmitterService, BaseKvStoreService, DataStoreConfig, UploadFileDataStore, UploadFileKVStore } from "@uploadista/core/types";
5
+ import { UploadServer, UploadServerShape } from "@uploadista/core/upload";
6
+ import { GenerateId } from "@uploadista/core/utils";
7
+ import { MetricsService } from "@uploadista/observability";
8
+ import { AuthCacheConfig, AuthResult } from "@uploadista/server";
9
+ import { Effect, Layer } from "effect";
10
+ import { Request, Response } from "express";
11
+ import { z } from "zod";
12
+
13
+ //#region src/uploadista-adapter-layer.d.ts
14
+ interface WebSocketConnection {
15
+ id: string;
16
+ send: (data: string) => void;
17
+ close: (code?: number, reason?: string) => void;
18
+ readyState: number;
19
+ }
20
+ type WebSocketHandlers = {
21
+ onMessage: (message: string) => void;
22
+ onClose: () => void;
23
+ onError: (error: Error) => void;
24
+ };
25
+ type ExpressWebSocketHandler = (req: IncomingMessage, connection: WebSocketConnection) => WebSocketHandlers;
26
+ //#endregion
27
+ //#region src/uploadista-adapter.d.ts
28
+ type ExpressUploadistaAdapterOptions<TFlows$1 extends (flowId: string, clientId: string | null) => Effect.Effect<Flow<z.ZodSchema<unknown>, z.ZodSchema<unknown>, unknown>, UploadistaError, unknown> = any, TPlugins$1 extends readonly Layer.Layer<any, never, never>[] = Layer.Layer<any, never, never>[]> = {
29
+ flows: TFlows$1;
30
+ plugins?: TPlugins$1;
31
+ dataStore: DataStoreConfig;
32
+ bufferedDataStore?: Layer.Layer<UploadFileDataStore, never, UploadFileKVStore>;
33
+ baseUrl?: string;
34
+ kvStore: Layer.Layer<BaseKvStoreService>;
35
+ eventEmitter?: Layer.Layer<BaseEventEmitterService>;
36
+ eventBroadcaster?: Layer.Layer<EventBroadcasterService>;
37
+ generateId?: Layer.Layer<GenerateId>;
38
+ withTracing?: boolean;
39
+ authMiddleware?: (req: Request, res: Response) => Promise<AuthResult>;
40
+ authCacheConfig?: AuthCacheConfig;
41
+ metricsLayer?: Layer.Layer<MetricsService, never, never>;
42
+ };
43
+ type InternalExpressUploadistaAdapterOptions<TRequirements$1 = never, TPlugins$1 extends readonly Layer.Layer<TRequirements$1, never, never>[] = []> = {
44
+ flowProvider: Layer.Layer<FlowProvider>;
45
+ plugins?: TPlugins$1;
46
+ dataStore: Layer.Layer<UploadFileDataStores, never, UploadFileKVStore>;
47
+ bufferedDataStore?: Layer.Layer<UploadFileDataStore, never, UploadFileKVStore>;
48
+ baseUrl: string;
49
+ kvStore: Layer.Layer<BaseKvStoreService>;
50
+ eventEmitter: Layer.Layer<BaseEventEmitterService>;
51
+ generateId?: Layer.Layer<GenerateId>;
52
+ withTracing?: boolean;
53
+ authMiddleware?: (req: Request, res: Response) => Promise<AuthResult>;
54
+ authCacheConfig?: AuthCacheConfig;
55
+ metricsLayer?: Layer.Layer<MetricsService, never, never>;
56
+ };
57
+ type ExpressUploadistaAdapter = {
58
+ baseUrl: string;
59
+ handler: (req: Request, res: Response, next?: (error?: Error) => void) => void;
60
+ websocketHandler: (req: IncomingMessage, connection: WebSocketConnection) => WebSocketHandlers;
61
+ websocketConnectionHandler: (ws: WebSocket, req: IncomingMessage) => void;
62
+ };
63
+ interface WebSocket {
64
+ readyState: number;
65
+ OPEN: number;
66
+ send: (data: string) => void;
67
+ close: (code?: number, reason?: string) => void;
68
+ on: (event: string, handler: (...args: any[]) => void) => void;
69
+ }
70
+ type ExpressUploadistaServer = {
71
+ handler: (req: Request, res: Response) => Effect.Effect<void, never, never>;
72
+ uploadServer: Layer.Layer<UploadServer>;
73
+ flowServer: Layer.Layer<FlowServer>;
74
+ websocketHandler: (req: IncomingMessage, connection: WebSocketConnection) => WebSocketHandlers;
75
+ };
76
+ /**
77
+ * Creates an Effect-native unified Express server - combining upload and flow capabilities
78
+ */
79
+ declare const createExpressUploadistaServer: <TRequirements = UploadServer>({
80
+ baseUrl,
81
+ flowProvider,
82
+ eventEmitter,
83
+ dataStore,
84
+ bufferedDataStore,
85
+ kvStore,
86
+ generateId,
87
+ authMiddleware,
88
+ authCacheConfig,
89
+ metricsLayer
90
+ }: InternalExpressUploadistaAdapterOptions<TRequirements>) => Effect.Effect<ExpressUploadistaServer>;
91
+ /**
92
+ * Creates a Promise-based Express adapter for compatibility with existing Express applications
93
+ * This wraps the Effect-native version with Promise conversion and caches the server instance
94
+ */
95
+ declare const createInternalExpressUploadistaAdapter: <TRequirements = UploadServer, TPlugins extends readonly Layer.Layer<TRequirements, never, never>[] = []>({
96
+ baseUrl,
97
+ flowProvider,
98
+ plugins,
99
+ eventEmitter,
100
+ dataStore,
101
+ bufferedDataStore,
102
+ kvStore,
103
+ withTracing,
104
+ authMiddleware,
105
+ authCacheConfig,
106
+ metricsLayer
107
+ }: InternalExpressUploadistaAdapterOptions<TRequirements, TPlugins>) => Promise<ExpressUploadistaAdapter>;
108
+ /**
109
+ * Creates a Promise-based Uploadista Express adapter for compatibility
110
+ *
111
+ * Note: Ensure that the plugins array provides all services required by your flows.
112
+ * Missing plugin services will result in runtime errors during flow execution.
113
+ */
114
+ declare const createExpressUploadistaAdapter: <TFlows extends (flowId: string, clientId: string | null) => Effect.Effect<Flow<z.ZodSchema<unknown>, z.ZodSchema<unknown>, unknown>, UploadistaError, unknown> = any, TPlugins extends readonly Layer.Layer<any, never, never>[] = Layer.Layer<any, never, never>[]>({
115
+ baseUrl,
116
+ flows,
117
+ plugins,
118
+ eventEmitter,
119
+ eventBroadcaster,
120
+ dataStore,
121
+ bufferedDataStore,
122
+ kvStore,
123
+ generateId,
124
+ authMiddleware,
125
+ authCacheConfig,
126
+ metricsLayer
127
+ }: ExpressUploadistaAdapterOptions<TFlows, TPlugins>) => Promise<ExpressUploadistaAdapter>;
128
+ //#endregion
129
+ //#region src/uploadista-websocket-handler.d.ts
130
+ declare const createUploadistaWebSocketHandler: (baseUrl: string, uploadServer: UploadServerShape, flowServer: FlowServerShape) => (req: IncomingMessage, connection: WebSocketConnection) => WebSocketHandlers;
131
+ declare const createWebSocketMessageHandler: (_uploadServer: UploadServerShape, _flowServer: FlowServerShape, _uploadId: string | undefined, _jobId: string | undefined, connection: WebSocketConnection) => (message: string) => void;
132
+ declare const createWebSocketCloseHandler: (uploadServer: UploadServerShape, flowServer: FlowServerShape, uploadId: string | undefined, jobId: string | undefined) => () => void;
133
+ declare const createWebSocketErrorHandler: (eventId: string | undefined) => (error: Error) => void;
134
+ //#endregion
135
+ export { ExpressUploadistaAdapter, ExpressUploadistaAdapterOptions, ExpressUploadistaServer, type ExpressWebSocketHandler, InternalExpressUploadistaAdapterOptions, type WebSocketConnection, type WebSocketHandlers, createExpressUploadistaAdapter, createExpressUploadistaServer, createInternalExpressUploadistaAdapter, createUploadistaWebSocketHandler, createWebSocketCloseHandler, createWebSocketErrorHandler, createWebSocketMessageHandler };
136
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/uploadista-adapter-layer.ts","../src/uploadista-adapter.ts","../src/uploadista-websocket-handler.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;UAIiB,mBAAA;;;;;;KAOL,iBAAA;;;mBAGO;AAVnB,CAAA;AAOY,KAMA,uBAAA,GAHO,CAAA,GAAK,EAIjB,eAJiB,EAAA,UAAA,EAKV,mBALU,EAAA,GAMnB,iBANmB;;;KC0CZ,8FAIL,MAAA,CAAO,OACV,KAAK,CAAA,CAAE,oBAAoB,CAAA,CAAE,8BAC7B,6DAKwB,KAAA,CAAM,6BAA6B,KAAA,CAAM;ED/DpD,KAAA,ECsER,QDtEQ;EAOL,OAAA,CAAA,ECgEA,UDhEA;EAMA,SAAA,EC4DC,eD5DsB;EAC5B,iBAAA,CAAA,EC4De,KAAA,CAAM,KD5DrB,CC6DH,mBD7DG,EAAA,KAAA,EC+DH,iBD/DG,CAAA;EACO,OAAA,CAAA,EAAA,MAAA;EACT,OAAA,ECkEM,KAAA,CAAM,KDlEZ,CCkEkB,kBDlElB,CAAA;EAAiB,YAAA,CAAA,ECmEL,KAAA,CAAM,KDnED,CCmEO,uBDnEP,CAAA;qBCoED,KAAA,CAAM,MAAM;eAClB,KAAA,CAAM,MAAM;;EAjCf,cAAA,CAAA,EAAA,CAAA,GAAA,EAqCa,OArCb,EAAA,GAA+B,EAqCJ,QArCI,EAAA,GAqCS,OArCT,CAqCiB,UArCjB,CAAA;EAKhC,eAAA,CAAA,EAiCS,eAjCT;EAAsB,YAAA,CAAA,EAoChB,KAAA,CAAM,KApCU,CAoCJ,cApCI,EAAA,KAAA,EAAA,KAAA,CAAA;CAA7B;AACA,KAsCQ,uCAtCR,CAAA,kBAAA,KAAA,EAAA,mBAAA,SAwCwB,KAAA,CAAM,KAxC9B,CAwCoC,eAxCpC,EAAA,KAAA,EAAA,KAAA,CAAA,EAAA,GAAA,EAAA,CAAA,GAAA;EAFG,YAAO,EA6CE,KAAA,CAAM,KA7CR,CA6Cc,YA7Cd,CAAA;EAOc,OAAM,CAAA,EAuCtB,UAvCsB;EAA6B,SAAM,EA0CxD,KAAA,CAAM,KA1CkD,CA0C5C,oBA1C4C,EAAA,KAAA,EA0Cf,iBA1Ce,CAAA;EAO5D,iBAAA,CAAA,EAoCa,KAAA,CAAM,KApCnB,CAqCL,mBArCK,EAAA,KAAA,EAuCL,iBAvCK,CAAA;EACG,OAAA,EAAA,MAAA;EAEC,OAAA,EAwCF,KAAA,CAAM,KAxCJ,CAwCU,kBAxCV,CAAA;EAET,YAAA,EAuCY,KAAA,CAAM,KAvClB,CAuCwB,uBAvCxB,CAAA;EAEA,UAAA,CAAA,EAsCW,KAAA,CAAM,KAtCjB,CAsCuB,UAtCvB,CAAA;EAHkB,WAAM,CAAA,EAAA,OAAA;EAQL,cAAA,CAAA,EAAA,CAAA,GAAA,EAqCE,OArCF,EAAA,GAAA,EAqCgB,QArChB,EAAA,GAqC6B,OArC7B,CAqCqC,UArCrC,CAAA;EAAZ,eAAM,CAAA,EAsCG,eAtCH;EACY,YAAA,CAAA,EAwCZ,KAAA,CAAM,KAxCM,CAwCA,cAxCA,EAAA,KAAA,EAAA,KAAA,CAAA;CAAZ;AACgB,KA0CrB,wBAAA,GA1CqB;EAAZ,OAAM,EAAA,MAAA;EACA,OAAA,EAAA,CAAA,GAAA,EA4ClB,OA5CkB,EAAA,GAAA,EA6ClB,QA7CkB,EAAA,IAAA,CAAA,EAAA,CAAA,KAAA,CAAA,EA8CP,KA9CO,EAAA,GAAA,IAAA,EAAA,GAAA,IAAA;EAAZ,gBAAM,EAAA,CAAA,GAAA,EAiDZ,eAjDY,EAAA,UAAA,EAkDL,mBAlDK,EAAA,GAmDd,iBAnDc;EAII,0BAAA,EAAA,CAAA,EAAA,EAgDU,SAhDV,EAAA,GAAA,EAgD0B,eAhD1B,EAAA,GAAA,IAAA;CAAc;UAoD7B,SAAA,CApDkD;EAAR,UAAA,EAAA,MAAA;EAChC,IAAA,EAAA,MAAA;EAGS,IAAA,EAAA,CAAA,IAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAAZ,KAAM,EAAA,CAAA,IAAA,CAAA,EAAA,MAAA,EAAA,MAAA,CAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAAK,EAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,OAAA,EAAA,CAAA,GAAA,IAAA,EAAA,GAAA,EAAA,EAAA,GAAA,IAAA,EAAA,GAAA,IAAA;AAG5B;AAEwC,KAoD5B,uBAAA,GApD4B;EAAZ,OAAM,EAAA,CAAA,GAAA,EAqDjB,OArDiB,EAAA,GAAA,EAqDH,QArDG,EAAA,GAqDU,MAAA,CAAO,MArDjB,CAAA,IAAA,EAAA,KAAA,EAAA,KAAA,CAAA;EAGN,YAAA,EAmDZ,KAAA,CAAM,KAnDM,CAmDA,YAnDA,CAAA;EAAZ,UAAM,EAoDR,KAAA,CAAM,KApDE,CAoDI,UApDJ,CAAA;EACV,gBAAA,EAAA,CAAA,GAAA,EAqDH,eArDG,EAAA,UAAA,EAsDI,mBAtDJ,EAAA,GAuDL,iBAvDK;CAGa;;;;AAIrB,cAgRS,6BAhRT,EAAA,CAAA,gBAgR0D,YAhR1D,CAAA,CAAA;EAAA,OAAA;EAAA,YAAA;EAAA,YAAA;EAAA,SAAA;EAAA,iBAAA;EAAA,OAAA;EAAA,UAAA;EAAA,cAAA;EAAA,eAAA;EAAA;AAAA,CAAA,EA2RD,uCA3RC,CA2RuC,aA3RvC,CAAA,EAAA,GA2RwD,MAAA,CAAO,MA3R/D,CA2RsE,uBA3RtE,CAAA;;;;;AAKkB,cAiVT,sCAjVS,EAAA,CAAA,gBAkVJ,YAlVI,EAAA,iBAAA,SAmVM,KAAA,CAAM,KAnVZ,CAmVkB,aAnVlB,EAAA,KAAA,EAAA,KAAA,CAAA,EAAA,GAAA,EAAA,CAAA,CAAA;EAAA,OAAA;EAAA,YAAA;EAAA,OAAA;EAAA,YAAA;EAAA,SAAA;EAAA,iBAAA;EAAA,OAAA;EAAA,WAAA;EAAA,cAAA;EAAA,eAAA;EAAA;AAAA,CAAA,EAgWnB,uCAhWmB,CAiWpB,aAjWoB,EAkWpB,QAlWoB,CAAA,EAAA,GAmWlB,OAnWkB,CAmWV,wBAnWU,CAAA;;;;;;;AAMF,cA6aP,8BA7aO,EAAA,CAAA,eAAA,CAAA,MAAA,EAAA,MAAA,EAAA,QAAA,EAAA,MAAA,GAAA,IAAA,EAAA,GAibb,MAAA,CAAO,MAjbM,CAkbhB,IAlbgB,CAkbX,CAAA,CAAE,SAlbS,CAAA,OAAA,CAAA,EAkbW,CAAA,CAAE,SAlbb,CAAA,OAAA,CAAA,EAAA,OAAA,CAAA,EAmbhB,eAnbgB,EAAA,OAAA,CAAA,GAAA,GAAA,EAAA,iBAAA,SAwbQ,KAAA,CAAM,KAxbd,CAAA,GAAA,EAAA,KAAA,EAAA,KAAA,CAAA,EAAA,GAwb2C,KAAA,CAAM,KAxbjD,CAAA,GAAA,EAAA,KAAA,EAAA,KAAA,CAAA,EAAA,CAAA,CAAA;EAAA,OAAA;EAAA,KAAA;EAAA,OAAA;EAAA,YAAA;EAAA,gBAAA;EAAA,SAAA;EAAA,iBAAA;EAAA,OAAA;EAAA,UAAA;EAAA,cAAA;EAAA,eAAA;EAAA;AAAA,CAAA,EA2cjB,+BA3ciB,CA4clB,MA5ckB,EA6clB,QA7ckB,CAAA,EAAA,GA8chB,OA9cgB,CA8cR,wBA9cQ,CAAA;;;cClHP,kEAEG,+BACF,0BAGL,6BACO,wBACX;cAsHQ,+CACI,gCACF,wFAGD;cAyBD,4CACG,+BACF;cA8BD,sEACI"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,136 @@
1
- export * from "./uploadista-adapter";
2
- export type { ExpressWebSocketHandler, WebSocketConnection, WebSocketHandlers, } from "./uploadista-adapter-layer";
3
- export { createUploadistaWebSocketHandler, createWebSocketCloseHandler, createWebSocketErrorHandler, createWebSocketMessageHandler, } from "./uploadista-websocket-handler";
1
+ import { Flow, FlowProvider, FlowServer, FlowServerShape } from "@uploadista/core/flow";
2
+ import { BaseEventEmitterService, BaseKvStoreService, DataStoreConfig, UploadFileDataStore, UploadFileKVStore } from "@uploadista/core/types";
3
+ import { UploadServer, UploadServerShape } from "@uploadista/core/upload";
4
+ import { GenerateId } from "@uploadista/core/utils";
5
+ import { MetricsService } from "@uploadista/observability";
6
+ import { AuthCacheConfig, AuthResult } from "@uploadista/server";
7
+ import { Context, Effect, Layer } from "effect";
8
+ import { IncomingMessage } from "node:http";
9
+ import { EventBroadcasterService, UploadFileDataStores, UploadistaError } from "@uploadista/core";
10
+ import { Request, Response } from "express";
11
+ import { z } from "zod";
12
+
13
+ //#region src/uploadista-adapter-layer.d.ts
14
+ interface WebSocketConnection {
15
+ id: string;
16
+ send: (data: string) => void;
17
+ close: (code?: number, reason?: string) => void;
18
+ readyState: number;
19
+ }
20
+ type WebSocketHandlers = {
21
+ onMessage: (message: string) => void;
22
+ onClose: () => void;
23
+ onError: (error: Error) => void;
24
+ };
25
+ type ExpressWebSocketHandler = (req: IncomingMessage, connection: WebSocketConnection) => WebSocketHandlers;
26
+ //#endregion
27
+ //#region src/uploadista-adapter.d.ts
28
+ type ExpressUploadistaAdapterOptions<TFlows$1 extends (flowId: string, clientId: string | null) => Effect.Effect<Flow<z.ZodSchema<unknown>, z.ZodSchema<unknown>, unknown>, UploadistaError, unknown> = any, TPlugins$1 extends readonly Layer.Layer<any, never, never>[] = Layer.Layer<any, never, never>[]> = {
29
+ flows: TFlows$1;
30
+ plugins?: TPlugins$1;
31
+ dataStore: DataStoreConfig;
32
+ bufferedDataStore?: Layer.Layer<UploadFileDataStore, never, UploadFileKVStore>;
33
+ baseUrl?: string;
34
+ kvStore: Layer.Layer<BaseKvStoreService>;
35
+ eventEmitter?: Layer.Layer<BaseEventEmitterService>;
36
+ eventBroadcaster?: Layer.Layer<EventBroadcasterService>;
37
+ generateId?: Layer.Layer<GenerateId>;
38
+ withTracing?: boolean;
39
+ authMiddleware?: (req: Request, res: Response) => Promise<AuthResult>;
40
+ authCacheConfig?: AuthCacheConfig;
41
+ metricsLayer?: Layer.Layer<MetricsService, never, never>;
42
+ };
43
+ type InternalExpressUploadistaAdapterOptions<TRequirements$1 = never, TPlugins$1 extends readonly Layer.Layer<TRequirements$1, never, never>[] = []> = {
44
+ flowProvider: Layer.Layer<FlowProvider>;
45
+ plugins?: TPlugins$1;
46
+ dataStore: Layer.Layer<UploadFileDataStores, never, UploadFileKVStore>;
47
+ bufferedDataStore?: Layer.Layer<UploadFileDataStore, never, UploadFileKVStore>;
48
+ baseUrl: string;
49
+ kvStore: Layer.Layer<BaseKvStoreService>;
50
+ eventEmitter: Layer.Layer<BaseEventEmitterService>;
51
+ generateId?: Layer.Layer<GenerateId>;
52
+ withTracing?: boolean;
53
+ authMiddleware?: (req: Request, res: Response) => Promise<AuthResult>;
54
+ authCacheConfig?: AuthCacheConfig;
55
+ metricsLayer?: Layer.Layer<MetricsService, never, never>;
56
+ };
57
+ type ExpressUploadistaAdapter = {
58
+ baseUrl: string;
59
+ handler: (req: Request, res: Response, next?: (error?: Error) => void) => void;
60
+ websocketHandler: (req: IncomingMessage, connection: WebSocketConnection) => WebSocketHandlers;
61
+ websocketConnectionHandler: (ws: WebSocket, req: IncomingMessage) => void;
62
+ };
63
+ interface WebSocket {
64
+ readyState: number;
65
+ OPEN: number;
66
+ send: (data: string) => void;
67
+ close: (code?: number, reason?: string) => void;
68
+ on: (event: string, handler: (...args: any[]) => void) => void;
69
+ }
70
+ type ExpressUploadistaServer = {
71
+ handler: (req: Request, res: Response) => Effect.Effect<void, never, never>;
72
+ uploadServer: Layer.Layer<UploadServer>;
73
+ flowServer: Layer.Layer<FlowServer>;
74
+ websocketHandler: (req: IncomingMessage, connection: WebSocketConnection) => WebSocketHandlers;
75
+ };
76
+ /**
77
+ * Creates an Effect-native unified Express server - combining upload and flow capabilities
78
+ */
79
+ declare const createExpressUploadistaServer: <TRequirements = UploadServer>({
80
+ baseUrl,
81
+ flowProvider,
82
+ eventEmitter,
83
+ dataStore,
84
+ bufferedDataStore,
85
+ kvStore,
86
+ generateId,
87
+ authMiddleware,
88
+ authCacheConfig,
89
+ metricsLayer
90
+ }: InternalExpressUploadistaAdapterOptions<TRequirements>) => Effect.Effect<ExpressUploadistaServer>;
91
+ /**
92
+ * Creates a Promise-based Express adapter for compatibility with existing Express applications
93
+ * This wraps the Effect-native version with Promise conversion and caches the server instance
94
+ */
95
+ declare const createInternalExpressUploadistaAdapter: <TRequirements = UploadServer, TPlugins extends readonly Layer.Layer<TRequirements, never, never>[] = []>({
96
+ baseUrl,
97
+ flowProvider,
98
+ plugins,
99
+ eventEmitter,
100
+ dataStore,
101
+ bufferedDataStore,
102
+ kvStore,
103
+ withTracing,
104
+ authMiddleware,
105
+ authCacheConfig,
106
+ metricsLayer
107
+ }: InternalExpressUploadistaAdapterOptions<TRequirements, TPlugins>) => Promise<ExpressUploadistaAdapter>;
108
+ /**
109
+ * Creates a Promise-based Uploadista Express adapter for compatibility
110
+ *
111
+ * Note: Ensure that the plugins array provides all services required by your flows.
112
+ * Missing plugin services will result in runtime errors during flow execution.
113
+ */
114
+ declare const createExpressUploadistaAdapter: <TFlows extends (flowId: string, clientId: string | null) => Effect.Effect<Flow<z.ZodSchema<unknown>, z.ZodSchema<unknown>, unknown>, UploadistaError, unknown> = any, TPlugins extends readonly Layer.Layer<any, never, never>[] = Layer.Layer<any, never, never>[]>({
115
+ baseUrl,
116
+ flows,
117
+ plugins,
118
+ eventEmitter,
119
+ eventBroadcaster,
120
+ dataStore,
121
+ bufferedDataStore,
122
+ kvStore,
123
+ generateId,
124
+ authMiddleware,
125
+ authCacheConfig,
126
+ metricsLayer
127
+ }: ExpressUploadistaAdapterOptions<TFlows, TPlugins>) => Promise<ExpressUploadistaAdapter>;
128
+ //#endregion
129
+ //#region src/uploadista-websocket-handler.d.ts
130
+ declare const createUploadistaWebSocketHandler: (baseUrl: string, uploadServer: UploadServerShape, flowServer: FlowServerShape) => (req: IncomingMessage, connection: WebSocketConnection) => WebSocketHandlers;
131
+ declare const createWebSocketMessageHandler: (_uploadServer: UploadServerShape, _flowServer: FlowServerShape, _uploadId: string | undefined, _jobId: string | undefined, connection: WebSocketConnection) => (message: string) => void;
132
+ declare const createWebSocketCloseHandler: (uploadServer: UploadServerShape, flowServer: FlowServerShape, uploadId: string | undefined, jobId: string | undefined) => () => void;
133
+ declare const createWebSocketErrorHandler: (eventId: string | undefined) => (error: Error) => void;
134
+ //#endregion
135
+ export { ExpressUploadistaAdapter, ExpressUploadistaAdapterOptions, ExpressUploadistaServer, type ExpressWebSocketHandler, InternalExpressUploadistaAdapterOptions, type WebSocketConnection, type WebSocketHandlers, createExpressUploadistaAdapter, createExpressUploadistaServer, createInternalExpressUploadistaAdapter, createUploadistaWebSocketHandler, createWebSocketCloseHandler, createWebSocketErrorHandler, createWebSocketMessageHandler };
4
136
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AAGrC,YAAY,EACV,uBAAuB,EACvB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,gCAAgC,EAChC,2BAA2B,EAC3B,2BAA2B,EAC3B,6BAA6B,GAC9B,MAAM,gCAAgC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/uploadista-adapter-layer.ts","../src/uploadista-adapter.ts","../src/uploadista-websocket-handler.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;UAIiB,mBAAA;;;;;;KAOL,iBAAA;;;mBAGO;AAVnB,CAAA;AAOY,KAMA,uBAAA,GAHO,CAAA,GAAK,EAIjB,eAJiB,EAAA,UAAA,EAKV,mBALU,EAAA,GAMnB,iBANmB;;;KC0CZ,8FAIL,MAAA,CAAO,OACV,KAAK,CAAA,CAAE,oBAAoB,CAAA,CAAE,8BAC7B,6DAKwB,KAAA,CAAM,6BAA6B,KAAA,CAAM;ED/DpD,KAAA,ECsER,QDtEQ;EAOL,OAAA,CAAA,ECgEA,UDhEA;EAMA,SAAA,EC4DC,eD5DsB;EAC5B,iBAAA,CAAA,EC4De,KAAA,CAAM,KD5DrB,CC6DH,mBD7DG,EAAA,KAAA,EC+DH,iBD/DG,CAAA;EACO,OAAA,CAAA,EAAA,MAAA;EACT,OAAA,ECkEM,KAAA,CAAM,KDlEZ,CCkEkB,kBDlElB,CAAA;EAAiB,YAAA,CAAA,ECmEL,KAAA,CAAM,KDnED,CCmEO,uBDnEP,CAAA;qBCoED,KAAA,CAAM,MAAM;eAClB,KAAA,CAAM,MAAM;;EAjCf,cAAA,CAAA,EAAA,CAAA,GAAA,EAqCa,OArCb,EAAA,GAA+B,EAqCJ,QArCI,EAAA,GAqCS,OArCT,CAqCiB,UArCjB,CAAA;EAKhC,eAAA,CAAA,EAiCS,eAjCT;EAAsB,YAAA,CAAA,EAoChB,KAAA,CAAM,KApCU,CAoCJ,cApCI,EAAA,KAAA,EAAA,KAAA,CAAA;CAA7B;AACA,KAsCQ,uCAtCR,CAAA,kBAAA,KAAA,EAAA,mBAAA,SAwCwB,KAAA,CAAM,KAxC9B,CAwCoC,eAxCpC,EAAA,KAAA,EAAA,KAAA,CAAA,EAAA,GAAA,EAAA,CAAA,GAAA;EAFG,YAAO,EA6CE,KAAA,CAAM,KA7CR,CA6Cc,YA7Cd,CAAA;EAOc,OAAM,CAAA,EAuCtB,UAvCsB;EAA6B,SAAM,EA0CxD,KAAA,CAAM,KA1CkD,CA0C5C,oBA1C4C,EAAA,KAAA,EA0Cf,iBA1Ce,CAAA;EAO5D,iBAAA,CAAA,EAoCa,KAAA,CAAM,KApCnB,CAqCL,mBArCK,EAAA,KAAA,EAuCL,iBAvCK,CAAA;EACG,OAAA,EAAA,MAAA;EAEC,OAAA,EAwCF,KAAA,CAAM,KAxCJ,CAwCU,kBAxCV,CAAA;EAET,YAAA,EAuCY,KAAA,CAAM,KAvClB,CAuCwB,uBAvCxB,CAAA;EAEA,UAAA,CAAA,EAsCW,KAAA,CAAM,KAtCjB,CAsCuB,UAtCvB,CAAA;EAHkB,WAAM,CAAA,EAAA,OAAA;EAQL,cAAA,CAAA,EAAA,CAAA,GAAA,EAqCE,OArCF,EAAA,GAAA,EAqCgB,QArChB,EAAA,GAqC6B,OArC7B,CAqCqC,UArCrC,CAAA;EAAZ,eAAM,CAAA,EAsCG,eAtCH;EACY,YAAA,CAAA,EAwCZ,KAAA,CAAM,KAxCM,CAwCA,cAxCA,EAAA,KAAA,EAAA,KAAA,CAAA;CAAZ;AACgB,KA0CrB,wBAAA,GA1CqB;EAAZ,OAAM,EAAA,MAAA;EACA,OAAA,EAAA,CAAA,GAAA,EA4ClB,OA5CkB,EAAA,GAAA,EA6ClB,QA7CkB,EAAA,IAAA,CAAA,EAAA,CAAA,KAAA,CAAA,EA8CP,KA9CO,EAAA,GAAA,IAAA,EAAA,GAAA,IAAA;EAAZ,gBAAM,EAAA,CAAA,GAAA,EAiDZ,eAjDY,EAAA,UAAA,EAkDL,mBAlDK,EAAA,GAmDd,iBAnDc;EAII,0BAAA,EAAA,CAAA,EAAA,EAgDU,SAhDV,EAAA,GAAA,EAgD0B,eAhD1B,EAAA,GAAA,IAAA;CAAc;UAoD7B,SAAA,CApDkD;EAAR,UAAA,EAAA,MAAA;EAChC,IAAA,EAAA,MAAA;EAGS,IAAA,EAAA,CAAA,IAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAAZ,KAAM,EAAA,CAAA,IAAA,CAAA,EAAA,MAAA,EAAA,MAAA,CAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAAK,EAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,OAAA,EAAA,CAAA,GAAA,IAAA,EAAA,GAAA,EAAA,EAAA,GAAA,IAAA,EAAA,GAAA,IAAA;AAG5B;AAEwC,KAoD5B,uBAAA,GApD4B;EAAZ,OAAM,EAAA,CAAA,GAAA,EAqDjB,OArDiB,EAAA,GAAA,EAqDH,QArDG,EAAA,GAqDU,MAAA,CAAO,MArDjB,CAAA,IAAA,EAAA,KAAA,EAAA,KAAA,CAAA;EAGN,YAAA,EAmDZ,KAAA,CAAM,KAnDM,CAmDA,YAnDA,CAAA;EAAZ,UAAM,EAoDR,KAAA,CAAM,KApDE,CAoDI,UApDJ,CAAA;EACV,gBAAA,EAAA,CAAA,GAAA,EAqDH,eArDG,EAAA,UAAA,EAsDI,mBAtDJ,EAAA,GAuDL,iBAvDK;CAGa;;;;AAIrB,cAgRS,6BAhRT,EAAA,CAAA,gBAgR0D,YAhR1D,CAAA,CAAA;EAAA,OAAA;EAAA,YAAA;EAAA,YAAA;EAAA,SAAA;EAAA,iBAAA;EAAA,OAAA;EAAA,UAAA;EAAA,cAAA;EAAA,eAAA;EAAA;AAAA,CAAA,EA2RD,uCA3RC,CA2RuC,aA3RvC,CAAA,EAAA,GA2RwD,MAAA,CAAO,MA3R/D,CA2RsE,uBA3RtE,CAAA;;;;;AAKkB,cAiVT,sCAjVS,EAAA,CAAA,gBAkVJ,YAlVI,EAAA,iBAAA,SAmVM,KAAA,CAAM,KAnVZ,CAmVkB,aAnVlB,EAAA,KAAA,EAAA,KAAA,CAAA,EAAA,GAAA,EAAA,CAAA,CAAA;EAAA,OAAA;EAAA,YAAA;EAAA,OAAA;EAAA,YAAA;EAAA,SAAA;EAAA,iBAAA;EAAA,OAAA;EAAA,WAAA;EAAA,cAAA;EAAA,eAAA;EAAA;AAAA,CAAA,EAgWnB,uCAhWmB,CAiWpB,aAjWoB,EAkWpB,QAlWoB,CAAA,EAAA,GAmWlB,OAnWkB,CAmWV,wBAnWU,CAAA;;;;;;;AAMF,cA6aP,8BA7aO,EAAA,CAAA,eAAA,CAAA,MAAA,EAAA,MAAA,EAAA,QAAA,EAAA,MAAA,GAAA,IAAA,EAAA,GAibb,MAAA,CAAO,MAjbM,CAkbhB,IAlbgB,CAkbX,CAAA,CAAE,SAlbS,CAAA,OAAA,CAAA,EAkbW,CAAA,CAAE,SAlbb,CAAA,OAAA,CAAA,EAAA,OAAA,CAAA,EAmbhB,eAnbgB,EAAA,OAAA,CAAA,GAAA,GAAA,EAAA,iBAAA,SAwbQ,KAAA,CAAM,KAxbd,CAAA,GAAA,EAAA,KAAA,EAAA,KAAA,CAAA,EAAA,GAwb2C,KAAA,CAAM,KAxbjD,CAAA,GAAA,EAAA,KAAA,EAAA,KAAA,CAAA,EAAA,CAAA,CAAA;EAAA,OAAA;EAAA,KAAA;EAAA,OAAA;EAAA,YAAA;EAAA,gBAAA;EAAA,SAAA;EAAA,iBAAA;EAAA,OAAA;EAAA,UAAA;EAAA,cAAA;EAAA,eAAA;EAAA;AAAA,CAAA,EA2cjB,+BA3ciB,CA4clB,MA5ckB,EA6clB,QA7ckB,CAAA,EAAA,GA8chB,OA9cgB,CA8cR,wBA9cQ,CAAA;;;cClHP,kEAEG,+BACF,0BAGL,6BACO,wBACX;cAsHQ,+CACI,gCACF,wFAGD;cAyBD,4CACG,+BACF;cA8BD,sEACI"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export * from "./uploadista-adapter";
2
- export { createUploadistaWebSocketHandler, createWebSocketCloseHandler, createWebSocketErrorHandler, createWebSocketMessageHandler, } from "./uploadista-websocket-handler";
1
+ import{FlowProvider as e,FlowServer as t}from"@uploadista/core/flow";import{createDataStoreLayer as n,inputFileSchema as r}from"@uploadista/core/types";import{UploadServer as i}from"@uploadista/core/upload";import{GenerateIdLive as a}from"@uploadista/core/utils";import{memoryEventBroadcaster as o}from"@uploadista/event-broadcaster-memory";import{webSocketEventEmitter as s}from"@uploadista/event-emitter-websocket";import{MetricsService as c,NoOpMetricsServiceLive as l,NodeSdkLive as u}from"@uploadista/observability";import{AdapterError as d,AuthCacheService as f,AuthCacheServiceLive as p,AuthContextService as m,AuthContextServiceLive as h,BadRequestError as g,ValidationError as _,createErrorResponseBody as v,createFlowServerLayer as y,createUploadServerLayer as b,createUploadistaErrorResponseBody as x,getLastSegment as S}from"@uploadista/server";import{Context as C,Effect as w,Layer as T}from"effect";import{UploadistaError as E}from"@uploadista/core/errors";const D=(e,t)=>{e.status(t.statusCode).json(v(t))},O=(e,t)=>{e.status(t.status).json(x(t))},k=e=>t=>{if(console.error(t),t instanceof d)return w.sync(()=>D(e,t));if(typeof t==`object`&&t&&`code`in t&&`status`in t&&`body`in t)return w.sync(()=>O(e,t));let n=`Internal server error`,r=`UNKNOWN_ERROR`,i=500;if(typeof t==`object`&&t){let e=t;`message`in e&&typeof e.message==`string`&&(n=e.message),`code`in e&&typeof e.code==`string`&&(r=e.code),`status`in e&&typeof e.status==`number`&&(i=e.status)}return w.sync(()=>{e.status(i).json({error:n,code:r,timestamp:new Date().toISOString()})})},A=(e,t,n)=>w.gen(function*(){let r=yield*(yield*m).getClientId(),i=S(new URL(e.url,`http://${e.get(`host`)}`).pathname);if(!i){t.status(400).json({error:`No id`});return}let a=yield*n.getFlowData(i,r);t.status(200).json(a)}).pipe(w.catchAll(k(t))),j=(e,t,n)=>w.gen(function*(){let r=yield*m,i=yield*f,a=yield*r.getClientId(),o=e.url.split(`/`),s=o.pop(),c=o.pop();if(!c){t.status(400).json({error:`No id`});return}if(!s){t.status(400).json({error:`No storage id`});return}let l=e.body;a?(console.log(`[Flow] Executing flow: ${c}, storage: ${s}, client: ${a}`),console.log(JSON.stringify(l,null,2))):(console.log(`Flow execution params: ${c} ${s}`),console.log(JSON.stringify(l,null,2)));let u=yield*n.runFlow({flowId:c,storageId:s,clientId:a,inputs:l.inputs}),d=yield*r.getAuthContext();d&&(yield*i.set(u.id,d)),a&&console.log(`[Flow] Flow started with jobId: ${u.id}, client: ${a}`),t.status(200).json(u)}).pipe(w.catchAll(k(t))),M=(e,t,n)=>w.gen(function*(){let r=e.url.split(`/`),i=r[r.length-2];if(!i){t.status(400).json({error:`No job id`});return}let a=yield*n.getJobStatus(i);t.status(200).json(a)}).pipe(w.catchAll(k(t))),N=(e,t,n)=>w.gen(function*(){let r=yield*(yield*m).getClientId(),i=new URL(e.url,`http://${e.get(`host`)}`).pathname.split(`/`),a=i[i.length-3],o=i[i.length-1];if(!a){console.error(`No job id`),t.status(400).json({error:`No job id`});return}if(!o){console.error(`No node id`),t.status(400).json({error:`No node id`});return}let s=e.get(`Content-Type`),c;if(s?.includes(`application/octet-stream`))c=new ReadableStream({start(t){e.on(`data`,e=>{t.enqueue(e)}),e.on(`end`,()=>{t.close()}),e.on(`error`,e=>{t.error(e)})}});else if(s?.includes(`application/json`)){let n=e.body;if(n.newData===void 0){console.error(`Missing newData`),t.status(400).json({error:`Missing newData`});return}c=n.newData}else{t.status(415).json({error:`Unsupported Content-Type`});return}let l=yield*n.continueFlow({jobId:a,nodeId:o,newData:c,clientId:r});t.status(200).json(l)}).pipe(w.catchAll(k(t))),P=(e,t,n)=>w.gen(function*(){let i=yield*m,a=yield*f,o=yield*i.getClientId();o&&console.log(`[Upload] Creating upload for client: ${o}`);let s=e.body;if(!s)return yield*w.fail(new g(`Invalid JSON payload`));let c=yield*w.sync(()=>r.safeParse(s));if(!c.success)return yield*w.fail(new _(`Invalid input file schema`));let l=yield*n.createUpload(c.data,o),u=yield*i.getAuthContext();u&&(yield*a.set(l.id,u)),o&&console.log(`[Upload] Upload created: ${l.id} for client: ${o}`),t.status(200).json(l)}).pipe(w.catchAll(k(t))),F=(e,t,n)=>w.gen(function*(){let r=yield*(yield*m).getClientId(),i=new URL(e.url,`http://${e.get(`host`)}`),a=i.pathname.split(`/`).filter(Boolean),o=a[a.length-1];if(o===`capabilities`){let e=i.searchParams.get(`storageId`)||a[a.length-2];if(!e)return yield*w.fail(new g(`storageId is required for capabilities`));let o=yield*n.getCapabilities(e,r);t.status(200).json({storageId:e,capabilities:o,timestamp:new Date().toISOString()});return}if(!o)return yield*w.fail(new g(`Upload ID is required`));let s=yield*n.getUpload(o);t.status(200).json(s)}).pipe(w.catchAll(k(t))),I=(e,t,n)=>w.gen(function*(){let r=yield*m,i=yield*f,a=yield*c,o=e.url.split(`/`).pop();if(!o)return yield*w.fail(new g(`Upload ID is required`));let s=yield*r.getClientId(),l=yield*r.getMetadata();if(!s){let e=yield*i.get(o);s=e?.clientId??null,l=e?.metadata??{}}s&&console.log(`[Upload] Uploading chunk for upload: ${o}, client: ${s}`);let u=new ReadableStream({start(t){e.on(`data`,e=>{t.enqueue(e)}),e.on(`end`,()=>{t.close()}),e.on(`error`,e=>{t.error(e)})}}),d=yield*n.uploadChunk(o,s,u);d.size&&d.offset>=d.size&&(yield*i.delete(o),s&&console.log(`[Upload] Upload completed, cleared auth cache: ${o}`),s&&d.size?(console.log(`[Upload] Recording metrics for org: ${s}, size: ${d.size}`),yield*w.forkDaemon(a.recordUpload(s,d.size,l))):console.warn(`[Upload] Cannot record metrics - missing organizationId or size`)),s&&console.log(`[Upload] Chunk uploaded for upload: ${o}, client: ${s}`),t.status(200).json(d)}).pipe(w.catchAll(k(t)));var L=class extends C.Tag(`ExpressUploadistaAdapterService`)(){};const R=(e,t,n)=>(r,i)=>{let a=r.url||``;if(!a.includes(`${e}/ws/`))return i.send(JSON.stringify({type:`error`,message:`WebSocket path must start with ${e}/ws/`})),i.close(1e3,`Invalid path`),{onMessage:()=>{},onClose:()=>{},onError:()=>{}};let o=a.replace(`${e}/ws/`,``).split(`/`).filter(Boolean),s=o.includes(`upload`),c=o.includes(`flow`),l=H(a,`jobId`),u=H(a,`uploadId`);if(!l&&!u&&o.length>=2){let e=o[0],t=o[1];e===`flow`?l=t:e===`upload`&&(u=t)}let d=l||u;console.log(`Uploadista websocket handler`,{jobId:l,uploadId:u,eventId:d});let f=w.gen(function*(){c&&l&&(yield*n.subscribeToFlowEvents(l,i)),s&&u&&(yield*t.subscribeToUploadEvents(u,i)),i.send(JSON.stringify({type:`connection`,message:`Uploadista WebSocket connected`,id:d,jobId:l,uploadId:u,timestamp:new Date().toISOString()}))}).pipe(w.catchAll(e=>w.sync(()=>{console.error(`Error subscribing to events:`,e);let t=e instanceof E?e.body:`Failed to subscribe to events`;i.send(JSON.stringify({type:`error`,message:t,code:e instanceof E?e.code:`SUBSCRIPTION_ERROR`}))})));return w.runFork(f),{onMessage:z(t,n,u,l,i),onClose:B(t,n,u,l),onError:V(d)}},z=(e,t,n,r,i)=>e=>{try{JSON.parse(e).type===`ping`&&i.send(JSON.stringify({type:`pong`,timestamp:new Date().toISOString()}))}catch(e){console.error(`Error handling WebSocket message:`,e),i.send(JSON.stringify({type:`error`,message:`Invalid message format`}))}},B=(e,t,n,r)=>()=>{let i=w.gen(function*(){r&&(yield*t.unsubscribeFromFlowEvents(r)),n&&(yield*e.unsubscribeFromUploadEvents(n))}).pipe(w.catchAll(e=>w.sync(()=>{console.error(`Error unsubscribing from events:`,e instanceof E?e.body:e)})));w.runFork(i)},V=e=>t=>{console.error(`WebSocket error for event ${e}:`,t)};function H(e,t){let n=RegExp(`[?&]${t}=([^&]*)`),r=e.match(n);return r?.[1]?decodeURIComponent(r[1]):void 0}const U=(e,n,r,a)=>T.effect(L,w.gen(function*(){let o=yield*i,s=yield*t,c=p(r);return{handler:(t,r)=>w.gen(function*(){let i=null;if(n){let e=yield*w.tryPromise({try:()=>n(t,r),catch:e=>(console.error(`Auth middleware error:`,e),{_tag:`AuthError`,error:e})}).pipe(w.timeout(`5 seconds`),w.catchAll(e=>e&&typeof e==`object`&&`_tag`in e&&e._tag===`TimeoutException`?(console.error(`Auth middleware timeout exceeded (5 seconds)`),w.succeed({_tag:`TimeoutError`})):w.succeed(null)));if(e&&typeof e==`object`&&`_tag`in e&&e._tag===`TimeoutError`){r.status(503).json({error:`Authentication service unavailable`,message:`Authentication took too long to respond. Please try again.`});return}if(e===null){r.status(401).json({error:`Unauthorized`,message:`Invalid credentials`});return}if(e&&typeof e==`object`&&`_tag`in e&&e._tag===`AuthError`){r.status(500).json({error:`Internal Server Error`,message:`An error occurred during authentication`});return}i=e}let u=h(i),d=T.mergeAll(u,c,a??l),f=new URL(t.url,`http://${t.get(`host`)}`);if(!f.pathname.includes(`${e}/api/`)){r.status(404).json({error:`Not found`});return}let p=f.pathname.replace(`${e}/api/`,``).split(`/`).filter(Boolean);if((p.includes(`upload`)&&t.method===`POST`||p.includes(`flow`)&&t.method===`POST`||p.includes(`continue`)&&t.get(`Content-Type`)?.includes(`application/json`))&&!t.body&&(yield*w.tryPromise({try:async()=>{let e=[];for await(let n of t)e.push(n);let n=Buffer.concat(e).toString();t.body=JSON.parse(n)},catch:e=>e})),p.includes(`upload`))switch(t.method){case`POST`:return yield*P(t,r,o).pipe(w.provide(d));case`GET`:return yield*F(t,r,o).pipe(w.provide(d));case`PATCH`:return yield*I(t,r,o).pipe(w.provide(d));default:r.status(405).json({error:`Method not allowed`});return}else if(p.includes(`flow`))switch(t.method){case`GET`:return yield*A(t,r,s).pipe(w.provide(d));case`POST`:return yield*j(t,r,s).pipe(w.provide(d));default:r.status(405).json({error:`Method not allowed`});return}else if(p.includes(`jobs`)){if(t.method===`GET`&&f.pathname.endsWith(`/status`))return yield*M(t,r,s).pipe(w.provide(d));if(t.method===`PATCH`&&p.includes(`continue`))return yield*N(t,r,s).pipe(w.provide(d));r.status(405).json({error:`Method not allowed`});return}else{r.status(404).json({error:`Not found`});return}}).pipe(w.catchAll(()=>w.sync(()=>{r.status(500).json({error:`Internal server error`})}))),websocketHandler:R(e,o,s)}})),W=({baseUrl:e,flowProvider:t,eventEmitter:n,dataStore:r,bufferedDataStore:i,kvStore:o,generateId:s=a,authMiddleware:c,authCacheConfig:l,metricsLayer:u})=>{let d=b({kvStore:o,eventEmitter:n,dataStore:r,bufferedDataStore:i,generateId:s}),f=y({kvStore:o,eventEmitter:n,flowProvider:t,uploadServer:d}),p=T.provide(U(e,c,l,u),T.mergeAll(d,f));return w.gen(function*(){let e=yield*L;return{handler:(t,n)=>e.handler(t,n),websocketHandler:(t,n)=>e.websocketHandler(t,n),uploadServer:d,flowServer:f}}).pipe(w.provide(p))},G=(e,t)=>t?w.runPromise(e.pipe(w.provide(u))):w.runPromise(e),K=async({baseUrl:e,flowProvider:t,plugins:n,eventEmitter:r,dataStore:i,bufferedDataStore:a,kvStore:o,withTracing:s=!1,authMiddleware:c,authCacheConfig:l,metricsLayer:u})=>{let d=await w.runPromise(W({baseUrl:e,flowProvider:t,eventEmitter:r,dataStore:i,bufferedDataStore:a,kvStore:o,authMiddleware:c,authCacheConfig:l,metricsLayer:u})),f=T.mergeAll(d.uploadServer,...n??[]);return{baseUrl:e,handler:(e,t,n)=>{G(d.handler(e,t).pipe(w.provide(f)),s).catch(e=>{console.error(`Express adapter error:`,e),n&&n(e)})},websocketHandler:(e,t)=>d.websocketHandler(e,t),websocketConnectionHandler:(t,n)=>{if(!n.url?.startsWith(`/${e}/ws/`)){t.close(1008,`Invalid WebSocket path`);return}console.log(`📡 WebSocket connected: ${n.url}`);let r={id:`conn_${Date.now()}_${Math.random().toString(36).substring(2,11)}`,send:e=>{t.readyState===t.OPEN&&t.send(e)},close:(e,n)=>t.close(e,n),readyState:t.readyState},i=d.websocketHandler(n,r);t.on(`message`,e=>{i.onMessage(e.toString())}),t.on(`close`,()=>{i.onClose()}),t.on(`error`,e=>{i.onError(e)})}}},q=async({baseUrl:t=`uploadista`,flows:r,plugins:i=[],eventEmitter:c,eventBroadcaster:l=o,dataStore:u,bufferedDataStore:d,kvStore:f,generateId:p=a,authMiddleware:m,authCacheConfig:h,metricsLayer:g})=>{let _=w.succeed({getFlow:(e,t)=>r(e,t)});return K({baseUrl:t,flowProvider:T.effect(e,_),plugins:i,eventEmitter:c??s(l),dataStore:await n(u),bufferedDataStore:d,kvStore:f,generateId:p,authMiddleware:m,authCacheConfig:h,metricsLayer:g})};export{q as createExpressUploadistaAdapter,W as createExpressUploadistaServer,K as createInternalExpressUploadistaAdapter,R as createUploadistaWebSocketHandler,B as createWebSocketCloseHandler,V as createWebSocketErrorHandler,z as createWebSocketMessageHandler};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["newData: unknown","BadRequestError","ValidationError","EffectContext","authContext: AuthContext | null","authResult:\n | AuthContext\n | null\n | { _tag: \"TimeoutError\" }\n | { _tag: \"AuthError\"; error: unknown }","chunks: Buffer[]","connection: WebSocketConnection"],"sources":["../src/error-types.ts","../src/flow-http-handlers.ts","../src/upload-http-handlers.ts","../src/uploadista-adapter-layer.ts","../src/uploadista-websocket-handler.ts","../src/uploadista-adapter.ts"],"sourcesContent":["import type { UploadistaError } from \"@uploadista/core/errors\";\nimport {\n AdapterError,\n BadRequestError as BaseBadRequestError,\n NotFoundError as BaseNotFoundError,\n ValidationError as BaseValidationError,\n createErrorResponseBody,\n createGenericErrorResponseBody,\n createUploadistaErrorResponseBody,\n} from \"@uploadista/server\";\nimport { Effect } from \"effect\";\nimport type { Response } from \"express\";\n\n// Re-export shared error types for backward compatibility\nexport {\n AdapterError as ExpressAdapterError,\n BaseValidationError as ValidationError,\n BaseNotFoundError as NotFoundError,\n BaseBadRequestError as BadRequestError,\n};\n\n/**\n * Sends error response using Express Response object\n */\nexport const sendErrorResponse = (res: Response, error: AdapterError): void => {\n res.status(error.statusCode).json(createErrorResponseBody(error));\n};\n\n/**\n * Sends UploadistaError response using Express Response object\n */\nexport const sendUploadistaErrorResponse = (\n res: Response,\n error: UploadistaError,\n): void => {\n res.status(error.status).json(createUploadistaErrorResponseBody(error));\n};\n\n/**\n * Sends generic error response using Express Response object\n */\nexport const sendGenericErrorResponse = (\n res: Response,\n message = \"Internal server error\",\n): void => {\n res.status(500).json(createGenericErrorResponseBody(message));\n};\n\n/**\n * Universal error handler that sends error response via Express Response.\n * Handles AdapterError, UploadistaError, and unknown errors.\n * This is the recommended way to handle errors in HTTP handlers.\n */\nexport const handleErrorResponse = (res: Response) => (error: unknown) => {\n console.error(error);\n\n // Handle known adapter errors\n if (error instanceof AdapterError) {\n return Effect.sync(() => sendErrorResponse(res, error));\n }\n\n // Handle UploadistaError\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n \"status\" in error &&\n \"body\" in error\n ) {\n return Effect.sync(() =>\n sendUploadistaErrorResponse(res, error as UploadistaError),\n );\n }\n\n // Handle unknown errors - try to extract what we can\n let message = \"Internal server error\";\n let code = \"UNKNOWN_ERROR\";\n let status = 500;\n\n if (typeof error === \"object\" && error !== null) {\n const errorObj = error as Record<string, unknown>;\n\n if (\"message\" in errorObj && typeof errorObj.message === \"string\") {\n message = errorObj.message;\n }\n\n if (\"code\" in errorObj && typeof errorObj.code === \"string\") {\n code = errorObj.code;\n }\n\n if (\"status\" in errorObj && typeof errorObj.status === \"number\") {\n status = errorObj.status;\n }\n }\n\n return Effect.sync(() => {\n res.status(status).json({\n error: message,\n code,\n timestamp: new Date().toISOString(),\n });\n });\n};\n","import type { FlowServerShape } from \"@uploadista/core/flow\";\nimport {\n AuthCacheService,\n AuthContextService,\n getLastSegment,\n} from \"@uploadista/server\";\nimport { Effect } from \"effect\";\nimport type { Request, Response } from \"express\";\nimport { handleErrorResponse } from \"./error-types\";\n\nexport const handleFlowGet = (\n req: Request,\n res: Response,\n flowServer: FlowServerShape,\n) => {\n return Effect.gen(function* () {\n // Access auth context if available\n const authService = yield* AuthContextService;\n const clientId = yield* authService.getClientId();\n\n const url = new URL(req.url, `http://${req.get(\"host\")}`);\n const id = getLastSegment(url.pathname);\n if (!id) {\n res.status(400).json({ error: \"No id\" });\n return;\n }\n\n const flowData = yield* flowServer.getFlowData(id, clientId);\n\n res.status(200).json(flowData);\n }).pipe(Effect.catchAll(handleErrorResponse(res)));\n};\n\nexport const handleFlowPost = <TRequirements = never>(\n req: Request,\n res: Response,\n flowServer: FlowServerShape,\n) => {\n return Effect.gen(function* () {\n const authService = yield* AuthContextService;\n const authCache = yield* AuthCacheService;\n const clientId = yield* authService.getClientId();\n\n const urlSegments = req.url.split(\"/\");\n const storageId = urlSegments.pop();\n const flowId = urlSegments.pop();\n\n if (!flowId) {\n res.status(400).json({ error: \"No id\" });\n return;\n }\n if (!storageId) {\n res.status(400).json({ error: \"No storage id\" });\n return;\n }\n\n const params = req.body;\n\n if (clientId) {\n console.log(\n `[Flow] Executing flow: ${flowId}, storage: ${storageId}, client: ${clientId}`,\n );\n console.log(JSON.stringify(params, null, 2));\n } else {\n console.log(`Flow execution params: ${flowId} ${storageId}`);\n console.log(JSON.stringify(params, null, 2));\n }\n\n // Run flow returns immediately with jobId\n const result = yield* flowServer.runFlow<TRequirements>({\n flowId,\n storageId,\n clientId,\n inputs: params.inputs,\n });\n\n // Cache auth context for subsequent flow operations (continue, status)\n const authContext = yield* authService.getAuthContext();\n if (authContext) {\n yield* authCache.set(result.id, authContext);\n }\n\n if (clientId) {\n console.log(\n `[Flow] Flow started with jobId: ${result.id}, client: ${clientId}`,\n );\n }\n\n res.status(200).json(result);\n }).pipe(Effect.catchAll(handleErrorResponse(res)));\n};\n\nexport const handleJobStatus = (\n req: Request,\n res: Response,\n flowServer: FlowServerShape,\n): Effect.Effect<void> => {\n return Effect.gen(function* () {\n const urlSegments = req.url.split(\"/\");\n const jobId = urlSegments[urlSegments.length - 2]; // .../jobs/:jobId/status\n\n if (!jobId) {\n res.status(400).json({ error: \"No job id\" });\n return;\n }\n\n const result = yield* flowServer.getJobStatus(jobId);\n\n res.status(200).json(result);\n }).pipe(Effect.catchAll(handleErrorResponse(res)));\n};\n\nexport const handleContinueFlow = <TRequirements = never>(\n req: Request,\n res: Response,\n flowServer: FlowServerShape,\n) => {\n return Effect.gen(function* () {\n const authService = yield* AuthContextService;\n const clientId = yield* authService.getClientId();\n\n const url = new URL(req.url, `http://${req.get(\"host\")}`);\n const urlSegments = url.pathname.split(\"/\");\n const jobId = urlSegments[urlSegments.length - 3]; // .../jobs/:jobId/continue/:nodeId\n const nodeId = urlSegments[urlSegments.length - 1]; // .../jobs/:jobId/continue/:nodeId\n\n if (!jobId) {\n console.error(\"No job id\");\n res.status(400).json({ error: \"No job id\" });\n return;\n }\n\n if (!nodeId) {\n console.error(\"No node id\");\n res.status(400).json({ error: \"No node id\" });\n return;\n }\n\n const contentType = req.get(\"Content-Type\");\n\n let newData: unknown;\n\n // Handle different content types\n if (contentType?.includes(\"application/octet-stream\")) {\n // For streaming data, convert Node.js Readable to web ReadableStream\n newData = new ReadableStream({\n start(controller) {\n req.on(\"data\", (chunk) => {\n controller.enqueue(chunk);\n });\n req.on(\"end\", () => {\n controller.close();\n });\n req.on(\"error\", (error) => {\n controller.error(error);\n });\n },\n });\n } else if (contentType?.includes(\"application/json\")) {\n // For JSON data, use the parsed body\n const body = req.body;\n\n if (body.newData === undefined) {\n console.error(\"Missing newData\");\n res.status(400).json({ error: \"Missing newData\" });\n return;\n }\n\n newData = body.newData;\n } else {\n res.status(415).json({ error: \"Unsupported Content-Type\" });\n return;\n }\n\n const result = yield* flowServer.continueFlow<TRequirements>({\n jobId,\n nodeId,\n newData,\n clientId,\n });\n\n res.status(200).json(result);\n }).pipe(Effect.catchAll(handleErrorResponse(res)));\n};\n","import { inputFileSchema } from \"@uploadista/core/types\";\nimport type { UploadServerShape } from \"@uploadista/core/upload\";\nimport { MetricsService } from \"@uploadista/observability\";\nimport { AuthCacheService, AuthContextService } from \"@uploadista/server\";\nimport { Effect } from \"effect\";\nimport type { Request, Response } from \"express\";\nimport {\n BadRequestError,\n handleErrorResponse,\n ValidationError,\n} from \"./error-types\";\n\nexport const handleUploadPost = (\n req: Request,\n res: Response,\n server: UploadServerShape,\n) =>\n Effect.gen(function* () {\n // Access auth context if available\n const authService = yield* AuthContextService;\n const authCache = yield* AuthCacheService;\n const clientId = yield* authService.getClientId();\n\n if (clientId) {\n console.log(`[Upload] Creating upload for client: ${clientId}`);\n }\n\n const json = req.body;\n\n if (!json) {\n return yield* Effect.fail(new BadRequestError(\"Invalid JSON payload\"));\n }\n\n const parsedInputFile = yield* Effect.sync(() =>\n inputFileSchema.safeParse(json),\n );\n\n if (!parsedInputFile.success) {\n return yield* Effect.fail(\n new ValidationError(\"Invalid input file schema\"),\n );\n }\n\n const fileCreated = yield* server.createUpload(\n parsedInputFile.data,\n clientId,\n );\n\n // Cache auth context for subsequent chunk uploads\n const authContext = yield* authService.getAuthContext();\n if (authContext) {\n yield* authCache.set(fileCreated.id, authContext);\n }\n\n if (clientId) {\n console.log(\n `[Upload] Upload created: ${fileCreated.id} for client: ${clientId}`,\n );\n }\n\n res.status(200).json(fileCreated);\n }).pipe(Effect.catchAll(handleErrorResponse(res)));\n\nexport const handleUploadGet = (\n req: Request,\n res: Response,\n server: UploadServerShape,\n) =>\n Effect.gen(function* () {\n const authService = yield* AuthContextService;\n const clientId = yield* authService.getClientId();\n\n const url = new URL(req.url, `http://${req.get(\"host\")}`);\n const pathSegments = url.pathname.split(\"/\").filter(Boolean);\n const lastSegment = pathSegments[pathSegments.length - 1];\n\n if (lastSegment === \"capabilities\") {\n const storageId =\n url.searchParams.get(\"storageId\") ||\n pathSegments[pathSegments.length - 2];\n\n if (!storageId) {\n return yield* Effect.fail(\n new BadRequestError(\"storageId is required for capabilities\"),\n );\n }\n\n const capabilities = yield* server.getCapabilities(storageId, clientId);\n\n res.status(200).json({\n storageId,\n capabilities,\n timestamp: new Date().toISOString(),\n });\n return;\n }\n\n if (!lastSegment) {\n return yield* Effect.fail(new BadRequestError(\"Upload ID is required\"));\n }\n\n const fileResult = yield* server.getUpload(lastSegment);\n\n res.status(200).json(fileResult);\n }).pipe(Effect.catchAll(handleErrorResponse(res)));\n\nexport const handleUploadPatch = (\n req: Request,\n res: Response,\n server: UploadServerShape,\n) =>\n Effect.gen(function* () {\n // Try to get auth from current request or cached auth\n const authService = yield* AuthContextService;\n const authCache = yield* AuthCacheService;\n const metricsService = yield* MetricsService;\n\n const uploadId = req.url.split(\"/\").pop();\n if (!uploadId) {\n return yield* Effect.fail(new BadRequestError(\"Upload ID is required\"));\n }\n\n // Try current auth first, fallback to cached auth\n let clientId = yield* authService.getClientId();\n let authMetadata = yield* authService.getMetadata();\n if (!clientId) {\n const cachedAuth = yield* authCache.get(uploadId);\n clientId = cachedAuth?.clientId ?? null;\n authMetadata = cachedAuth?.metadata ?? {};\n }\n\n if (clientId) {\n console.log(\n `[Upload] Uploading chunk for upload: ${uploadId}, client: ${clientId}`,\n );\n }\n\n // Convert Node.js Readable stream to web ReadableStream\n const body = new ReadableStream({\n start(controller) {\n req.on(\"data\", (chunk) => {\n controller.enqueue(chunk);\n });\n req.on(\"end\", () => {\n controller.close();\n });\n req.on(\"error\", (error) => {\n controller.error(error);\n });\n },\n });\n\n const fileResult = yield* server.uploadChunk(uploadId, clientId, body);\n\n // Clear cache and record metrics if upload is complete\n if (fileResult.size && fileResult.offset >= fileResult.size) {\n yield* authCache.delete(uploadId);\n if (clientId) {\n console.log(\n `[Upload] Upload completed, cleared auth cache: ${uploadId}`,\n );\n }\n\n // Record upload metrics if we have organization ID\n if (clientId && fileResult.size) {\n console.log(\n `[Upload] Recording metrics for org: ${clientId}, size: ${fileResult.size}`,\n );\n yield* Effect.forkDaemon(\n metricsService.recordUpload(clientId, fileResult.size, authMetadata),\n );\n } else {\n console.warn(\n `[Upload] Cannot record metrics - missing organizationId or size`,\n );\n }\n }\n\n if (clientId) {\n console.log(\n `[Upload] Chunk uploaded for upload: ${uploadId}, client: ${clientId}`,\n );\n }\n\n res.status(200).json(fileResult);\n }).pipe(Effect.catchAll(handleErrorResponse(res)));\n","import type { IncomingMessage } from \"node:http\";\nimport { type Effect, Context as EffectContext } from \"effect\";\nimport type { Request, Response } from \"express\";\n\nexport interface WebSocketConnection {\n id: string;\n send: (data: string) => void;\n close: (code?: number, reason?: string) => void;\n readyState: number;\n}\n\nexport type WebSocketHandlers = {\n onMessage: (message: string) => void;\n onClose: () => void;\n onError: (error: Error) => void;\n};\n\nexport type ExpressWebSocketHandler = (\n req: IncomingMessage,\n connection: WebSocketConnection,\n) => WebSocketHandlers;\n\n// Define the Uploadista adapter service interface\nexport type ExpressUploadistaAdapterServiceShape = {\n handler: (req: Request, res: Response) => Effect.Effect<void, never, never>;\n websocketHandler: ExpressWebSocketHandler;\n};\n\n// Context Tag for the Uploadista adapter service\nexport class ExpressUploadistaAdapterService extends EffectContext.Tag(\n \"ExpressUploadistaAdapterService\",\n)<ExpressUploadistaAdapterService, ExpressUploadistaAdapterServiceShape>() {}\n","import type { IncomingMessage } from \"node:http\";\nimport { UploadistaError } from \"@uploadista/core/errors\";\nimport type { FlowServerShape } from \"@uploadista/core/flow\";\nimport type { UploadServerShape } from \"@uploadista/core/upload\";\nimport { Effect } from \"effect\";\nimport type {\n WebSocketConnection,\n WebSocketHandlers,\n} from \"./uploadista-adapter-layer\";\n\nexport const createUploadistaWebSocketHandler = (\n baseUrl: string,\n uploadServer: UploadServerShape,\n flowServer: FlowServerShape,\n) => {\n return (\n req: IncomingMessage,\n connection: WebSocketConnection,\n ): WebSocketHandlers => {\n // Check for ws/uploadista prefix\n const url = req.url || \"\";\n\n if (!url.includes(`${baseUrl}/ws/`)) {\n connection.send(\n JSON.stringify({\n type: \"error\",\n message: `WebSocket path must start with ${baseUrl}/ws/`,\n }),\n );\n connection.close(1000, \"Invalid path\");\n // Return no-op handlers since connection is closed\n return {\n onMessage: () => {},\n onClose: () => {},\n onError: () => {},\n };\n }\n\n // Remove the prefix and get the actual route segments\n const routeSegments = url\n .replace(`${baseUrl}/ws/`, \"\")\n .split(\"/\")\n .filter(Boolean);\n\n const isUploadRoute = routeSegments.includes(\"upload\");\n const isFlowRoute = routeSegments.includes(\"flow\");\n\n // Extract jobId and uploadId from URL path or query parameters\n // Path format: /uploadista/ws/flow/{jobId} or /uploadista/ws/upload/{uploadId}\n let jobId = extractQueryParam(url, \"jobId\");\n let uploadId = extractQueryParam(url, \"uploadId\");\n\n // If not in query params, extract from path segments\n if (!jobId && !uploadId && routeSegments.length >= 2) {\n const routeType = routeSegments[0]; // 'flow' or 'upload'\n const id = routeSegments[1]; // the actual ID\n\n if (routeType === \"flow\") {\n jobId = id;\n } else if (routeType === \"upload\") {\n uploadId = id;\n }\n }\n\n // Use jobId if available, otherwise use uploadId\n const eventId = jobId || uploadId;\n\n console.log(\"Uploadista websocket handler\", { jobId, uploadId, eventId });\n\n const subscribeEffect = Effect.gen(function* () {\n // Subscribe to flow events if we had a jobId\n if (isFlowRoute && jobId) {\n // Subscribe to flow events (this handles job tracking)\n yield* flowServer.subscribeToFlowEvents(jobId, connection);\n }\n\n // If we have an uploadId, also subscribe to upload events\n // These will be treated as task events within the job\n if (isUploadRoute && uploadId) {\n yield* uploadServer.subscribeToUploadEvents(uploadId, connection);\n }\n\n connection.send(\n JSON.stringify({\n type: \"connection\",\n message: \"Uploadista WebSocket connected\",\n id: eventId,\n jobId,\n uploadId,\n timestamp: new Date().toISOString(),\n }),\n );\n }).pipe(\n Effect.catchAll((error) =>\n Effect.sync(() => {\n console.error(\"Error subscribing to events:\", error);\n const errorMessage =\n error instanceof UploadistaError\n ? error.body\n : \"Failed to subscribe to events\";\n connection.send(\n JSON.stringify({\n type: \"error\",\n message: errorMessage,\n code:\n error instanceof UploadistaError\n ? error.code\n : \"SUBSCRIPTION_ERROR\",\n }),\n );\n }),\n ),\n );\n\n Effect.runFork(subscribeEffect);\n\n // Return handlers for WebSocket events\n return {\n onMessage: createWebSocketMessageHandler(\n uploadServer,\n flowServer,\n uploadId,\n jobId,\n connection,\n ),\n onClose: createWebSocketCloseHandler(\n uploadServer,\n flowServer,\n uploadId,\n jobId,\n ),\n onError: createWebSocketErrorHandler(eventId),\n };\n };\n};\n\nexport const createWebSocketMessageHandler = (\n _uploadServer: UploadServerShape,\n _flowServer: FlowServerShape,\n _uploadId: string | undefined,\n _jobId: string | undefined,\n connection: WebSocketConnection,\n) => {\n return (message: string): void => {\n try {\n const parsed = JSON.parse(message);\n if (parsed.type === \"ping\") {\n connection.send(\n JSON.stringify({\n type: \"pong\",\n timestamp: new Date().toISOString(),\n }),\n );\n }\n } catch (error) {\n console.error(\"Error handling WebSocket message:\", error);\n connection.send(\n JSON.stringify({\n type: \"error\",\n message: \"Invalid message format\",\n }),\n );\n }\n };\n};\n\nexport const createWebSocketCloseHandler = (\n uploadServer: UploadServerShape,\n flowServer: FlowServerShape,\n uploadId: string | undefined,\n jobId: string | undefined,\n) => {\n return (): void => {\n const unsubscribeEffect = Effect.gen(function* () {\n // Unsubscribe from flow events if we had a jobId\n if (jobId) {\n yield* flowServer.unsubscribeFromFlowEvents(jobId);\n }\n\n // Unsubscribe from upload events if we had an uploadId\n if (uploadId) {\n yield* uploadServer.unsubscribeFromUploadEvents(uploadId);\n }\n }).pipe(\n Effect.catchAll((error) =>\n Effect.sync(() => {\n console.error(\n \"Error unsubscribing from events:\",\n error instanceof UploadistaError ? error.body : error,\n );\n }),\n ),\n );\n\n Effect.runFork(unsubscribeEffect);\n };\n};\n\nexport const createWebSocketErrorHandler = (eventId: string | undefined) => {\n return (error: Error): void => {\n console.error(`WebSocket error for event ${eventId}:`, error);\n };\n};\n\nfunction extractQueryParam(url: string, param: string): string | undefined {\n const regex = new RegExp(`[?&]${param}=([^&]*)`);\n const match = url.match(regex);\n return match?.[1] ? decodeURIComponent(match[1]) : undefined;\n}\n","import type { IncomingMessage } from \"node:http\";\nimport type {\n EventBroadcasterService,\n UploadFileDataStores,\n UploadistaError,\n} from \"@uploadista/core\";\nimport { type Flow, FlowProvider, FlowServer } from \"@uploadista/core/flow\";\nimport {\n type BaseEventEmitterService,\n type BaseKvStoreService,\n createDataStoreLayer,\n type DataStoreConfig,\n type UploadFileDataStore,\n type UploadFileKVStore,\n} from \"@uploadista/core/types\";\nimport { UploadServer } from \"@uploadista/core/upload\";\nimport { type GenerateId, GenerateIdLive } from \"@uploadista/core/utils\";\nimport { memoryEventBroadcaster } from \"@uploadista/event-broadcaster-memory\";\nimport { webSocketEventEmitter } from \"@uploadista/event-emitter-websocket\";\nimport {\n type MetricsService,\n NodeSdkLive,\n NoOpMetricsServiceLive,\n} from \"@uploadista/observability\";\nimport {\n type AuthCacheConfig,\n AuthCacheServiceLive,\n type AuthContext,\n AuthContextServiceLive,\n type AuthResult,\n createFlowServerLayer,\n createUploadServerLayer,\n type FlowRequirementsOf,\n} from \"@uploadista/server\";\nimport { Effect, Layer } from \"effect\";\nimport type { Request, Response } from \"express\";\nimport type { z } from \"zod\";\nimport {\n handleContinueFlow,\n handleFlowGet,\n handleFlowPost,\n handleJobStatus,\n} from \"./flow-http-handlers\";\nimport {\n handleUploadGet,\n handleUploadPatch,\n handleUploadPost,\n} from \"./upload-http-handlers\";\nimport {\n ExpressUploadistaAdapterService,\n type ExpressUploadistaAdapterServiceShape,\n type WebSocketConnection,\n type WebSocketHandlers,\n} from \"./uploadista-adapter-layer\";\nimport { createUploadistaWebSocketHandler } from \"./uploadista-websocket-handler\";\n\nexport type ExpressUploadistaAdapterOptions<\n TFlows extends (\n flowId: string,\n clientId: string | null,\n ) => Effect.Effect<\n Flow<z.ZodSchema<unknown>, z.ZodSchema<unknown>, unknown>,\n UploadistaError,\n unknown\n // biome-ignore lint/suspicious/noExplicitAny: Generic type constraint allows any flow function type\n > = any,\n // biome-ignore lint/suspicious/noExplicitAny: Permissive constraint allows plugin tuples, validation via PluginAssertion\n TPlugins extends readonly Layer.Layer<any, never, never>[] = Layer.Layer<\n any,\n never,\n never\n >[],\n> = {\n // Flow configuration\n flows: TFlows;\n plugins?: TPlugins;\n\n dataStore: DataStoreConfig;\n bufferedDataStore?: Layer.Layer<\n UploadFileDataStore,\n never,\n UploadFileKVStore\n >;\n\n // Shared configuration\n baseUrl?: string;\n kvStore: Layer.Layer<BaseKvStoreService>;\n eventEmitter?: Layer.Layer<BaseEventEmitterService>;\n eventBroadcaster?: Layer.Layer<EventBroadcasterService>;\n generateId?: Layer.Layer<GenerateId>;\n withTracing?: boolean;\n\n // Authentication\n authMiddleware?: (req: Request, res: Response) => Promise<AuthResult>;\n authCacheConfig?: AuthCacheConfig;\n\n // Metrics\n metricsLayer?: Layer.Layer<MetricsService, never, never>;\n};\n\nexport type InternalExpressUploadistaAdapterOptions<\n TRequirements = never,\n TPlugins extends readonly Layer.Layer<TRequirements, never, never>[] = [],\n> = {\n // Flow configuration\n flowProvider: Layer.Layer<FlowProvider>;\n plugins?: TPlugins;\n\n // Upload configuration\n dataStore: Layer.Layer<UploadFileDataStores, never, UploadFileKVStore>;\n bufferedDataStore?: Layer.Layer<\n UploadFileDataStore,\n never,\n UploadFileKVStore\n >;\n // Shared configuration\n baseUrl: string;\n kvStore: Layer.Layer<BaseKvStoreService>;\n eventEmitter: Layer.Layer<BaseEventEmitterService>;\n generateId?: Layer.Layer<GenerateId>;\n withTracing?: boolean;\n\n // Authentication\n authMiddleware?: (req: Request, res: Response) => Promise<AuthResult>;\n authCacheConfig?: AuthCacheConfig;\n\n // Metrics\n metricsLayer?: Layer.Layer<MetricsService, never, never>;\n};\n\nexport type ExpressUploadistaAdapter = {\n baseUrl: string;\n handler: (\n req: Request,\n res: Response,\n next?: (error?: Error) => void,\n ) => void;\n websocketHandler: (\n req: IncomingMessage,\n connection: WebSocketConnection,\n ) => WebSocketHandlers;\n websocketConnectionHandler: (ws: WebSocket, req: IncomingMessage) => void;\n};\n\n// WebSocket type from ws package\ninterface WebSocket {\n readyState: number;\n OPEN: number;\n send: (data: string) => void;\n close: (code?: number, reason?: string) => void;\n on: (event: string, handler: (...args: any[]) => void) => void;\n}\n\n// Effect-native API\nexport type ExpressUploadistaServer = {\n handler: (req: Request, res: Response) => Effect.Effect<void, never, never>;\n uploadServer: Layer.Layer<UploadServer>;\n flowServer: Layer.Layer<FlowServer>;\n websocketHandler: (\n req: IncomingMessage,\n connection: WebSocketConnection,\n ) => WebSocketHandlers;\n};\n\n// Effect-based service factory for creating the unified adapter layer\nconst createExpressUploadistaAdapterServiceLayer = (\n baseUrl: string,\n authMiddleware?: (req: Request, res: Response) => Promise<AuthResult>,\n authCacheConfig?: AuthCacheConfig,\n metricsLayer?: Layer.Layer<MetricsService, never, never>,\n) =>\n Layer.effect(\n ExpressUploadistaAdapterService,\n Effect.gen(function* () {\n const uploadServer = yield* UploadServer;\n const flowServer = yield* FlowServer;\n\n // Create auth cache layer (always present, even if auth is not enabled)\n const authCacheLayer = AuthCacheServiceLive(authCacheConfig);\n\n return {\n handler: (req: Request, res: Response) =>\n Effect.gen(function* () {\n // Call auth middleware if configured and create auth context layer\n let authContext: AuthContext | null = null;\n if (authMiddleware) {\n // Run auth middleware with timeout protection (5 seconds default)\n const authMiddlewareWithTimeout = Effect.tryPromise({\n try: () => authMiddleware(req, res),\n catch: (error) => {\n console.error(\"Auth middleware error:\", error);\n return { _tag: \"AuthError\" as const, error };\n },\n }).pipe(\n Effect.timeout(\"5 seconds\"),\n Effect.catchAll((error) => {\n // Check if timeout occurred\n if (error && typeof error === \"object\" && \"_tag\" in error) {\n if (error._tag === \"TimeoutException\") {\n console.error(\n \"Auth middleware timeout exceeded (5 seconds)\",\n );\n return Effect.succeed({\n _tag: \"TimeoutError\" as const,\n } as const);\n }\n }\n return Effect.succeed(null);\n }),\n );\n\n const authResult:\n | AuthContext\n | null\n | { _tag: \"TimeoutError\" }\n | { _tag: \"AuthError\"; error: unknown } =\n yield* authMiddlewareWithTimeout;\n\n // If auth middleware timed out, return 503 Service Unavailable\n if (\n authResult &&\n typeof authResult === \"object\" &&\n \"_tag\" in authResult &&\n authResult._tag === \"TimeoutError\"\n ) {\n res.status(503).json({\n error: \"Authentication service unavailable\",\n message:\n \"Authentication took too long to respond. Please try again.\",\n });\n return;\n }\n\n // If auth middleware returned null, authentication failed\n if (authResult === null) {\n res.status(401).json({\n error: \"Unauthorized\",\n message: \"Invalid credentials\",\n });\n return;\n }\n\n // Check for error marker (shouldn't happen after catchAll, but for type safety)\n if (\n authResult &&\n typeof authResult === \"object\" &&\n \"_tag\" in authResult &&\n authResult._tag === \"AuthError\"\n ) {\n res.status(500).json({\n error: \"Internal Server Error\",\n message: \"An error occurred during authentication\",\n });\n return;\n }\n\n authContext = authResult;\n }\n\n // Create auth context layer for this request\n const authContextLayer = AuthContextServiceLive(authContext);\n\n // Combine auth context, auth cache, and metrics layers\n // Always provide a metrics layer (either real or no-op) to satisfy type requirements\n const authLayer = Layer.mergeAll(\n authContextLayer,\n authCacheLayer,\n metricsLayer ?? NoOpMetricsServiceLive,\n );\n\n const url = new URL(req.url, `http://${req.get(\"host\")}`);\n\n // Check for uploadista/api/ prefix\n if (!url.pathname.includes(`${baseUrl}/api/`)) {\n res.status(404).json({ error: \"Not found\" });\n return;\n }\n\n // Remove the prefix and get the actual route segments\n const routeSegments = url.pathname\n .replace(`${baseUrl}/api/`, \"\")\n .split(\"/\")\n .filter(Boolean);\n\n // Parse JSON body for routes that need it\n const needsJsonBody =\n (routeSegments.includes(\"upload\") && req.method === \"POST\") ||\n (routeSegments.includes(\"flow\") && req.method === \"POST\") ||\n (routeSegments.includes(\"continue\") &&\n req.get(\"Content-Type\")?.includes(\"application/json\"));\n\n if (needsJsonBody && !req.body) {\n // Manually parse JSON body\n yield* Effect.tryPromise({\n try: async () => {\n const chunks: Buffer[] = [];\n for await (const chunk of req) {\n chunks.push(chunk as Buffer);\n }\n const body = Buffer.concat(chunks).toString();\n req.body = JSON.parse(body);\n },\n catch: (error) => error,\n });\n }\n\n // Route based on path\n if (routeSegments.includes(\"upload\")) {\n // Upload API routes - these now create jobs behind the scenes\n switch (req.method) {\n case \"POST\":\n return yield* handleUploadPost(req, res, uploadServer).pipe(\n Effect.provide(authLayer),\n );\n case \"GET\":\n return yield* handleUploadGet(req, res, uploadServer).pipe(\n Effect.provide(authLayer),\n );\n case \"PATCH\":\n return yield* handleUploadPatch(req, res, uploadServer).pipe(\n Effect.provide(authLayer),\n );\n default:\n res.status(405).json({ error: \"Method not allowed\" });\n return;\n }\n } else if (routeSegments.includes(\"flow\")) {\n // Flow API routes\n switch (req.method) {\n case \"GET\":\n return yield* handleFlowGet(req, res, flowServer).pipe(\n Effect.provide(authLayer),\n );\n case \"POST\":\n return yield* handleFlowPost<never>(\n req,\n res,\n flowServer,\n ).pipe(Effect.provide(authLayer));\n default:\n res.status(405).json({ error: \"Method not allowed\" });\n return;\n }\n } else if (routeSegments.includes(\"jobs\")) {\n // Unified job status routes\n if (req.method === \"GET\" && url.pathname.endsWith(\"/status\")) {\n return yield* handleJobStatus(req, res, flowServer).pipe(\n Effect.provide(authLayer),\n );\n } else if (\n req.method === \"PATCH\" &&\n routeSegments.includes(\"continue\")\n ) {\n return yield* handleContinueFlow<never>(\n req,\n res,\n flowServer,\n ).pipe(Effect.provide(authLayer));\n }\n res.status(405).json({ error: \"Method not allowed\" });\n return;\n } else {\n res.status(404).json({ error: \"Not found\" });\n return;\n }\n }).pipe(\n Effect.catchAll(() =>\n Effect.sync(() => {\n res.status(500).json({ error: \"Internal server error\" });\n }),\n ),\n ),\n\n websocketHandler: createUploadistaWebSocketHandler(\n baseUrl,\n uploadServer,\n flowServer,\n ),\n } satisfies ExpressUploadistaAdapterServiceShape;\n }),\n );\n\n/**\n * Creates an Effect-native unified Express server - combining upload and flow capabilities\n */\nexport const createExpressUploadistaServer = <TRequirements = UploadServer>({\n baseUrl,\n flowProvider,\n eventEmitter,\n dataStore,\n bufferedDataStore,\n kvStore,\n generateId = GenerateIdLive,\n authMiddleware,\n authCacheConfig,\n metricsLayer,\n}: InternalExpressUploadistaAdapterOptions<TRequirements>): Effect.Effect<ExpressUploadistaServer> => {\n // Set up upload server dependencies using shared utility\n const uploadServerLayer = createUploadServerLayer({\n kvStore,\n eventEmitter,\n dataStore,\n bufferedDataStore,\n generateId,\n });\n\n // Set up flow server dependencies using shared utility\n const flowServerLayer = createFlowServerLayer({\n kvStore,\n eventEmitter,\n flowProvider,\n uploadServer: uploadServerLayer,\n });\n\n // Set up adapter\n const adapterLayer = Layer.provide(\n createExpressUploadistaAdapterServiceLayer(\n baseUrl,\n authMiddleware,\n authCacheConfig,\n metricsLayer,\n ),\n Layer.mergeAll(uploadServerLayer, flowServerLayer),\n );\n\n return Effect.gen(function* () {\n const adapterService = yield* ExpressUploadistaAdapterService;\n\n return {\n handler: (req: Request, res: Response) =>\n adapterService.handler(req, res),\n websocketHandler: (\n req: IncomingMessage,\n connection: WebSocketConnection,\n ) => adapterService.websocketHandler(req, connection),\n uploadServer: uploadServerLayer,\n flowServer: flowServerLayer,\n } satisfies ExpressUploadistaServer;\n }).pipe(Effect.provide(adapterLayer));\n};\n\nconst runProgram = <A, E>(\n effect: Effect.Effect<A, E>,\n withTracing: boolean,\n) => {\n if (withTracing) {\n return Effect.runPromise(effect.pipe(Effect.provide(NodeSdkLive)));\n }\n return Effect.runPromise(effect);\n};\n\n/**\n * Creates a Promise-based Express adapter for compatibility with existing Express applications\n * This wraps the Effect-native version with Promise conversion and caches the server instance\n */\nexport const createInternalExpressUploadistaAdapter = async <\n TRequirements = UploadServer,\n TPlugins extends readonly Layer.Layer<TRequirements, never, never>[] = [],\n>({\n baseUrl,\n flowProvider,\n plugins,\n eventEmitter,\n dataStore,\n bufferedDataStore,\n kvStore,\n withTracing = false,\n authMiddleware,\n authCacheConfig,\n metricsLayer,\n}: InternalExpressUploadistaAdapterOptions<\n TRequirements,\n TPlugins\n>): Promise<ExpressUploadistaAdapter> => {\n // Create and cache the Effect server instance\n const uploadistaServer = await Effect.runPromise(\n createExpressUploadistaServer<TRequirements>({\n baseUrl,\n flowProvider,\n eventEmitter,\n dataStore,\n bufferedDataStore,\n kvStore,\n authMiddleware,\n authCacheConfig,\n metricsLayer,\n }),\n );\n\n // Merge all plugin layers so we can provide them when running handlers\n const pluginLayers = Layer.mergeAll(\n uploadistaServer.uploadServer,\n ...(plugins ?? []),\n ) as Layer.Layer<UploadServer | TRequirements, never, never>;\n\n return {\n baseUrl,\n handler: (req: Request, res: Response, next) => {\n runProgram(\n uploadistaServer.handler(req, res).pipe(Effect.provide(pluginLayers)),\n withTracing,\n ).catch((error) => {\n console.error(\"Express adapter error:\", error);\n if (next) next(error);\n });\n },\n websocketHandler: (req: IncomingMessage, connection: WebSocketConnection) =>\n uploadistaServer.websocketHandler(req, connection),\n websocketConnectionHandler: (ws: WebSocket, req: IncomingMessage) => {\n // Filter to only handle uploadista WebSocket paths\n if (!req.url?.startsWith(`/${baseUrl}/ws/`)) {\n ws.close(1008, \"Invalid WebSocket path\");\n return;\n }\n\n console.log(`📡 WebSocket connected: ${req.url}`);\n\n const connection: WebSocketConnection = {\n id: `conn_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`,\n send: (data: string) => {\n if (ws.readyState === ws.OPEN) {\n ws.send(data);\n }\n },\n close: (code?: number, reason?: string) => ws.close(code, reason),\n readyState: ws.readyState,\n };\n\n // Initialize WebSocket handler with Uploadista and get event handlers\n const handlers = uploadistaServer.websocketHandler(req, connection);\n\n // Attach event handlers\n ws.on(\"message\", (message: Buffer) => {\n handlers.onMessage(message.toString());\n });\n\n ws.on(\"close\", () => {\n handlers.onClose();\n });\n\n ws.on(\"error\", (error: Error) => {\n handlers.onError(error);\n });\n },\n } satisfies ExpressUploadistaAdapter;\n};\n\n/**\n * Creates a Promise-based Uploadista Express adapter for compatibility\n *\n * Note: Ensure that the plugins array provides all services required by your flows.\n * Missing plugin services will result in runtime errors during flow execution.\n */\nexport const createExpressUploadistaAdapter = async <\n TFlows extends (\n flowId: string,\n clientId: string | null,\n ) => Effect.Effect<\n Flow<z.ZodSchema<unknown>, z.ZodSchema<unknown>, unknown>,\n UploadistaError,\n unknown\n // biome-ignore lint/suspicious/noExplicitAny: Generic type constraint allows any flow function type\n > = any,\n // biome-ignore lint/suspicious/noExplicitAny: Permissive constraint allows plugin tuples, validation done at runtime\n TPlugins extends readonly Layer.Layer<any, never, never>[] = Layer.Layer<\n any,\n never,\n never\n >[],\n>({\n baseUrl = \"uploadista\",\n flows,\n // Default to an empty plugin list while preserving the generic type\n plugins = [] as unknown as TPlugins,\n eventEmitter,\n eventBroadcaster = memoryEventBroadcaster,\n dataStore,\n bufferedDataStore,\n kvStore,\n generateId = GenerateIdLive,\n authMiddleware,\n authCacheConfig,\n metricsLayer,\n}: ExpressUploadistaAdapterOptions<\n TFlows,\n TPlugins\n>): Promise<ExpressUploadistaAdapter> => {\n type FlowReq = FlowRequirementsOf<TFlows>;\n // Create a simplified flow provider that uses the flows function directly\n const createFlowProvider = Effect.succeed({\n getFlow: (flowId: string, clientId: string | null) => {\n // The flows function returns an Effect with TRequirements context,\n // but the FlowProvider interface expects no context.\n // We cast this to match the interface - the requirements will be provided\n // at the layer level when the flow adapter is created.\n return flows(flowId, clientId) as Effect.Effect<\n Flow<z.ZodSchema<unknown>, z.ZodSchema<unknown>, FlowReq>,\n UploadistaError\n >;\n },\n });\n\n // Create the flow provider layer that provides the requirements\n const flowProvider = Layer.effect(FlowProvider, createFlowProvider);\n\n // Default eventEmitter to webSocketEventEmitter with the provided eventBroadcaster\n const finalEventEmitter =\n eventEmitter ?? webSocketEventEmitter(eventBroadcaster);\n\n // Convert DataStoreConfig to Layer\n const dataStoreLayer = await createDataStoreLayer(dataStore);\n\n return createInternalExpressUploadistaAdapter<FlowReq, TPlugins>({\n baseUrl,\n flowProvider,\n plugins,\n eventEmitter: finalEventEmitter,\n dataStore: dataStoreLayer,\n bufferedDataStore,\n kvStore,\n generateId,\n authMiddleware,\n authCacheConfig,\n metricsLayer,\n });\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@uploadista/adapters-express",
3
3
  "type": "module",
4
- "version": "0.0.3",
4
+ "version": "0.0.4",
5
5
  "description": "Express adapter for Uploadista",
6
6
  "license": "MIT",
7
7
  "author": "Uploadista",
@@ -15,23 +15,24 @@
15
15
  "dependencies": {
16
16
  "effect": "3.18.4",
17
17
  "zod": "4.1.12",
18
- "@uploadista/core": "0.0.3",
19
- "@uploadista/observability": "0.0.3",
20
- "@uploadista/server": "0.0.3",
21
- "@uploadista/event-broadcaster-memory": "0.0.3",
22
- "@uploadista/event-emitter-websocket": "0.0.3"
18
+ "@uploadista/core": "0.0.4",
19
+ "@uploadista/observability": "0.0.4",
20
+ "@uploadista/server": "0.0.4",
21
+ "@uploadista/event-emitter-websocket": "0.0.4",
22
+ "@uploadista/event-broadcaster-memory": "0.0.4"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@types/express": "^5.0.0",
26
26
  "@types/node": "24.8.1",
27
+ "tsdown": "0.15.9",
27
28
  "typescript": "5.9.3",
28
- "@uploadista/typescript-config": "0.0.3"
29
+ "@uploadista/typescript-config": "0.0.4"
29
30
  },
30
31
  "peerDependencies": {
31
32
  "express": "^4.0.0 || ^5.0.0"
32
33
  },
33
34
  "scripts": {
34
- "build": "tsc -b",
35
+ "build": "tsdown",
35
36
  "format": "biome format --write ./src",
36
37
  "lint": "biome lint --write ./src",
37
38
  "check": "biome check --write ./src",
@@ -0,0 +1,11 @@
1
+ import { defineConfig } from "tsdown";
2
+
3
+ export default defineConfig({
4
+ entry: {
5
+ index: "src/index.ts",
6
+ },
7
+ minify: true,
8
+ format: ["esm", "cjs"],
9
+ dts: true,
10
+ outDir: "dist",
11
+ });
@@ -1,22 +0,0 @@
1
- import type { IncomingMessage } from "node:http";
2
- import type { UploadistaError } from "@uploadista/core/errors";
3
- import type { InputFile, UploadFile } from "@uploadista/core/types";
4
- import { type Effect, Context as EffectContext } from "effect";
5
- import type { Request, Response } from "express";
6
- export interface WebSocketConnection {
7
- id: string;
8
- send: (data: string) => void;
9
- close: (code?: number, reason?: string) => void;
10
- readyState: number;
11
- }
12
- export type ExpressWebSocketHandler = (req: IncomingMessage, connection: WebSocketConnection) => void;
13
- export type ExpressAdapterServiceShape = {
14
- handler: (req: Request, res: Response) => Effect.Effect<void>;
15
- upload: (file: InputFile, stream: ReadableStream) => Effect.Effect<UploadFile, UploadistaError>;
16
- websocketHandler: ExpressWebSocketHandler;
17
- };
18
- declare const ExpressAdapterService_base: EffectContext.TagClass<ExpressAdapterService, "ExpressAdapterService", ExpressAdapterServiceShape>;
19
- export declare class ExpressAdapterService extends ExpressAdapterService_base {
20
- }
21
- export {};
22
- //# sourceMappingURL=adapter-layer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"adapter-layer.d.ts","sourceRoot":"","sources":["../src/adapter-layer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,KAAK,MAAM,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC/D,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEjD,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,uBAAuB,GAAG,CACpC,GAAG,EAAE,eAAe,EACpB,UAAU,EAAE,mBAAmB,KAC5B,IAAI,CAAC;AAEV,MAAM,MAAM,0BAA0B,GAAG;IACvC,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC9D,MAAM,EAAE,CACN,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,cAAc,KACnB,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;IAChD,gBAAgB,EAAE,uBAAuB,CAAC;CAC3C,CAAC;;AAEF,qBAAa,qBAAsB,SAAQ,0BAEW;CAAG"}
@@ -1,3 +0,0 @@
1
- import { Context as EffectContext } from "effect";
2
- export class ExpressAdapterService extends EffectContext.Tag("ExpressAdapterService")() {
3
- }