@uploadista/server 0.0.3

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 (91) hide show
  1. package/.turbo/turbo-build.log +5 -0
  2. package/.turbo/turbo-check.log +34 -0
  3. package/LICENSE +21 -0
  4. package/README.md +503 -0
  5. package/dist/auth/cache.d.ts +87 -0
  6. package/dist/auth/cache.d.ts.map +1 -0
  7. package/dist/auth/cache.js +121 -0
  8. package/dist/auth/cache.test.d.ts +2 -0
  9. package/dist/auth/cache.test.d.ts.map +1 -0
  10. package/dist/auth/cache.test.js +209 -0
  11. package/dist/auth/get-auth-credentials.d.ts +73 -0
  12. package/dist/auth/get-auth-credentials.d.ts.map +1 -0
  13. package/dist/auth/get-auth-credentials.js +55 -0
  14. package/dist/auth/index.d.ts +2 -0
  15. package/dist/auth/index.d.ts.map +1 -0
  16. package/dist/auth/index.js +1 -0
  17. package/dist/auth/jwt/index.d.ts +38 -0
  18. package/dist/auth/jwt/index.d.ts.map +1 -0
  19. package/dist/auth/jwt/index.js +36 -0
  20. package/dist/auth/jwt/types.d.ts +77 -0
  21. package/dist/auth/jwt/types.d.ts.map +1 -0
  22. package/dist/auth/jwt/types.js +1 -0
  23. package/dist/auth/jwt/validate.d.ts +58 -0
  24. package/dist/auth/jwt/validate.d.ts.map +1 -0
  25. package/dist/auth/jwt/validate.js +226 -0
  26. package/dist/auth/jwt/validate.test.d.ts +2 -0
  27. package/dist/auth/jwt/validate.test.d.ts.map +1 -0
  28. package/dist/auth/jwt/validate.test.js +492 -0
  29. package/dist/auth/service.d.ts +63 -0
  30. package/dist/auth/service.d.ts.map +1 -0
  31. package/dist/auth/service.js +43 -0
  32. package/dist/auth/service.test.d.ts +2 -0
  33. package/dist/auth/service.test.d.ts.map +1 -0
  34. package/dist/auth/service.test.js +195 -0
  35. package/dist/auth/types.d.ts +38 -0
  36. package/dist/auth/types.d.ts.map +1 -0
  37. package/dist/auth/types.js +1 -0
  38. package/dist/cache.d.ts +87 -0
  39. package/dist/cache.d.ts.map +1 -0
  40. package/dist/cache.js +121 -0
  41. package/dist/cache.test.d.ts +2 -0
  42. package/dist/cache.test.d.ts.map +1 -0
  43. package/dist/cache.test.js +209 -0
  44. package/dist/cloudflare-config.d.ts +72 -0
  45. package/dist/cloudflare-config.d.ts.map +1 -0
  46. package/dist/cloudflare-config.js +67 -0
  47. package/dist/error-types.d.ts +138 -0
  48. package/dist/error-types.d.ts.map +1 -0
  49. package/dist/error-types.js +155 -0
  50. package/dist/hono-adapter.d.ts +48 -0
  51. package/dist/hono-adapter.d.ts.map +1 -0
  52. package/dist/hono-adapter.js +58 -0
  53. package/dist/http-utils.d.ts +148 -0
  54. package/dist/http-utils.d.ts.map +1 -0
  55. package/dist/http-utils.js +233 -0
  56. package/dist/index.d.ts +9 -0
  57. package/dist/index.d.ts.map +1 -0
  58. package/dist/index.js +8 -0
  59. package/dist/layer-utils.d.ts +121 -0
  60. package/dist/layer-utils.d.ts.map +1 -0
  61. package/dist/layer-utils.js +80 -0
  62. package/dist/metrics/service.d.ts +26 -0
  63. package/dist/metrics/service.d.ts.map +1 -0
  64. package/dist/metrics/service.js +20 -0
  65. package/dist/plugins-typing.d.ts +11 -0
  66. package/dist/plugins-typing.d.ts.map +1 -0
  67. package/dist/plugins-typing.js +1 -0
  68. package/dist/service.d.ts +63 -0
  69. package/dist/service.d.ts.map +1 -0
  70. package/dist/service.js +43 -0
  71. package/dist/service.test.d.ts +2 -0
  72. package/dist/service.test.d.ts.map +1 -0
  73. package/dist/service.test.js +195 -0
  74. package/dist/types.d.ts +38 -0
  75. package/dist/types.d.ts.map +1 -0
  76. package/dist/types.js +1 -0
  77. package/package.json +47 -0
  78. package/src/auth/get-auth-credentials.ts +97 -0
  79. package/src/auth/index.ts +1 -0
  80. package/src/cache.test.ts +306 -0
  81. package/src/cache.ts +204 -0
  82. package/src/error-types.ts +172 -0
  83. package/src/http-utils.ts +264 -0
  84. package/src/index.ts +8 -0
  85. package/src/layer-utils.ts +184 -0
  86. package/src/plugins-typing.ts +57 -0
  87. package/src/service.test.ts +275 -0
  88. package/src/service.ts +78 -0
  89. package/src/types.ts +40 -0
  90. package/tsconfig.json +13 -0
  91. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Shared HTTP utilities for server adapters
3
+ *
4
+ * This module provides routing and error handling utilities used across
5
+ * Hono, Express, and Fastify adapters for request parsing and response formatting.
6
+ */
7
+ /**
8
+ * Parses URL segments from a pathname, filtering out empty segments.
9
+ * Useful for extracting route components from request paths.
10
+ *
11
+ * @param pathname - The URL pathname (e.g., "/uploadista/api/upload/abc123")
12
+ * @returns Array of non-empty path segments
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * const segments = parseUrlSegments("/uploadista/api/upload/abc123");
17
+ * // => ["uploadista", "api", "upload", "abc123"]
18
+ * ```
19
+ */
20
+ export declare const parseUrlSegments: (pathname: string) => string[];
21
+ /**
22
+ * Extracts the last segment from a URL pathname.
23
+ *
24
+ * @param pathname - The URL pathname to parse
25
+ * @returns The last non-empty segment, or undefined if none exists
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * const id = getLastSegment("/uploadista/api/upload/abc123");
30
+ * // => "abc123"
31
+ * ```
32
+ */
33
+ export declare const getLastSegment: (pathname: string) => string | undefined;
34
+ /**
35
+ * Checks if a pathname includes a specific base path and API prefix.
36
+ * Used to determine if a request should be handled by the Uploadista adapter.
37
+ *
38
+ * @param pathname - The request pathname
39
+ * @param basePath - The base path configured for the adapter (e.g., "uploadista")
40
+ * @returns true if the path includes `{basePath}/api/`
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * const isUploadistaPath = hasBasePath("/uploadista/api/upload", "uploadista");
45
+ * // => true
46
+ * ```
47
+ */
48
+ export declare const hasBasePath: (pathname: string, basePath: string) => boolean;
49
+ /**
50
+ * Removes the base path prefix and returns clean route segments.
51
+ * Transforms "/uploadista/api/upload/abc123" → ["upload", "abc123"]
52
+ *
53
+ * @param pathname - The full request pathname
54
+ * @param basePath - The base path to remove (e.g., "uploadista")
55
+ * @returns Array of route segments without base path prefix
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * const route = getRouteSegments("/uploadista/api/upload/abc123", "uploadista");
60
+ * // => ["upload", "abc123"]
61
+ * ```
62
+ */
63
+ export declare const getRouteSegments: (pathname: string, basePath: string) => string[];
64
+ /**
65
+ * Standard error handler for flow and job operations.
66
+ * Maps application errors to appropriate HTTP status codes and error formats.
67
+ *
68
+ * Supports errors with `code`, `message`, `status`, and `details` properties.
69
+ * Maps error codes to HTTP status codes (e.g., NOT_FOUND → 404, VALIDATION_ERROR → 400).
70
+ *
71
+ * @param error - The error object to handle (can be any type)
72
+ * @returns Standardized error response with status, code, message, and optional details
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * import { handleFlowError } from "@uploadista/server";
77
+ *
78
+ * const response = handleFlowError({
79
+ * code: "FLOW_JOB_NOT_FOUND",
80
+ * message: "Job not found",
81
+ * });
82
+ * // => { status: 404, code: "FLOW_JOB_NOT_FOUND", message: "Job not found" }
83
+ * ```
84
+ */
85
+ export declare const handleFlowError: (error: unknown) => {
86
+ status: number;
87
+ code: string;
88
+ message: string;
89
+ details?: unknown;
90
+ };
91
+ /**
92
+ * Extracts job ID from URL segments for job status endpoint.
93
+ * Expected URL format: `/uploadista/api/jobs/:jobId/status`
94
+ *
95
+ * @param urlSegments - Parsed URL segments (without base path)
96
+ * @returns The job ID if found, or undefined
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * const jobId = extractJobIdFromStatus(["jobs", "job-123", "status"]);
101
+ * // => "job-123"
102
+ * ```
103
+ */
104
+ export declare const extractJobIdFromStatus: (urlSegments: string[]) => string | undefined;
105
+ /**
106
+ * Extracts job ID and node ID from URL segments for continue flow endpoint.
107
+ * Expected URL format: `/uploadista/api/jobs/:jobId/continue/:nodeId`
108
+ *
109
+ * @param urlSegments - Parsed URL segments (without base path)
110
+ * @returns Object with extracted jobId and nodeId (either can be undefined if not found)
111
+ *
112
+ * @example
113
+ * ```typescript
114
+ * const { jobId, nodeId } = extractJobAndNodeId([
115
+ * "jobs",
116
+ * "job-123",
117
+ * "continue",
118
+ * "node-456",
119
+ * ]);
120
+ * // => { jobId: "job-123", nodeId: "node-456" }
121
+ * ```
122
+ */
123
+ export declare const extractJobAndNodeId: (urlSegments: string[]) => {
124
+ jobId: string | undefined;
125
+ nodeId: string | undefined;
126
+ };
127
+ /**
128
+ * Extracts flow ID and storage ID from URL segments.
129
+ * Expected URL format: `/uploadista/api/flow/:flowId/:storageId`
130
+ *
131
+ * Mutates the input array (removes last 2 elements).
132
+ *
133
+ * @param urlSegments - Parsed URL segments (will be mutated)
134
+ * @returns Object with extracted flowId and storageId
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * const segments = ["flow", "flow-123", "storage-456"];
139
+ * const { flowId, storageId } = extractFlowAndStorageId(segments);
140
+ * // => { flowId: "flow-123", storageId: "storage-456" }
141
+ * // segments is now ["flow"]
142
+ * ```
143
+ */
144
+ export declare const extractFlowAndStorageId: (urlSegments: string[]) => {
145
+ flowId: string | undefined;
146
+ storageId: string | undefined;
147
+ };
148
+ //# sourceMappingURL=http-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-utils.d.ts","sourceRoot":"","sources":["../src/http-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB,GAAI,UAAU,MAAM,KAAG,MAAM,EAEzD,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,cAAc,GAAI,UAAU,MAAM,KAAG,MAAM,GAAG,SAG1D,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,WAAW,GAAI,UAAU,MAAM,EAAE,UAAU,MAAM,KAAG,OAEhE,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,gBAAgB,GAC3B,UAAU,MAAM,EAChB,UAAU,MAAM,KACf,MAAM,EAER,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,eAAe,GAC1B,OAAO,OAAO,KACb;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAwFpE,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,sBAAsB,GACjC,aAAa,MAAM,EAAE,KACpB,MAAM,GAAG,SAEX,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,mBAAmB,GAC9B,aAAa,MAAM,EAAE,KACpB;IAAE,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;CAKzD,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,uBAAuB,GAClC,aAAa,MAAM,EAAE,KACpB;IAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;CAK7D,CAAC"}
@@ -0,0 +1,233 @@
1
+ /**
2
+ * Shared HTTP utilities for server adapters
3
+ *
4
+ * This module provides routing and error handling utilities used across
5
+ * Hono, Express, and Fastify adapters for request parsing and response formatting.
6
+ */
7
+ /**
8
+ * Parses URL segments from a pathname, filtering out empty segments.
9
+ * Useful for extracting route components from request paths.
10
+ *
11
+ * @param pathname - The URL pathname (e.g., "/uploadista/api/upload/abc123")
12
+ * @returns Array of non-empty path segments
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * const segments = parseUrlSegments("/uploadista/api/upload/abc123");
17
+ * // => ["uploadista", "api", "upload", "abc123"]
18
+ * ```
19
+ */
20
+ export const parseUrlSegments = (pathname) => {
21
+ return pathname.split("/").filter(Boolean);
22
+ };
23
+ /**
24
+ * Extracts the last segment from a URL pathname.
25
+ *
26
+ * @param pathname - The URL pathname to parse
27
+ * @returns The last non-empty segment, or undefined if none exists
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * const id = getLastSegment("/uploadista/api/upload/abc123");
32
+ * // => "abc123"
33
+ * ```
34
+ */
35
+ export const getLastSegment = (pathname) => {
36
+ const segments = parseUrlSegments(pathname);
37
+ return segments[segments.length - 1];
38
+ };
39
+ /**
40
+ * Checks if a pathname includes a specific base path and API prefix.
41
+ * Used to determine if a request should be handled by the Uploadista adapter.
42
+ *
43
+ * @param pathname - The request pathname
44
+ * @param basePath - The base path configured for the adapter (e.g., "uploadista")
45
+ * @returns true if the path includes `{basePath}/api/`
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * const isUploadistaPath = hasBasePath("/uploadista/api/upload", "uploadista");
50
+ * // => true
51
+ * ```
52
+ */
53
+ export const hasBasePath = (pathname, basePath) => {
54
+ return pathname.includes(`${basePath}/api/`);
55
+ };
56
+ /**
57
+ * Removes the base path prefix and returns clean route segments.
58
+ * Transforms "/uploadista/api/upload/abc123" → ["upload", "abc123"]
59
+ *
60
+ * @param pathname - The full request pathname
61
+ * @param basePath - The base path to remove (e.g., "uploadista")
62
+ * @returns Array of route segments without base path prefix
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * const route = getRouteSegments("/uploadista/api/upload/abc123", "uploadista");
67
+ * // => ["upload", "abc123"]
68
+ * ```
69
+ */
70
+ export const getRouteSegments = (pathname, basePath) => {
71
+ return pathname.replace(`${basePath}/api/`, "").split("/").filter(Boolean);
72
+ };
73
+ /**
74
+ * Standard error handler for flow and job operations.
75
+ * Maps application errors to appropriate HTTP status codes and error formats.
76
+ *
77
+ * Supports errors with `code`, `message`, `status`, and `details` properties.
78
+ * Maps error codes to HTTP status codes (e.g., NOT_FOUND → 404, VALIDATION_ERROR → 400).
79
+ *
80
+ * @param error - The error object to handle (can be any type)
81
+ * @returns Standardized error response with status, code, message, and optional details
82
+ *
83
+ * @example
84
+ * ```typescript
85
+ * import { handleFlowError } from "@uploadista/server";
86
+ *
87
+ * const response = handleFlowError({
88
+ * code: "FLOW_JOB_NOT_FOUND",
89
+ * message: "Job not found",
90
+ * });
91
+ * // => { status: 404, code: "FLOW_JOB_NOT_FOUND", message: "Job not found" }
92
+ * ```
93
+ */
94
+ export const handleFlowError = (error) => {
95
+ let status = 500;
96
+ let code = "UNKNOWN_ERROR";
97
+ let message = "Internal server error";
98
+ let details;
99
+ if (typeof error === "object" && error !== null) {
100
+ const errorObj = error;
101
+ // Extract error code
102
+ if ("code" in errorObj && typeof errorObj.code === "string") {
103
+ code = errorObj.code;
104
+ }
105
+ // Extract message
106
+ if ("message" in errorObj && typeof errorObj.message === "string") {
107
+ message = errorObj.message;
108
+ }
109
+ else if ("body" in errorObj && typeof errorObj.body === "string") {
110
+ // Support UploadistaError's body property
111
+ message = errorObj.body;
112
+ }
113
+ // Extract details if present
114
+ if ("details" in errorObj) {
115
+ details = errorObj.details;
116
+ }
117
+ // Map error codes to HTTP status codes
118
+ if ("status" in errorObj && typeof errorObj.status === "number") {
119
+ status = errorObj.status;
120
+ }
121
+ else if ("code" in errorObj) {
122
+ // Fallback: derive status from common error codes
123
+ switch (errorObj.code) {
124
+ case "FILE_NOT_FOUND":
125
+ case "FLOW_JOB_NOT_FOUND":
126
+ case "UPLOAD_ID_NOT_FOUND":
127
+ status = 404;
128
+ break;
129
+ case "FLOW_JOB_ERROR":
130
+ case "VALIDATION_ERROR":
131
+ case "INVALID_METADATA":
132
+ case "INVALID_LENGTH":
133
+ case "ABORTED":
134
+ case "INVALID_TERMINATION":
135
+ status = 400;
136
+ break;
137
+ case "INVALID_OFFSET":
138
+ status = 409;
139
+ break;
140
+ case "ERR_SIZE_EXCEEDED":
141
+ case "ERR_MAX_SIZE_EXCEEDED":
142
+ status = 413;
143
+ break;
144
+ case "FILE_NO_LONGER_EXISTS":
145
+ status = 410;
146
+ break;
147
+ case "MISSING_OFFSET":
148
+ case "INVALID_CONTENT_TYPE":
149
+ status = 403;
150
+ break;
151
+ default:
152
+ status = 500;
153
+ }
154
+ }
155
+ // Special handling for specific error messages
156
+ if ("message" in errorObj && errorObj.message === "Invalid JSON body") {
157
+ status = 400;
158
+ code = "VALIDATION_ERROR";
159
+ }
160
+ }
161
+ const result = {
162
+ status,
163
+ code,
164
+ message,
165
+ };
166
+ if (details !== undefined) {
167
+ result.details = details;
168
+ }
169
+ return result;
170
+ };
171
+ /**
172
+ * Extracts job ID from URL segments for job status endpoint.
173
+ * Expected URL format: `/uploadista/api/jobs/:jobId/status`
174
+ *
175
+ * @param urlSegments - Parsed URL segments (without base path)
176
+ * @returns The job ID if found, or undefined
177
+ *
178
+ * @example
179
+ * ```typescript
180
+ * const jobId = extractJobIdFromStatus(["jobs", "job-123", "status"]);
181
+ * // => "job-123"
182
+ * ```
183
+ */
184
+ export const extractJobIdFromStatus = (urlSegments) => {
185
+ return urlSegments[urlSegments.length - 2];
186
+ };
187
+ /**
188
+ * Extracts job ID and node ID from URL segments for continue flow endpoint.
189
+ * Expected URL format: `/uploadista/api/jobs/:jobId/continue/:nodeId`
190
+ *
191
+ * @param urlSegments - Parsed URL segments (without base path)
192
+ * @returns Object with extracted jobId and nodeId (either can be undefined if not found)
193
+ *
194
+ * @example
195
+ * ```typescript
196
+ * const { jobId, nodeId } = extractJobAndNodeId([
197
+ * "jobs",
198
+ * "job-123",
199
+ * "continue",
200
+ * "node-456",
201
+ * ]);
202
+ * // => { jobId: "job-123", nodeId: "node-456" }
203
+ * ```
204
+ */
205
+ export const extractJobAndNodeId = (urlSegments) => {
206
+ return {
207
+ jobId: urlSegments[urlSegments.length - 3],
208
+ nodeId: urlSegments[urlSegments.length - 1],
209
+ };
210
+ };
211
+ /**
212
+ * Extracts flow ID and storage ID from URL segments.
213
+ * Expected URL format: `/uploadista/api/flow/:flowId/:storageId`
214
+ *
215
+ * Mutates the input array (removes last 2 elements).
216
+ *
217
+ * @param urlSegments - Parsed URL segments (will be mutated)
218
+ * @returns Object with extracted flowId and storageId
219
+ *
220
+ * @example
221
+ * ```typescript
222
+ * const segments = ["flow", "flow-123", "storage-456"];
223
+ * const { flowId, storageId } = extractFlowAndStorageId(segments);
224
+ * // => { flowId: "flow-123", storageId: "storage-456" }
225
+ * // segments is now ["flow"]
226
+ * ```
227
+ */
228
+ export const extractFlowAndStorageId = (urlSegments) => {
229
+ return {
230
+ storageId: urlSegments.pop(),
231
+ flowId: urlSegments.pop(),
232
+ };
233
+ };
@@ -0,0 +1,9 @@
1
+ export * from "./auth";
2
+ export * from "./cache";
3
+ export * from "./error-types";
4
+ export * from "./http-utils";
5
+ export * from "./layer-utils";
6
+ export * from "./plugins-typing";
7
+ export * from "./service";
8
+ export * from "./types";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ export * from "./auth";
2
+ export * from "./cache";
3
+ export * from "./error-types";
4
+ export * from "./http-utils";
5
+ export * from "./layer-utils";
6
+ export * from "./plugins-typing";
7
+ export * from "./service";
8
+ export * from "./types";
@@ -0,0 +1,121 @@
1
+ import type { FlowProvider } from "@uploadista/core/flow";
2
+ import { type BaseEventEmitterService, type BaseKvStoreService, type UploadFileDataStore, type UploadFileDataStores, type UploadFileKVStore } from "@uploadista/core/types";
3
+ import { type UploadServer } from "@uploadista/core/upload";
4
+ import type { GenerateId } from "@uploadista/core/utils";
5
+ import { Layer } from "effect";
6
+ /**
7
+ * Configuration for creating upload server layers.
8
+ * Specifies all dependencies needed by the upload server Effect Layer.
9
+ *
10
+ * @property kvStore - Key-value store for upload metadata
11
+ * @property eventEmitter - Event emitter for upload progress events
12
+ * @property dataStore - File data storage implementation
13
+ * @property bufferedDataStore - Optional buffered storage for performance optimization
14
+ * @property generateId - Optional custom ID generator (uses default if omitted)
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * import { createUploadServerLayer } from "@uploadista/server";
19
+ *
20
+ * const uploadLayerConfig: UploadServerLayerConfig = {
21
+ * kvStore: redisKvStore,
22
+ * eventEmitter: webSocketEventEmitter,
23
+ * dataStore: s3DataStore,
24
+ * };
25
+ * ```
26
+ */
27
+ export interface UploadServerLayerConfig {
28
+ kvStore: Layer.Layer<BaseKvStoreService>;
29
+ eventEmitter: Layer.Layer<BaseEventEmitterService>;
30
+ dataStore: Layer.Layer<UploadFileDataStores, never, UploadFileKVStore>;
31
+ bufferedDataStore?: Layer.Layer<UploadFileDataStore, never, UploadFileKVStore>;
32
+ generateId?: Layer.Layer<GenerateId>;
33
+ }
34
+ /**
35
+ * Configuration for creating flow server layers.
36
+ * Specifies all dependencies needed by the flow processing server.
37
+ *
38
+ * @property kvStore - Key-value store for flow job metadata
39
+ * @property eventEmitter - Event emitter for flow progress events
40
+ * @property flowProvider - Factory function for creating flows
41
+ * @property uploadServer - Upload server layer (used by flows for uploads)
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * import { createFlowServerLayer } from "@uploadista/server";
46
+ *
47
+ * const flowLayerConfig: FlowServerLayerConfig = {
48
+ * kvStore: redisKvStore,
49
+ * eventEmitter: webSocketEventEmitter,
50
+ * flowProvider: createFlowsEffect,
51
+ * uploadServer: uploadServerLayer,
52
+ * };
53
+ * ```
54
+ */
55
+ export interface FlowServerLayerConfig {
56
+ kvStore: Layer.Layer<BaseKvStoreService>;
57
+ eventEmitter: Layer.Layer<BaseEventEmitterService>;
58
+ flowProvider: Layer.Layer<FlowProvider>;
59
+ uploadServer: Layer.Layer<UploadServer>;
60
+ }
61
+ /**
62
+ * Creates the upload server layer with all dependencies composed.
63
+ * This layer handles file uploads with chunked transfer, resumption, and metadata tracking.
64
+ *
65
+ * The created layer includes:
66
+ * - Upload KV store (metadata tracking)
67
+ * - Data store (file storage)
68
+ * - Event emitter (progress notifications)
69
+ * - Optional buffered data store (performance optimization)
70
+ * - Optional custom ID generator
71
+ *
72
+ * @param config - Upload server layer configuration
73
+ * @returns Effect Layer providing UploadServer
74
+ *
75
+ * @example
76
+ * ```typescript
77
+ * import { createUploadServerLayer } from "@uploadista/server";
78
+ * import { Layer } from "effect";
79
+ *
80
+ * const uploadServerLayer = createUploadServerLayer({
81
+ * kvStore: redisKvStore,
82
+ * eventEmitter: webSocketEventEmitter,
83
+ * dataStore: s3DataStore,
84
+ * });
85
+ *
86
+ * // Use in application
87
+ * const app = Layer.provide(appLogic, uploadServerLayer);
88
+ * ```
89
+ */
90
+ export declare const createUploadServerLayer: ({ kvStore, eventEmitter, dataStore, bufferedDataStore, generateId, }: UploadServerLayerConfig) => Layer.Layer<UploadServer, never, never>;
91
+ /**
92
+ * Creates the flow server layer with all dependencies composed.
93
+ * This layer handles file processing workflows with multi-stage pipelines.
94
+ *
95
+ * The created layer includes:
96
+ * - Flow job KV store (job metadata and state)
97
+ * - Event emitter (progress notifications)
98
+ * - Flow provider (flow definitions)
99
+ * - Upload server (for uploads within flows)
100
+ *
101
+ * @param config - Flow server layer configuration
102
+ * @returns Effect Layer providing FlowServer
103
+ *
104
+ * @example
105
+ * ```typescript
106
+ * import { createFlowServerLayer } from "@uploadista/server";
107
+ * import { Layer } from "effect";
108
+ *
109
+ * const flowServerLayer = createFlowServerLayer({
110
+ * kvStore: redisKvStore,
111
+ * eventEmitter: webSocketEventEmitter,
112
+ * flowProvider: createFlowsEffect,
113
+ * uploadServer: uploadServerLayer,
114
+ * });
115
+ *
116
+ * // Use in application
117
+ * const app = Layer.provide(appLogic, flowServerLayer);
118
+ * ```
119
+ */
120
+ export declare const createFlowServerLayer: ({ kvStore, eventEmitter, flowProvider, uploadServer, }: FlowServerLayerConfig) => Layer.Layer<import("@uploadista/core").FlowServer, never, never>;
121
+ //# sourceMappingURL=layer-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layer-utils.d.ts","sourceRoot":"","sources":["../src/layer-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,EAGvB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EAGvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,KAAK,YAAY,EAAgB,MAAM,yBAAyB,CAAC;AAC1E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAE/B;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACzC,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;IACnD,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC;IACvE,iBAAiB,CAAC,EAAE,KAAK,CAAC,KAAK,CAC7B,mBAAmB,EACnB,KAAK,EACL,iBAAiB,CAClB,CAAC;IACF,UAAU,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;CACtC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACzC,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;IACnD,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACxC,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;CACzC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,uBAAuB,GAAI,sEAMrC,uBAAuB,4CAqBzB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,qBAAqB,GAAI,wDAKnC,qBAAqB,qEAavB,CAAC"}
@@ -0,0 +1,80 @@
1
+ import { flowServer } from "@uploadista/core/flow";
2
+ import { flowEventEmitter, flowJobKvStore, uploadEventEmitter, uploadFileKvStore, } from "@uploadista/core/types";
3
+ import { uploadServer } from "@uploadista/core/upload";
4
+ import { Layer } from "effect";
5
+ /**
6
+ * Creates the upload server layer with all dependencies composed.
7
+ * This layer handles file uploads with chunked transfer, resumption, and metadata tracking.
8
+ *
9
+ * The created layer includes:
10
+ * - Upload KV store (metadata tracking)
11
+ * - Data store (file storage)
12
+ * - Event emitter (progress notifications)
13
+ * - Optional buffered data store (performance optimization)
14
+ * - Optional custom ID generator
15
+ *
16
+ * @param config - Upload server layer configuration
17
+ * @returns Effect Layer providing UploadServer
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * import { createUploadServerLayer } from "@uploadista/server";
22
+ * import { Layer } from "effect";
23
+ *
24
+ * const uploadServerLayer = createUploadServerLayer({
25
+ * kvStore: redisKvStore,
26
+ * eventEmitter: webSocketEventEmitter,
27
+ * dataStore: s3DataStore,
28
+ * });
29
+ *
30
+ * // Use in application
31
+ * const app = Layer.provide(appLogic, uploadServerLayer);
32
+ * ```
33
+ */
34
+ export const createUploadServerLayer = ({ kvStore, eventEmitter, dataStore, bufferedDataStore, generateId, }) => {
35
+ // Set up upload server dependencies
36
+ const uploadFileKVStoreLayer = Layer.provide(uploadFileKvStore, kvStore);
37
+ const uploadDataStoreLayer = Layer.provide(dataStore, uploadFileKVStoreLayer);
38
+ const uploadBufferedDataStoreLayer = bufferedDataStore
39
+ ? Layer.provide(bufferedDataStore, uploadFileKVStoreLayer)
40
+ : Layer.empty;
41
+ const uploadEventEmitterLayer = Layer.provide(uploadEventEmitter, eventEmitter);
42
+ const uploadServerLayers = Layer.mergeAll(uploadDataStoreLayer, uploadFileKVStoreLayer, uploadEventEmitterLayer, ...(generateId ? [generateId] : []), uploadBufferedDataStoreLayer);
43
+ return Layer.provide(uploadServer, uploadServerLayers);
44
+ };
45
+ /**
46
+ * Creates the flow server layer with all dependencies composed.
47
+ * This layer handles file processing workflows with multi-stage pipelines.
48
+ *
49
+ * The created layer includes:
50
+ * - Flow job KV store (job metadata and state)
51
+ * - Event emitter (progress notifications)
52
+ * - Flow provider (flow definitions)
53
+ * - Upload server (for uploads within flows)
54
+ *
55
+ * @param config - Flow server layer configuration
56
+ * @returns Effect Layer providing FlowServer
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * import { createFlowServerLayer } from "@uploadista/server";
61
+ * import { Layer } from "effect";
62
+ *
63
+ * const flowServerLayer = createFlowServerLayer({
64
+ * kvStore: redisKvStore,
65
+ * eventEmitter: webSocketEventEmitter,
66
+ * flowProvider: createFlowsEffect,
67
+ * uploadServer: uploadServerLayer,
68
+ * });
69
+ *
70
+ * // Use in application
71
+ * const app = Layer.provide(appLogic, flowServerLayer);
72
+ * ```
73
+ */
74
+ export const createFlowServerLayer = ({ kvStore, eventEmitter, flowProvider, uploadServer, }) => {
75
+ // Set up flow server dependencies
76
+ const flowJobKVStoreLayer = Layer.provide(flowJobKvStore, kvStore);
77
+ const flowEventEmitterLayer = Layer.provide(flowEventEmitter, eventEmitter);
78
+ const flowServerLayers = Layer.mergeAll(flowProvider, flowEventEmitterLayer, flowJobKVStoreLayer, uploadServer);
79
+ return Layer.provide(flowServer, flowServerLayers);
80
+ };
@@ -0,0 +1,26 @@
1
+ import type { Database } from "@uploadista/orm";
2
+ import { Context, Effect, Layer } from "effect";
3
+ declare const MetricsService_base: Context.TagClass<MetricsService, "MetricsService", {
4
+ /**
5
+ * Record upload metrics for an organization
6
+ */
7
+ readonly recordUpload: (organizationId: string, bytes: number) => Effect.Effect<void, never>;
8
+ }>;
9
+ /**
10
+ * Metrics Recording Service
11
+ *
12
+ * Provides access to metrics recording functionality throughout
13
+ * the upload and flow processing pipeline. The service is provided
14
+ * via Effect Layer and can be accessed using Effect.service().
15
+ */
16
+ export declare class MetricsService extends MetricsService_base {
17
+ }
18
+ /**
19
+ * Creates a MetricsService Layer from a Database.
20
+ *
21
+ * @param db - The database instance
22
+ * @returns Effect Layer providing MetricsService
23
+ */
24
+ export declare const MetricsServiceLive: (db: Database) => Layer.Layer<MetricsService>;
25
+ export {};
26
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/metrics/service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;;IAY5C;;OAEG;2BACoB,CACrB,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE,MAAM,KACV,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC;;AAhBnC;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,mBAWjC;CAAG;AAEN;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,IAAI,QAAQ,KAAG,KAAK,CAAC,KAAK,CAAC,cAAc,CAMxE,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { recordUploadMetrics } from "@uploadista/server-metrics";
2
+ import { Context, Effect, Layer } from "effect";
3
+ /**
4
+ * Metrics Recording Service
5
+ *
6
+ * Provides access to metrics recording functionality throughout
7
+ * the upload and flow processing pipeline. The service is provided
8
+ * via Effect Layer and can be accessed using Effect.service().
9
+ */
10
+ export class MetricsService extends Context.Tag("MetricsService")() {
11
+ }
12
+ /**
13
+ * Creates a MetricsService Layer from a Database.
14
+ *
15
+ * @param db - The database instance
16
+ * @returns Effect Layer providing MetricsService
17
+ */
18
+ export const MetricsServiceLive = (db) => Layer.succeed(MetricsService, {
19
+ recordUpload: (organizationId, bytes) => recordUploadMetrics(db, organizationId, bytes).pipe(Effect.catchAll(() => Effect.void)),
20
+ });
@@ -0,0 +1,11 @@
1
+ import type { Flow, UploadServer } from "@uploadista/core";
2
+ import type { Effect, Layer } from "effect";
3
+ import type z from "zod";
4
+ export type LayerSuccessUnion<Layers extends readonly Layer.Layer<any, never, never>[]> = Layers[number] extends Layer.Layer<infer Success, never, never> ? Success : never;
5
+ export type FlowSuccess<TFlows extends (flowId: string, clientId: string | null) => Effect.Effect<unknown, unknown, unknown>> = ReturnType<TFlows> extends Effect.Effect<infer Success, unknown, unknown> ? Success : never;
6
+ export type FlowRequirementsOf<TFlows extends (flowId: string, clientId: string | null) => Effect.Effect<unknown, unknown, unknown>> = FlowSuccess<TFlows> extends Flow<z.ZodSchema<unknown>, z.ZodSchema<unknown>, infer R> ? Exclude<R, UploadServer> : never;
7
+ export type RequiredPluginsOf<TFlows extends (flowId: string, clientId: string | null) => Effect.Effect<unknown, unknown, unknown>> = Exclude<FlowRequirementsOf<TFlows>, UploadServer>;
8
+ export type PluginAssertion<TFlows extends (flowId: string, clientId: string | null) => Effect.Effect<unknown, unknown, unknown>, TPlugins extends readonly Layer.Layer<any, never, never>[]> = Exclude<RequiredPluginsOf<TFlows>, LayerSuccessUnion<TPlugins>> extends never ? unknown : {
9
+ __missingPlugins: Exclude<RequiredPluginsOf<TFlows>, LayerSuccessUnion<TPlugins>>;
10
+ };
11
+ //# sourceMappingURL=plugins-typing.d.ts.map