@uploadista/flow-images-nodes 0.0.20 → 0.1.0-beta.5
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.
- package/dist/index.d.cts +46 -46
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +6 -6
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -9
- package/src/describe-image-node.ts +4 -1
- package/src/transform-image-node.ts +6 -7
- package/tests/image-nodes.test.ts +4 -4
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _uploadista_core23 from "@uploadista/core";
|
|
2
2
|
import { UploadistaError } from "@uploadista/core";
|
|
3
|
-
import * as
|
|
4
|
-
import * as
|
|
3
|
+
import * as zod_v4_core3 from "zod/v4/core";
|
|
4
|
+
import * as zod3 from "zod";
|
|
5
5
|
import { UploadistaError as UploadistaError$1 } from "@uploadista/core/errors";
|
|
6
6
|
import { FileNamingConfig, ImageAiPlugin, ImagePlugin, NodeType, OptimizeParams, ResizeParams, StreamingConfig, TransformImageParams, TransformMode } from "@uploadista/core/flow";
|
|
7
7
|
import { Effect } from "effect";
|
|
@@ -14,8 +14,8 @@ declare function createDescribeImageNode(id: string, {
|
|
|
14
14
|
}?: {
|
|
15
15
|
credentialId?: string;
|
|
16
16
|
keepOutput?: boolean;
|
|
17
|
-
}): Effect.Effect<
|
|
18
|
-
inputSchema:
|
|
17
|
+
}): Effect.Effect<_uploadista_core23.FlowNodeData & {
|
|
18
|
+
inputSchema: zod3.ZodType<{
|
|
19
19
|
id: string;
|
|
20
20
|
offset: number;
|
|
21
21
|
storage: {
|
|
@@ -31,7 +31,7 @@ declare function createDescribeImageNode(id: string, {
|
|
|
31
31
|
}[] | undefined;
|
|
32
32
|
};
|
|
33
33
|
size?: number | undefined;
|
|
34
|
-
metadata?: Record<string,
|
|
34
|
+
metadata?: Record<string, _uploadista_core23.JsonValue> | undefined;
|
|
35
35
|
creationDate?: string | undefined;
|
|
36
36
|
url?: string | undefined;
|
|
37
37
|
sizeIsDeferred?: boolean | undefined;
|
|
@@ -47,7 +47,7 @@ declare function createDescribeImageNode(id: string, {
|
|
|
47
47
|
spanId: string;
|
|
48
48
|
traceFlags: number;
|
|
49
49
|
} | undefined;
|
|
50
|
-
}, unknown,
|
|
50
|
+
}, unknown, zod_v4_core3.$ZodTypeInternals<{
|
|
51
51
|
id: string;
|
|
52
52
|
offset: number;
|
|
53
53
|
storage: {
|
|
@@ -63,7 +63,7 @@ declare function createDescribeImageNode(id: string, {
|
|
|
63
63
|
}[] | undefined;
|
|
64
64
|
};
|
|
65
65
|
size?: number | undefined;
|
|
66
|
-
metadata?: Record<string,
|
|
66
|
+
metadata?: Record<string, _uploadista_core23.JsonValue> | undefined;
|
|
67
67
|
creationDate?: string | undefined;
|
|
68
68
|
url?: string | undefined;
|
|
69
69
|
sizeIsDeferred?: boolean | undefined;
|
|
@@ -80,11 +80,11 @@ declare function createDescribeImageNode(id: string, {
|
|
|
80
80
|
traceFlags: number;
|
|
81
81
|
} | undefined;
|
|
82
82
|
}, unknown>>;
|
|
83
|
-
outputSchema:
|
|
83
|
+
outputSchema: zod3.ZodType<{
|
|
84
84
|
description: string;
|
|
85
85
|
confidence?: number | undefined;
|
|
86
86
|
metadata?: Record<string, unknown> | undefined;
|
|
87
|
-
}, unknown,
|
|
87
|
+
}, unknown, zod_v4_core3.$ZodTypeInternals<{
|
|
88
88
|
description: string;
|
|
89
89
|
confidence?: number | undefined;
|
|
90
90
|
metadata?: Record<string, unknown> | undefined;
|
|
@@ -106,7 +106,7 @@ declare function createDescribeImageNode(id: string, {
|
|
|
106
106
|
}[] | undefined;
|
|
107
107
|
};
|
|
108
108
|
size?: number | undefined;
|
|
109
|
-
metadata?: Record<string,
|
|
109
|
+
metadata?: Record<string, _uploadista_core23.JsonValue> | undefined;
|
|
110
110
|
creationDate?: string | undefined;
|
|
111
111
|
url?: string | undefined;
|
|
112
112
|
sizeIsDeferred?: boolean | undefined;
|
|
@@ -128,7 +128,7 @@ declare function createDescribeImageNode(id: string, {
|
|
|
128
128
|
flowId: string;
|
|
129
129
|
inputs?: Record<string, unknown>;
|
|
130
130
|
clientId: string | null;
|
|
131
|
-
}) => Effect.Effect<
|
|
131
|
+
}) => Effect.Effect<_uploadista_core23.NodeExecutionResult<{
|
|
132
132
|
description: string;
|
|
133
133
|
confidence?: number | undefined;
|
|
134
134
|
metadata?: Record<string, unknown> | undefined;
|
|
@@ -146,7 +146,7 @@ declare function createDescribeImageNode(id: string, {
|
|
|
146
146
|
retryDelay?: number;
|
|
147
147
|
exponentialBackoff?: boolean;
|
|
148
148
|
};
|
|
149
|
-
circuitBreaker?:
|
|
149
|
+
circuitBreaker?: _uploadista_core23.FlowCircuitBreakerConfig;
|
|
150
150
|
} & {
|
|
151
151
|
type: NodeType.process;
|
|
152
152
|
}, UploadistaError$1, ImageAiPlugin>;
|
|
@@ -196,17 +196,17 @@ declare function createOptimizeNode(id: string, {
|
|
|
196
196
|
naming?: FileNamingConfig;
|
|
197
197
|
mode?: TransformMode;
|
|
198
198
|
streamingConfig?: StreamingConfig;
|
|
199
|
-
}): Effect.Effect<
|
|
200
|
-
inputSchema:
|
|
201
|
-
outputSchema:
|
|
199
|
+
}): Effect.Effect<_uploadista_core23.FlowNodeData & {
|
|
200
|
+
inputSchema: zod3.ZodType<_uploadista_core23.UploadFile, unknown, zod_v4_core3.$ZodTypeInternals<_uploadista_core23.UploadFile, unknown>>;
|
|
201
|
+
outputSchema: zod3.ZodType<_uploadista_core23.UploadFile, unknown, zod_v4_core3.$ZodTypeInternals<_uploadista_core23.UploadFile, unknown>>;
|
|
202
202
|
run: (args: {
|
|
203
|
-
data:
|
|
203
|
+
data: _uploadista_core23.UploadFile;
|
|
204
204
|
jobId: string;
|
|
205
205
|
storageId: string;
|
|
206
206
|
flowId: string;
|
|
207
207
|
inputs?: Record<string, unknown>;
|
|
208
208
|
clientId: string | null;
|
|
209
|
-
}) => Effect.Effect<
|
|
209
|
+
}) => Effect.Effect<_uploadista_core23.NodeExecutionResult<_uploadista_core23.UploadFile>, UploadistaError, never>;
|
|
210
210
|
condition?: {
|
|
211
211
|
field: string;
|
|
212
212
|
operator: string;
|
|
@@ -220,10 +220,10 @@ declare function createOptimizeNode(id: string, {
|
|
|
220
220
|
retryDelay?: number;
|
|
221
221
|
exponentialBackoff?: boolean;
|
|
222
222
|
};
|
|
223
|
-
circuitBreaker?:
|
|
223
|
+
circuitBreaker?: _uploadista_core23.FlowCircuitBreakerConfig;
|
|
224
224
|
} & {
|
|
225
|
-
type:
|
|
226
|
-
}, UploadistaError, ImagePlugin |
|
|
225
|
+
type: _uploadista_core23.NodeType;
|
|
226
|
+
}, UploadistaError, ImagePlugin | _uploadista_core23.UploadEngine>;
|
|
227
227
|
//#endregion
|
|
228
228
|
//#region src/remove-background-node.d.ts
|
|
229
229
|
/**
|
|
@@ -251,8 +251,8 @@ declare function createRemoveBackgroundNode(id: string, {
|
|
|
251
251
|
credentialId?: string;
|
|
252
252
|
keepOutput?: boolean;
|
|
253
253
|
naming?: FileNamingConfig;
|
|
254
|
-
}): Effect.Effect<
|
|
255
|
-
inputSchema:
|
|
254
|
+
}): Effect.Effect<_uploadista_core23.FlowNodeData & {
|
|
255
|
+
inputSchema: zod3.ZodType<{
|
|
256
256
|
id: string;
|
|
257
257
|
offset: number;
|
|
258
258
|
storage: {
|
|
@@ -268,7 +268,7 @@ declare function createRemoveBackgroundNode(id: string, {
|
|
|
268
268
|
}[] | undefined;
|
|
269
269
|
};
|
|
270
270
|
size?: number | undefined;
|
|
271
|
-
metadata?: Record<string,
|
|
271
|
+
metadata?: Record<string, _uploadista_core23.JsonValue> | undefined;
|
|
272
272
|
creationDate?: string | undefined;
|
|
273
273
|
url?: string | undefined;
|
|
274
274
|
sizeIsDeferred?: boolean | undefined;
|
|
@@ -284,7 +284,7 @@ declare function createRemoveBackgroundNode(id: string, {
|
|
|
284
284
|
spanId: string;
|
|
285
285
|
traceFlags: number;
|
|
286
286
|
} | undefined;
|
|
287
|
-
}, unknown,
|
|
287
|
+
}, unknown, zod_v4_core3.$ZodTypeInternals<{
|
|
288
288
|
id: string;
|
|
289
289
|
offset: number;
|
|
290
290
|
storage: {
|
|
@@ -300,7 +300,7 @@ declare function createRemoveBackgroundNode(id: string, {
|
|
|
300
300
|
}[] | undefined;
|
|
301
301
|
};
|
|
302
302
|
size?: number | undefined;
|
|
303
|
-
metadata?: Record<string,
|
|
303
|
+
metadata?: Record<string, _uploadista_core23.JsonValue> | undefined;
|
|
304
304
|
creationDate?: string | undefined;
|
|
305
305
|
url?: string | undefined;
|
|
306
306
|
sizeIsDeferred?: boolean | undefined;
|
|
@@ -317,7 +317,7 @@ declare function createRemoveBackgroundNode(id: string, {
|
|
|
317
317
|
traceFlags: number;
|
|
318
318
|
} | undefined;
|
|
319
319
|
}, unknown>>;
|
|
320
|
-
outputSchema:
|
|
320
|
+
outputSchema: zod3.ZodType<_uploadista_core23.UploadFile, unknown, zod_v4_core3.$ZodTypeInternals<_uploadista_core23.UploadFile, unknown>>;
|
|
321
321
|
run: (args: {
|
|
322
322
|
data: {
|
|
323
323
|
id: string;
|
|
@@ -335,7 +335,7 @@ declare function createRemoveBackgroundNode(id: string, {
|
|
|
335
335
|
}[] | undefined;
|
|
336
336
|
};
|
|
337
337
|
size?: number | undefined;
|
|
338
|
-
metadata?: Record<string,
|
|
338
|
+
metadata?: Record<string, _uploadista_core23.JsonValue> | undefined;
|
|
339
339
|
creationDate?: string | undefined;
|
|
340
340
|
url?: string | undefined;
|
|
341
341
|
sizeIsDeferred?: boolean | undefined;
|
|
@@ -357,7 +357,7 @@ declare function createRemoveBackgroundNode(id: string, {
|
|
|
357
357
|
flowId: string;
|
|
358
358
|
inputs?: Record<string, unknown>;
|
|
359
359
|
clientId: string | null;
|
|
360
|
-
}) => Effect.Effect<
|
|
360
|
+
}) => Effect.Effect<_uploadista_core23.NodeExecutionResult<_uploadista_core23.UploadFile>, UploadistaError$1, never>;
|
|
361
361
|
condition?: {
|
|
362
362
|
field: string;
|
|
363
363
|
operator: string;
|
|
@@ -371,7 +371,7 @@ declare function createRemoveBackgroundNode(id: string, {
|
|
|
371
371
|
retryDelay?: number;
|
|
372
372
|
exponentialBackoff?: boolean;
|
|
373
373
|
};
|
|
374
|
-
circuitBreaker?:
|
|
374
|
+
circuitBreaker?: _uploadista_core23.FlowCircuitBreakerConfig;
|
|
375
375
|
} & {
|
|
376
376
|
type: NodeType.process;
|
|
377
377
|
}, UploadistaError$1, ImageAiPlugin | UploadEngine>;
|
|
@@ -421,17 +421,17 @@ declare function createResizeNode(id: string, {
|
|
|
421
421
|
naming?: FileNamingConfig;
|
|
422
422
|
mode?: TransformMode;
|
|
423
423
|
streamingConfig?: StreamingConfig;
|
|
424
|
-
}): Effect.Effect<
|
|
425
|
-
inputSchema:
|
|
426
|
-
outputSchema:
|
|
424
|
+
}): Effect.Effect<_uploadista_core23.FlowNodeData & {
|
|
425
|
+
inputSchema: zod3.ZodType<_uploadista_core23.UploadFile, unknown, zod_v4_core3.$ZodTypeInternals<_uploadista_core23.UploadFile, unknown>>;
|
|
426
|
+
outputSchema: zod3.ZodType<_uploadista_core23.UploadFile, unknown, zod_v4_core3.$ZodTypeInternals<_uploadista_core23.UploadFile, unknown>>;
|
|
427
427
|
run: (args: {
|
|
428
|
-
data:
|
|
428
|
+
data: _uploadista_core23.UploadFile;
|
|
429
429
|
jobId: string;
|
|
430
430
|
storageId: string;
|
|
431
431
|
flowId: string;
|
|
432
432
|
inputs?: Record<string, unknown>;
|
|
433
433
|
clientId: string | null;
|
|
434
|
-
}) => Effect.Effect<
|
|
434
|
+
}) => Effect.Effect<_uploadista_core23.NodeExecutionResult<_uploadista_core23.UploadFile>, _uploadista_core23.UploadistaError, never>;
|
|
435
435
|
condition?: {
|
|
436
436
|
field: string;
|
|
437
437
|
operator: string;
|
|
@@ -445,10 +445,10 @@ declare function createResizeNode(id: string, {
|
|
|
445
445
|
retryDelay?: number;
|
|
446
446
|
exponentialBackoff?: boolean;
|
|
447
447
|
};
|
|
448
|
-
circuitBreaker?:
|
|
448
|
+
circuitBreaker?: _uploadista_core23.FlowCircuitBreakerConfig;
|
|
449
449
|
} & {
|
|
450
|
-
type:
|
|
451
|
-
},
|
|
450
|
+
type: _uploadista_core23.NodeType;
|
|
451
|
+
}, _uploadista_core23.UploadistaError, ImagePlugin | _uploadista_core23.UploadEngine>;
|
|
452
452
|
//#endregion
|
|
453
453
|
//#region src/transform-image-node.d.ts
|
|
454
454
|
/**
|
|
@@ -520,17 +520,17 @@ declare function createTransformImageNode(id: string, {
|
|
|
520
520
|
naming?: FileNamingConfig;
|
|
521
521
|
mode?: TransformMode;
|
|
522
522
|
streamingConfig?: StreamingConfig;
|
|
523
|
-
}): Effect.Effect<
|
|
524
|
-
inputSchema:
|
|
525
|
-
outputSchema:
|
|
523
|
+
}): Effect.Effect<_uploadista_core23.FlowNodeData & {
|
|
524
|
+
inputSchema: zod3.ZodType<_uploadista_core23.UploadFile, unknown, zod_v4_core3.$ZodTypeInternals<_uploadista_core23.UploadFile, unknown>>;
|
|
525
|
+
outputSchema: zod3.ZodType<_uploadista_core23.UploadFile, unknown, zod_v4_core3.$ZodTypeInternals<_uploadista_core23.UploadFile, unknown>>;
|
|
526
526
|
run: (args: {
|
|
527
|
-
data:
|
|
527
|
+
data: _uploadista_core23.UploadFile;
|
|
528
528
|
jobId: string;
|
|
529
529
|
storageId: string;
|
|
530
530
|
flowId: string;
|
|
531
531
|
inputs?: Record<string, unknown>;
|
|
532
532
|
clientId: string | null;
|
|
533
|
-
}) => Effect.Effect<
|
|
533
|
+
}) => Effect.Effect<_uploadista_core23.NodeExecutionResult<_uploadista_core23.UploadFile>, UploadistaError$1, never>;
|
|
534
534
|
condition?: {
|
|
535
535
|
field: string;
|
|
536
536
|
operator: string;
|
|
@@ -544,10 +544,10 @@ declare function createTransformImageNode(id: string, {
|
|
|
544
544
|
retryDelay?: number;
|
|
545
545
|
exponentialBackoff?: boolean;
|
|
546
546
|
};
|
|
547
|
-
circuitBreaker?:
|
|
547
|
+
circuitBreaker?: _uploadista_core23.FlowCircuitBreakerConfig;
|
|
548
548
|
} & {
|
|
549
|
-
type:
|
|
550
|
-
}, UploadistaError$1, ImagePlugin |
|
|
549
|
+
type: _uploadista_core23.NodeType;
|
|
550
|
+
}, UploadistaError$1, ImagePlugin | _uploadista_core23.UploadEngine>;
|
|
551
551
|
//#endregion
|
|
552
552
|
//#region src/wait-for-url.d.ts
|
|
553
553
|
/**
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/describe-image-node.ts","../src/optimize-node.ts","../src/remove-background-node.ts","../src/resize-node.ts","../src/transform-image-node.ts","../src/wait-for-url.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;iBAcgB,uBAAA;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/describe-image-node.ts","../src/optimize-node.ts","../src/remove-background-node.ts","../src/resize-node.ts","../src/transform-image-node.ts","../src/wait-for-url.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -31,7 +31,7 @@ declare function createDescribeImageNode(id: string, {
|
|
|
31
31
|
}[] | undefined;
|
|
32
32
|
};
|
|
33
33
|
size?: number | undefined;
|
|
34
|
-
metadata?: Record<string,
|
|
34
|
+
metadata?: Record<string, _uploadista_core0.JsonValue> | undefined;
|
|
35
35
|
creationDate?: string | undefined;
|
|
36
36
|
url?: string | undefined;
|
|
37
37
|
sizeIsDeferred?: boolean | undefined;
|
|
@@ -63,7 +63,7 @@ declare function createDescribeImageNode(id: string, {
|
|
|
63
63
|
}[] | undefined;
|
|
64
64
|
};
|
|
65
65
|
size?: number | undefined;
|
|
66
|
-
metadata?: Record<string,
|
|
66
|
+
metadata?: Record<string, _uploadista_core0.JsonValue> | undefined;
|
|
67
67
|
creationDate?: string | undefined;
|
|
68
68
|
url?: string | undefined;
|
|
69
69
|
sizeIsDeferred?: boolean | undefined;
|
|
@@ -106,7 +106,7 @@ declare function createDescribeImageNode(id: string, {
|
|
|
106
106
|
}[] | undefined;
|
|
107
107
|
};
|
|
108
108
|
size?: number | undefined;
|
|
109
|
-
metadata?: Record<string,
|
|
109
|
+
metadata?: Record<string, _uploadista_core0.JsonValue> | undefined;
|
|
110
110
|
creationDate?: string | undefined;
|
|
111
111
|
url?: string | undefined;
|
|
112
112
|
sizeIsDeferred?: boolean | undefined;
|
|
@@ -268,7 +268,7 @@ declare function createRemoveBackgroundNode(id: string, {
|
|
|
268
268
|
}[] | undefined;
|
|
269
269
|
};
|
|
270
270
|
size?: number | undefined;
|
|
271
|
-
metadata?: Record<string,
|
|
271
|
+
metadata?: Record<string, _uploadista_core0.JsonValue> | undefined;
|
|
272
272
|
creationDate?: string | undefined;
|
|
273
273
|
url?: string | undefined;
|
|
274
274
|
sizeIsDeferred?: boolean | undefined;
|
|
@@ -300,7 +300,7 @@ declare function createRemoveBackgroundNode(id: string, {
|
|
|
300
300
|
}[] | undefined;
|
|
301
301
|
};
|
|
302
302
|
size?: number | undefined;
|
|
303
|
-
metadata?: Record<string,
|
|
303
|
+
metadata?: Record<string, _uploadista_core0.JsonValue> | undefined;
|
|
304
304
|
creationDate?: string | undefined;
|
|
305
305
|
url?: string | undefined;
|
|
306
306
|
sizeIsDeferred?: boolean | undefined;
|
|
@@ -335,7 +335,7 @@ declare function createRemoveBackgroundNode(id: string, {
|
|
|
335
335
|
}[] | undefined;
|
|
336
336
|
};
|
|
337
337
|
size?: number | undefined;
|
|
338
|
-
metadata?: Record<string,
|
|
338
|
+
metadata?: Record<string, _uploadista_core0.JsonValue> | undefined;
|
|
339
339
|
creationDate?: string | undefined;
|
|
340
340
|
url?: string | undefined;
|
|
341
341
|
sizeIsDeferred?: boolean | undefined;
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/describe-image-node.ts","../src/optimize-node.ts","../src/remove-background-node.ts","../src/resize-node.ts","../src/transform-image-node.ts","../src/wait-for-url.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;iBAcgB,uBAAA;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/describe-image-node.ts","../src/optimize-node.ts","../src/remove-background-node.ts","../src/resize-node.ts","../src/transform-image-node.ts","../src/wait-for-url.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["formatToMimeType: Record<OptimizeParams[\"format\"], string>","formatToExtension: Record<OptimizeParams[\"format\"], string>","effectiveMode: TransformMode","newFileName: string | undefined","namingConfig: FileNamingConfig","UploadistaError","namingConfig: FileNamingConfig","effectiveMode: TransformMode","namingConfig: FileNamingConfig | undefined","chunks: Uint8Array[]","effectiveMode: TransformMode","namingConfig: FileNamingConfig | undefined"],"sources":["../src/wait-for-url.ts","../src/describe-image-node.ts","../src/optimize-node.ts","../src/remove-background-node.ts","../src/resize-node.ts","../src/transform-image-node.ts"],"sourcesContent":["import { UploadistaError } from \"@uploadista/core/errors\";\nimport { Effect } from \"effect\";\n\n/**\n * Waits for a URL to become available by periodically checking its accessibility.\n * This is useful when a file has just been uploaded and may not be immediately\n * accessible due to CDN propagation or storage consistency delays.\n *\n * @param url - The URL to check for availability\n * @param options - Configuration options\n * @param options.maxWaitTime - Maximum time to wait in milliseconds (default: 10000)\n * @param options.retryDelay - Delay between retries in milliseconds (default: 500)\n * @returns Effect that succeeds when URL is available or fails with UploadistaError\n */\nexport function waitForUrlAvailability(\n url: string,\n options: {\n maxWaitTime?: number;\n retryDelay?: number;\n } = {},\n): Effect.Effect<void, UploadistaError> {\n const { maxWaitTime = 10000, retryDelay = 500 } = options;\n\n return Effect.gen(function* () {\n const startTime = Date.now();\n\n while (Date.now() - startTime < maxWaitTime) {\n const response = yield* Effect.tryPromise(() =>\n fetch(url, { method: \"HEAD\" }),\n ).pipe(Effect.catchAll(() => Effect.succeed(null)));\n\n if (response?.ok) {\n yield* Effect.logInfo(`URL ${url} is now available`);\n return;\n }\n\n if (response) {\n yield* Effect.logDebug(\n `URL not ready yet (${response.status}), retrying...`,\n );\n } else {\n yield* Effect.logDebug(`URL check failed, retrying...`);\n }\n\n yield* Effect.sleep(retryDelay);\n }\n\n return yield* UploadistaError.fromCode(\"FLOW_NODE_ERROR\", {\n cause: `URL ${url} not available after ${maxWaitTime}ms`,\n }).toEffect();\n });\n}\n","import { UploadistaError } from \"@uploadista/core/errors\";\nimport {\n completeNodeExecution,\n createFlowNode,\n IMAGE_DESCRIPTION_OUTPUT_TYPE_ID,\n ImageAiPlugin,\n imageDescriptionOutputSchema,\n NodeType,\n} from \"@uploadista/core/flow\";\nimport { uploadFileSchema } from \"@uploadista/core/types\";\n\nimport { Effect } from \"effect\";\nimport { waitForUrlAvailability } from \"./wait-for-url\";\n\nexport function createDescribeImageNode(\n id: string,\n { credentialId, keepOutput }: { credentialId?: string; keepOutput?: boolean } = {},\n) {\n return Effect.gen(function* () {\n const imageAiService = yield* ImageAiPlugin;\n\n return yield* createFlowNode({\n id,\n name: \"Describe Image\",\n description: \"Describes the image using AI\",\n type: NodeType.process,\n nodeTypeId: \"describe-image\",\n outputTypeId: IMAGE_DESCRIPTION_OUTPUT_TYPE_ID,\n keepOutput,\n inputSchema: uploadFileSchema,\n outputSchema: imageDescriptionOutputSchema,\n // AI service - enable circuit breaker with skip fallback\n circuitBreaker: {\n enabled: true,\n failureThreshold: 5,\n resetTimeout: 60000,\n fallback: { type: \"skip\", passThrough: true },\n },\n run: ({ data: file, flowId, jobId, clientId }) => {\n return Effect.gen(function* () {\n const flow = {\n flowId,\n nodeId: id,\n jobId,\n };\n\n const fileUrl = file.url;\n\n // Validate input\n if (!fileUrl) {\n return yield* UploadistaError.fromCode(\"FLOW_NODE_ERROR\", {\n cause: \"URL is required for describe image operation\",\n }).toEffect();\n }\n\n yield* Effect.logInfo(\n `Describing image for file ${file.id} at URL: ${fileUrl}`,\n );\n\n // Wait for URL to be available with retry mechanism\n yield* waitForUrlAvailability(fileUrl);\n\n // Build context for ImageAI plugin\n const context = {\n clientId,\n credentialId,\n };\n\n // Describe image with error handling\n const result = yield* imageAiService\n .describeImage(fileUrl, context)\n .pipe(\n Effect.catchAll((error) =>\n Effect.gen(function* () {\n yield* Effect.logError(\"Failed to describe image\", error);\n return yield* UploadistaError.fromCode(\"FLOW_NODE_ERROR\", {\n cause:\n error instanceof Error\n ? error.message\n : \"Failed to describe image\",\n }).toEffect();\n }),\n ),\n );\n\n yield* Effect.logInfo(\n `Successfully described image for file ${file.id}`,\n );\n\n // Return structured image description output (not UploadFile)\n return completeNodeExecution({\n description: result.description,\n flow,\n });\n });\n },\n });\n });\n}\n","import { UploadistaError } from \"@uploadista/core\";\nimport {\n applyFileNaming,\n buildNamingContext,\n createTransformNode,\n type FileNamingConfig,\n getBaseName,\n ImagePlugin,\n type OptimizeParams,\n STORAGE_OUTPUT_TYPE_ID,\n type StreamingConfig,\n type TransformMode,\n} from \"@uploadista/core/flow\";\nimport { Effect } from \"effect\";\n\n// Map image format to MIME type\nconst formatToMimeType: Record<OptimizeParams[\"format\"], string> = {\n jpeg: \"image/jpeg\",\n webp: \"image/webp\",\n png: \"image/png\",\n avif: \"image/avif\",\n};\n\n// Map image format to file extension\nconst formatToExtension: Record<OptimizeParams[\"format\"], string> = {\n jpeg: \"jpg\",\n webp: \"webp\",\n png: \"png\",\n avif: \"avif\",\n};\n\n/**\n * Creates an optimize node that optimizes images for web delivery.\n *\n * Supports both buffered and streaming modes for memory-efficient processing\n * of large images. In streaming mode, the image is read and processed\n * incrementally, reducing peak memory usage.\n *\n * @param id - Unique node identifier\n * @param params - Optimize parameters (quality, format)\n * @param options - Optional configuration\n * @param options.keepOutput - Whether to keep output in flow results\n * @param options.naming - File naming configuration (auto suffix: `${format}`)\n * @param options.mode - Transform mode: \"buffered\" (default), \"streaming\", or \"auto\"\n * @param options.streamingConfig - Streaming configuration (file size threshold, chunk size)\n *\n * @example\n * ```typescript\n * // Buffered mode (default) - \"photo.jpg\" -> \"photo-webp.webp\"\n * const optimize = yield* createOptimizeNode(\"opt-1\", { quality: 80, format: \"webp\" }, {\n * naming: { mode: \"auto\" }\n * });\n *\n * // Streaming mode for large files\n * const optimizeStreaming = yield* createOptimizeNode(\"opt-2\", { quality: 80, format: \"webp\" }, {\n * mode: \"streaming\",\n * naming: { mode: \"auto\" }\n * });\n *\n * // Auto mode - uses streaming for files > 1MB\n * const optimizeAuto = yield* createOptimizeNode(\"opt-3\", { quality: 80, format: \"webp\" }, {\n * mode: \"auto\",\n * streamingConfig: { fileSizeThreshold: 1_048_576 },\n * naming: { mode: \"auto\" }\n * });\n * ```\n */\nexport function createOptimizeNode(\n id: string,\n { quality, format }: OptimizeParams,\n options?: {\n keepOutput?: boolean;\n naming?: FileNamingConfig;\n mode?: TransformMode;\n streamingConfig?: StreamingConfig;\n },\n) {\n return Effect.gen(function* () {\n const imageService = yield* ImagePlugin;\n\n // Determine if streaming is available and requested\n const supportsStreaming = imageService.supportsStreaming ?? false;\n const requestedMode = options?.mode ?? \"buffered\";\n\n // If streaming requested but not supported, fall back to buffered\n const effectiveMode: TransformMode =\n requestedMode === \"buffered\"\n ? \"buffered\"\n : supportsStreaming\n ? requestedMode\n : \"buffered\";\n\n // Helper to build output metadata from optimized result\n const buildOutputMetadata = (file: {\n metadata?: Record<string, unknown>;\n flow?: { flowId?: string; jobId?: string };\n }) => {\n const newType = formatToMimeType[format];\n const newExtension = formatToExtension[format];\n\n // Get original fileName\n const fileName = file.metadata?.fileName;\n let newFileName: string | undefined;\n\n if (fileName && typeof fileName === \"string\") {\n // Apply naming if configured\n if (options?.naming) {\n const namingConfig: FileNamingConfig = {\n ...options.naming,\n autoSuffix:\n options.naming.autoSuffix ?? ((ctx) => ctx.format ?? format),\n };\n const namingContext = buildNamingContext(\n file as Parameters<typeof buildNamingContext>[0],\n {\n flowId: file.flow?.flowId ?? \"\",\n jobId: file.flow?.jobId ?? \"\",\n nodeId: id,\n nodeType: \"optimize\",\n },\n { format, quality },\n );\n // Apply naming to get base name with suffix\n const namedFile = applyFileNaming(\n file as Parameters<typeof applyFileNaming>[0],\n namingContext,\n namingConfig,\n );\n // Replace extension with new format extension\n newFileName = `${getBaseName(namedFile)}.${newExtension}`;\n } else {\n // No naming config, just update extension\n newFileName = fileName.replace(/\\.[^.]+$/, `.${newExtension}`);\n }\n }\n\n return { newType, newFileName };\n };\n\n return yield* createTransformNode({\n id,\n name: \"Optimize\",\n description: \"Optimizes an image for web delivery\",\n nodeTypeId: \"optimize-image\",\n outputTypeId: STORAGE_OUTPUT_TYPE_ID,\n keepOutput: options?.keepOutput,\n // Note: naming is handled in transform since format changes extension\n nodeType: \"optimize\",\n namingVars: { format, quality },\n mode: effectiveMode,\n streamingConfig: options?.streamingConfig,\n // Buffered transform (used when mode is \"buffered\" or \"auto\" selects buffered)\n transform: (inputBytes, file) =>\n Effect.map(\n imageService.optimize(inputBytes, { quality, format }),\n (optimizedBytes) => {\n const { newType, newFileName } = buildOutputMetadata(file);\n return {\n bytes: optimizedBytes,\n type: newType,\n fileName: newFileName,\n } as\n | Uint8Array\n | { bytes: Uint8Array; type: string; fileName?: string };\n },\n ),\n // Streaming transform (used when mode is \"streaming\" or \"auto\" selects streaming)\n streamingTransform: imageService.optimizeStream\n ? (inputStream, file) => {\n const optimizeStreamFn = imageService.optimizeStream;\n if (!optimizeStreamFn) {\n throw UploadistaError.fromCode(\"UNKNOWN_ERROR\");\n }\n return Effect.gen(function* () {\n // Use the streaming optimization\n const outputStream = yield* optimizeStreamFn(inputStream, {\n quality,\n format,\n });\n\n const { newType, newFileName } = buildOutputMetadata(file);\n\n return {\n stream: outputStream,\n type: newType,\n fileName: newFileName,\n };\n });\n }\n : undefined,\n });\n });\n}\n","import { UploadistaError } from \"@uploadista/core/errors\";\nimport {\n applyFileNaming,\n buildNamingContext,\n completeNodeExecution,\n createFlowNode,\n type FileNamingConfig,\n ImageAiPlugin,\n NodeType,\n resolveUploadMetadata,\n STORAGE_OUTPUT_TYPE_ID,\n} from \"@uploadista/core/flow\";\nimport { uploadFileSchema } from \"@uploadista/core/types\";\nimport { UploadEngine } from \"@uploadista/core/upload\";\nimport { Effect } from \"effect\";\nimport { waitForUrlAvailability } from \"./wait-for-url\";\n\n/**\n * Creates a remove-background node that removes backgrounds from images using AI.\n *\n * @param id - Unique node identifier\n * @param options - Optional configuration\n * @param options.credentialId - Optional credential ID for AI service\n * @param options.keepOutput - Whether to keep output in flow results\n * @param options.naming - File naming configuration (auto suffix: `nobg`)\n *\n * @example\n * ```typescript\n * // With auto-naming: \"photo.jpg\" -> \"photo-nobg.jpg\"\n * const node = yield* createRemoveBackgroundNode(\"remove-bg-1\", {\n * naming: { mode: \"auto\" }\n * });\n * ```\n */\nexport function createRemoveBackgroundNode(\n id: string,\n {\n credentialId,\n keepOutput,\n naming,\n }: {\n credentialId?: string;\n keepOutput?: boolean;\n naming?: FileNamingConfig;\n } = {},\n) {\n return Effect.gen(function* () {\n const imageAiService = yield* ImageAiPlugin;\n const uploadEngine = yield* UploadEngine;\n\n return yield* createFlowNode({\n id,\n name: \"Remove Background\",\n description: \"Removes the background from an image\",\n type: NodeType.process,\n nodeTypeId: \"remove-background\",\n outputTypeId: STORAGE_OUTPUT_TYPE_ID,\n keepOutput,\n inputSchema: uploadFileSchema,\n outputSchema: uploadFileSchema,\n // AI service - enable circuit breaker with skip fallback\n circuitBreaker: {\n enabled: true,\n failureThreshold: 5,\n resetTimeout: 60000,\n fallback: { type: \"skip\", passThrough: true },\n },\n run: ({ data: file, flowId, jobId, storageId, clientId }) => {\n return Effect.gen(function* () {\n const flow = {\n flowId,\n nodeId: id,\n jobId,\n };\n\n const fileUrl = file.url;\n\n // Validate input\n if (!fileUrl) {\n return yield* UploadistaError.fromCode(\"FLOW_NODE_ERROR\", {\n cause: \"URL is required for remove background operation\",\n }).toEffect();\n }\n\n yield* Effect.logInfo(\n `Removing background for file ${file.id} at URL: ${file.url}`,\n );\n\n // Wait for URL to be available with retry mechanism\n yield* waitForUrlAvailability(fileUrl);\n\n // Build context for ImageAI plugin\n const context = {\n clientId,\n credentialId,\n };\n\n // Remove background with error handling\n const backgroundRemovalResult = yield* imageAiService\n .removeBackground(fileUrl, context)\n .pipe(\n Effect.catchAll((error) =>\n Effect.gen(function* () {\n yield* Effect.logError(\"Failed to remove background\", error);\n return yield* UploadistaError.fromCode(\"FLOW_NODE_ERROR\", {\n cause:\n error instanceof Error\n ? error.message\n : \"Failed to remove background from image\",\n }).toEffect();\n }),\n ),\n );\n\n const { outputUrl } = backgroundRemovalResult;\n const { type, fileName, metadata, metadataJson } =\n resolveUploadMetadata(file.metadata);\n\n // Apply file naming if configured\n let outputFileName = fileName;\n if (naming) {\n const namingConfig: FileNamingConfig = {\n ...naming,\n autoSuffix: naming.autoSuffix ?? (() => \"nobg\"),\n };\n const namingContext = buildNamingContext(file, {\n flowId,\n jobId,\n nodeId: id,\n nodeType: \"remove-background\",\n });\n outputFileName = applyFileNaming(file, namingContext, namingConfig);\n }\n\n yield* Effect.logInfo(`Uploading processed file to storage`);\n\n // Upload the transformed bytes back to the upload server with error handling\n const result = yield* uploadEngine\n .uploadFromUrl(\n {\n storageId,\n size: 0,\n type,\n fileName: outputFileName,\n lastModified: 0,\n metadata: metadataJson,\n flow,\n },\n clientId,\n outputUrl,\n )\n .pipe(\n Effect.catchAll((error) =>\n Effect.gen(function* () {\n yield* Effect.logError(\n \"Failed to upload processed file\",\n error,\n );\n return yield* UploadistaError.fromCode(\"FLOW_NODE_ERROR\", {\n cause:\n error instanceof Error\n ? error.message\n : \"Failed to upload processed file\",\n }).toEffect();\n }),\n ),\n );\n\n yield* Effect.logInfo(\n `Successfully removed background for file ${file.id}`,\n );\n\n // Update metadata with new filename if naming was applied\n const updatedMetadata = metadata\n ? {\n ...metadata,\n ...(outputFileName !== fileName && {\n fileName: outputFileName,\n originalName: outputFileName,\n name: outputFileName,\n extension:\n outputFileName.split(\".\").pop() || metadata.extension,\n }),\n }\n : result.metadata;\n\n return completeNodeExecution(\n updatedMetadata\n ? {\n ...result,\n metadata: updatedMetadata,\n }\n : result,\n );\n });\n },\n });\n });\n}\n","import {\n createTransformNode,\n type FileNamingConfig,\n ImagePlugin,\n type ResizeParams,\n STORAGE_OUTPUT_TYPE_ID,\n type StreamingConfig,\n type TransformMode,\n} from \"@uploadista/core/flow\";\nimport { Effect } from \"effect\";\n\n/**\n * Creates a resize node that resizes images to specified dimensions.\n *\n * Supports both buffered and streaming modes for memory-efficient processing\n * of large images. In streaming mode, the image is read and processed\n * incrementally, reducing peak memory usage.\n *\n * @param id - Unique node identifier\n * @param params - Resize parameters (width, height, fit)\n * @param options - Optional configuration\n * @param options.keepOutput - Whether to keep output in flow results\n * @param options.naming - File naming configuration (auto suffix: `${width}x${height}`)\n * @param options.mode - Transform mode: \"buffered\", \"streaming\", or \"auto\" (default)\n * @param options.streamingConfig - Streaming configuration (file size threshold, chunk size)\n *\n * @example\n * ```typescript\n * // Auto mode (default) - uses streaming for files > 1MB, otherwise buffered\n * const resize = yield* createResizeNode(\"resize-1\", { width: 800, height: 600 }, {\n * naming: { mode: \"auto\" }\n * });\n *\n * // Force buffered mode for small files\n * const resizeBuffered = yield* createResizeNode(\"resize-2\", { width: 800, height: 600 }, {\n * mode: \"buffered\",\n * naming: { mode: \"auto\" }\n * });\n *\n * // Force streaming mode for memory efficiency\n * const resizeStreaming = yield* createResizeNode(\"resize-3\", { width: 800, height: 600 }, {\n * mode: \"streaming\",\n * naming: { mode: \"auto\" }\n * });\n * ```\n */\nexport function createResizeNode(\n id: string,\n { width, height, fit }: ResizeParams,\n options?: {\n keepOutput?: boolean;\n naming?: FileNamingConfig;\n mode?: TransformMode;\n streamingConfig?: StreamingConfig;\n },\n) {\n return Effect.gen(function* () {\n const imageService = yield* ImagePlugin;\n\n // Determine if streaming is available and requested\n const supportsStreaming = imageService.supportsStreaming ?? false;\n const requestedMode = options?.mode ?? \"auto\";\n\n // If streaming requested but not supported, fall back to buffered\n const effectiveMode: TransformMode =\n requestedMode === \"buffered\"\n ? \"buffered\"\n : supportsStreaming\n ? requestedMode\n : \"buffered\";\n\n // Build naming config with auto suffix for resize\n const namingConfig: FileNamingConfig | undefined = options?.naming\n ? {\n ...options.naming,\n // Provide default auto suffix generator for resize nodes\n autoSuffix:\n options.naming.autoSuffix ??\n ((ctx) => `${ctx.width ?? width}x${ctx.height ?? height}`),\n }\n : undefined;\n\n return yield* createTransformNode({\n id,\n name: \"Resize\",\n description: \"Resizes an image to the specified dimensions\",\n nodeTypeId: \"resize-image\",\n outputTypeId: STORAGE_OUTPUT_TYPE_ID,\n keepOutput: options?.keepOutput,\n naming: namingConfig,\n nodeType: \"resize\",\n namingVars: { width, height },\n mode: effectiveMode,\n streamingConfig: options?.streamingConfig,\n // Buffered transform (used when mode is \"buffered\" or \"auto\" selects buffered)\n transform: (inputBytes) =>\n imageService.resize(inputBytes, { height, width, fit }),\n // Streaming transform (used when mode is \"streaming\" or \"auto\" selects streaming)\n streamingTransform: imageService.resizeStream\n ? (inputStream) =>\n Effect.gen(function* () {\n const resizeStreamFn = imageService.resizeStream;\n if (!resizeStreamFn) {\n throw new Error(\"resizeStream not available\");\n }\n const outputStream = yield* resizeStreamFn(inputStream, {\n width,\n height,\n fit,\n });\n return { stream: outputStream };\n })\n : undefined,\n });\n });\n}\n","import {\n createTransformNode,\n type FileNamingConfig,\n ImagePlugin,\n STORAGE_OUTPUT_TYPE_ID,\n type StreamingConfig,\n type TransformImageParams,\n type TransformMode,\n} from \"@uploadista/core/flow\";\nimport type { UploadistaError } from \"@uploadista/core/errors\";\nimport { Effect, Stream } from \"effect\";\n\n/**\n * Apply a chain of transformations to an image by reducing over the transformations array.\n * Each transformation receives the output of the previous transformation as input.\n *\n * @param imageService - The image plugin service to use for transformations\n * @param inputBytes - The input image bytes\n * @param transformations - Array of transformations to apply in sequence\n * @returns Effect that resolves to the final transformed image bytes\n */\nfunction applyTransformationChain(\n imageService: ReturnType<typeof ImagePlugin.of>,\n inputBytes: Uint8Array,\n transformations: TransformImageParams[\"transformations\"],\n) {\n return Effect.reduce(transformations, inputBytes, (bytes, transformation) =>\n imageService.transform(bytes, transformation),\n );\n}\n\n/**\n * Apply a chain of transformations using streaming where possible.\n * Falls back to buffered processing for transformations that don't support streaming.\n *\n * @param imageService - The image plugin service to use for transformations\n * @param inputStream - The input image as a stream\n * @param transformations - Array of transformations to apply in sequence\n * @returns Effect that resolves to the final transformed image stream\n */\nfunction applyStreamingTransformationChain(\n imageService: ReturnType<typeof ImagePlugin.of>,\n inputStream: Stream.Stream<Uint8Array, UploadistaError>,\n transformations: TransformImageParams[\"transformations\"],\n): Effect.Effect<Stream.Stream<Uint8Array, UploadistaError>, UploadistaError> {\n const transformStreamFn = imageService.transformStream;\n\n if (!transformStreamFn) {\n // If streaming not supported, collect to buffer and use buffered chain\n return Effect.gen(function* () {\n // Collect stream to buffer\n const chunks: Uint8Array[] = [];\n yield* Stream.runForEach(inputStream, (chunk) =>\n Effect.sync(() => {\n chunks.push(chunk);\n }),\n );\n const totalLength = chunks.reduce((sum, c) => sum + c.byteLength, 0);\n const inputBuffer = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n inputBuffer.set(chunk, offset);\n offset += chunk.byteLength;\n }\n\n // Apply transformations\n const result = yield* applyTransformationChain(\n imageService,\n inputBuffer,\n transformations,\n );\n return Stream.make(result);\n });\n }\n\n // Apply each transformation in sequence using streaming\n return Effect.reduce(\n transformations,\n inputStream,\n (currentStream, transformation) =>\n Effect.flatMap(\n transformStreamFn(currentStream, transformation),\n (outputStream) => Effect.succeed(outputStream),\n ),\n );\n}\n\n/**\n * Creates a transform image node that applies multiple transformations sequentially.\n *\n * This node enables complex image processing workflows by chaining multiple transformations\n * together. Each transformation is applied to the output of the previous transformation,\n * allowing for powerful image manipulation pipelines.\n *\n * Supports both buffered and streaming modes for memory-efficient processing\n * of large images. In streaming mode, each transformation is applied in sequence\n * using streaming where supported.\n *\n * Supported transformations include:\n * - Basic: resize, blur, rotate, flip\n * - Filters: grayscale, sepia, brightness, contrast\n * - Effects: sharpen\n * - Advanced: watermark, logo, text (streaming not supported for these)\n *\n * Note: Watermark and logo transformations require imagePath to be a valid URL.\n * Images will be fetched from the provided URL during transformation.\n * Streaming mode is not supported for watermark, logo, and text transformations;\n * these will cause fallback to buffered mode.\n *\n * @param id - Unique identifier for this node\n * @param params - Parameters including the transformations array\n * @param options - Optional configuration\n * @param options.keepOutput - Whether to keep output in flow results\n * @param options.naming - File naming configuration (auto suffix: `transformed`)\n * @param options.mode - Transform mode: \"buffered\", \"streaming\", or \"auto\" (default)\n * @param options.streamingConfig - Streaming configuration (file size threshold, chunk size)\n *\n * @example\n * ```typescript\n * // Auto mode (default) - uses streaming for files > 1MB, otherwise buffered\n * const node = yield* createTransformImageNode(\"transform-1\", {\n * transformations: [\n * { type: 'resize', width: 800, height: 600, fit: 'cover' },\n * { type: 'brightness', value: 20 }\n * ]\n * }, {\n * naming: { mode: \"auto\" }\n * });\n *\n * // Force buffered mode for small files\n * const nodeBuffered = yield* createTransformImageNode(\"transform-2\", {\n * transformations: [\n * { type: 'resize', width: 800, height: 600, fit: 'cover' },\n * { type: 'blur', sigma: 5 }\n * ]\n * }, {\n * mode: \"buffered\",\n * naming: { mode: \"auto\" }\n * });\n *\n * // Force streaming mode for memory efficiency\n * const nodeStreaming = yield* createTransformImageNode(\"transform-3\", {\n * transformations: [{ type: 'grayscale' }]\n * }, {\n * mode: \"streaming\",\n * naming: { mode: \"auto\" }\n * });\n * ```\n */\nexport function createTransformImageNode(\n id: string,\n { transformations }: TransformImageParams,\n options?: {\n keepOutput?: boolean;\n naming?: FileNamingConfig;\n mode?: TransformMode;\n streamingConfig?: StreamingConfig;\n },\n) {\n return Effect.gen(function* () {\n const imageService = yield* ImagePlugin;\n\n // Determine if streaming is available and requested\n const supportsStreaming = imageService.supportsStreaming ?? false;\n const requestedMode = options?.mode ?? \"auto\";\n\n // Check if any transformations don't support streaming\n const hasUnsupportedTransformations = transformations.some(\n (t) => t.type === \"watermark\" || t.type === \"logo\" || t.type === \"text\",\n );\n\n // If streaming requested but not supported or unsupported transformations, fall back to buffered\n const effectiveMode: TransformMode =\n requestedMode === \"buffered\"\n ? \"buffered\"\n : supportsStreaming && !hasUnsupportedTransformations\n ? requestedMode\n : \"buffered\";\n\n // Build naming config with auto suffix for transform-image\n const namingConfig: FileNamingConfig | undefined = options?.naming\n ? {\n ...options.naming,\n autoSuffix: options.naming.autoSuffix ?? (() => \"transformed\"),\n }\n : undefined;\n\n return yield* createTransformNode({\n id,\n name: \"Transform Image\",\n description: `Apply ${transformations.length} transformation${transformations.length === 1 ? \"\" : \"s\"} to the image`,\n nodeTypeId: \"transform-image\",\n outputTypeId: STORAGE_OUTPUT_TYPE_ID,\n keepOutput: options?.keepOutput,\n naming: namingConfig,\n nodeType: \"transform-image\",\n mode: effectiveMode,\n streamingConfig: options?.streamingConfig,\n // Buffered transform (used when mode is \"buffered\" or \"auto\" selects buffered)\n transform: (inputBytes) =>\n applyTransformationChain(imageService, inputBytes, transformations),\n // Streaming transform (used when mode is \"streaming\" or \"auto\" selects streaming)\n streamingTransform:\n supportsStreaming && !hasUnsupportedTransformations\n ? (inputStream) =>\n Effect.gen(function* () {\n const outputStream =\n yield* applyStreamingTransformationChain(\n imageService,\n inputStream,\n transformations,\n );\n return { stream: outputStream };\n })\n : undefined,\n });\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["UploadistaError"],"sources":["../src/wait-for-url.ts","../src/describe-image-node.ts","../src/optimize-node.ts","../src/remove-background-node.ts","../src/resize-node.ts","../src/transform-image-node.ts"],"sourcesContent":["import { UploadistaError } from \"@uploadista/core/errors\";\nimport { Effect } from \"effect\";\n\n/**\n * Waits for a URL to become available by periodically checking its accessibility.\n * This is useful when a file has just been uploaded and may not be immediately\n * accessible due to CDN propagation or storage consistency delays.\n *\n * @param url - The URL to check for availability\n * @param options - Configuration options\n * @param options.maxWaitTime - Maximum time to wait in milliseconds (default: 10000)\n * @param options.retryDelay - Delay between retries in milliseconds (default: 500)\n * @returns Effect that succeeds when URL is available or fails with UploadistaError\n */\nexport function waitForUrlAvailability(\n url: string,\n options: {\n maxWaitTime?: number;\n retryDelay?: number;\n } = {},\n): Effect.Effect<void, UploadistaError> {\n const { maxWaitTime = 10000, retryDelay = 500 } = options;\n\n return Effect.gen(function* () {\n const startTime = Date.now();\n\n while (Date.now() - startTime < maxWaitTime) {\n const response = yield* Effect.tryPromise(() =>\n fetch(url, { method: \"HEAD\" }),\n ).pipe(Effect.catchAll(() => Effect.succeed(null)));\n\n if (response?.ok) {\n yield* Effect.logInfo(`URL ${url} is now available`);\n return;\n }\n\n if (response) {\n yield* Effect.logDebug(\n `URL not ready yet (${response.status}), retrying...`,\n );\n } else {\n yield* Effect.logDebug(`URL check failed, retrying...`);\n }\n\n yield* Effect.sleep(retryDelay);\n }\n\n return yield* UploadistaError.fromCode(\"FLOW_NODE_ERROR\", {\n cause: `URL ${url} not available after ${maxWaitTime}ms`,\n }).toEffect();\n });\n}\n","import { UploadistaError } from \"@uploadista/core/errors\";\nimport {\n completeNodeExecution,\n createFlowNode,\n IMAGE_DESCRIPTION_OUTPUT_TYPE_ID,\n ImageAiPlugin,\n imageDescriptionOutputSchema,\n NodeType,\n} from \"@uploadista/core/flow\";\nimport { uploadFileSchema } from \"@uploadista/core/types\";\n\nimport { Effect } from \"effect\";\nimport { waitForUrlAvailability } from \"./wait-for-url\";\n\nexport function createDescribeImageNode(\n id: string,\n {\n credentialId,\n keepOutput,\n }: { credentialId?: string; keepOutput?: boolean } = {},\n) {\n return Effect.gen(function* () {\n const imageAiService = yield* ImageAiPlugin;\n\n return yield* createFlowNode({\n id,\n name: \"Describe Image\",\n description: \"Describes the image using AI\",\n type: NodeType.process,\n nodeTypeId: \"describe-image\",\n outputTypeId: IMAGE_DESCRIPTION_OUTPUT_TYPE_ID,\n keepOutput,\n inputSchema: uploadFileSchema,\n outputSchema: imageDescriptionOutputSchema,\n // AI service - enable circuit breaker with skip fallback\n circuitBreaker: {\n enabled: true,\n failureThreshold: 5,\n resetTimeout: 60000,\n fallback: { type: \"skip\", passThrough: true },\n },\n run: ({ data: file, flowId, jobId, clientId }) => {\n return Effect.gen(function* () {\n const flow = {\n flowId,\n nodeId: id,\n jobId,\n };\n\n const fileUrl = file.url;\n\n // Validate input\n if (!fileUrl) {\n return yield* UploadistaError.fromCode(\"FLOW_NODE_ERROR\", {\n cause: \"URL is required for describe image operation\",\n }).toEffect();\n }\n\n yield* Effect.logInfo(\n `Describing image for file ${file.id} at URL: ${fileUrl}`,\n );\n\n // Wait for URL to be available with retry mechanism\n yield* waitForUrlAvailability(fileUrl);\n\n // Build context for ImageAI plugin\n const context = {\n clientId,\n credentialId,\n };\n\n // Describe image with error handling\n const result = yield* imageAiService\n .describeImage(fileUrl, context)\n .pipe(\n Effect.catchAll((error) =>\n Effect.gen(function* () {\n yield* Effect.logError(\"Failed to describe image\", error);\n return yield* UploadistaError.fromCode(\"FLOW_NODE_ERROR\", {\n cause:\n error instanceof Error\n ? error.message\n : \"Failed to describe image\",\n }).toEffect();\n }),\n ),\n );\n\n yield* Effect.logInfo(\n `Successfully described image for file ${file.id}`,\n );\n\n // Return structured image description output (not UploadFile)\n return completeNodeExecution({\n description: result.description,\n flow,\n });\n });\n },\n });\n });\n}\n","import { UploadistaError } from \"@uploadista/core\";\nimport {\n applyFileNaming,\n buildNamingContext,\n createTransformNode,\n type FileNamingConfig,\n getBaseName,\n ImagePlugin,\n type OptimizeParams,\n STORAGE_OUTPUT_TYPE_ID,\n type StreamingConfig,\n type TransformMode,\n} from \"@uploadista/core/flow\";\nimport { Effect } from \"effect\";\n\n// Map image format to MIME type\nconst formatToMimeType: Record<OptimizeParams[\"format\"], string> = {\n jpeg: \"image/jpeg\",\n webp: \"image/webp\",\n png: \"image/png\",\n avif: \"image/avif\",\n};\n\n// Map image format to file extension\nconst formatToExtension: Record<OptimizeParams[\"format\"], string> = {\n jpeg: \"jpg\",\n webp: \"webp\",\n png: \"png\",\n avif: \"avif\",\n};\n\n/**\n * Creates an optimize node that optimizes images for web delivery.\n *\n * Supports both buffered and streaming modes for memory-efficient processing\n * of large images. In streaming mode, the image is read and processed\n * incrementally, reducing peak memory usage.\n *\n * @param id - Unique node identifier\n * @param params - Optimize parameters (quality, format)\n * @param options - Optional configuration\n * @param options.keepOutput - Whether to keep output in flow results\n * @param options.naming - File naming configuration (auto suffix: `${format}`)\n * @param options.mode - Transform mode: \"buffered\" (default), \"streaming\", or \"auto\"\n * @param options.streamingConfig - Streaming configuration (file size threshold, chunk size)\n *\n * @example\n * ```typescript\n * // Buffered mode (default) - \"photo.jpg\" -> \"photo-webp.webp\"\n * const optimize = yield* createOptimizeNode(\"opt-1\", { quality: 80, format: \"webp\" }, {\n * naming: { mode: \"auto\" }\n * });\n *\n * // Streaming mode for large files\n * const optimizeStreaming = yield* createOptimizeNode(\"opt-2\", { quality: 80, format: \"webp\" }, {\n * mode: \"streaming\",\n * naming: { mode: \"auto\" }\n * });\n *\n * // Auto mode - uses streaming for files > 1MB\n * const optimizeAuto = yield* createOptimizeNode(\"opt-3\", { quality: 80, format: \"webp\" }, {\n * mode: \"auto\",\n * streamingConfig: { fileSizeThreshold: 1_048_576 },\n * naming: { mode: \"auto\" }\n * });\n * ```\n */\nexport function createOptimizeNode(\n id: string,\n { quality, format }: OptimizeParams,\n options?: {\n keepOutput?: boolean;\n naming?: FileNamingConfig;\n mode?: TransformMode;\n streamingConfig?: StreamingConfig;\n },\n) {\n return Effect.gen(function* () {\n const imageService = yield* ImagePlugin;\n\n // Determine if streaming is available and requested\n const supportsStreaming = imageService.supportsStreaming ?? false;\n const requestedMode = options?.mode ?? \"buffered\";\n\n // If streaming requested but not supported, fall back to buffered\n const effectiveMode: TransformMode =\n requestedMode === \"buffered\"\n ? \"buffered\"\n : supportsStreaming\n ? requestedMode\n : \"buffered\";\n\n // Helper to build output metadata from optimized result\n const buildOutputMetadata = (file: {\n metadata?: Record<string, unknown>;\n flow?: { flowId?: string; jobId?: string };\n }) => {\n const newType = formatToMimeType[format];\n const newExtension = formatToExtension[format];\n\n // Get original fileName\n const fileName = file.metadata?.fileName;\n let newFileName: string | undefined;\n\n if (fileName && typeof fileName === \"string\") {\n // Apply naming if configured\n if (options?.naming) {\n const namingConfig: FileNamingConfig = {\n ...options.naming,\n autoSuffix:\n options.naming.autoSuffix ?? ((ctx) => ctx.format ?? format),\n };\n const namingContext = buildNamingContext(\n file as Parameters<typeof buildNamingContext>[0],\n {\n flowId: file.flow?.flowId ?? \"\",\n jobId: file.flow?.jobId ?? \"\",\n nodeId: id,\n nodeType: \"optimize\",\n },\n { format, quality },\n );\n // Apply naming to get base name with suffix\n const namedFile = applyFileNaming(\n file as Parameters<typeof applyFileNaming>[0],\n namingContext,\n namingConfig,\n );\n // Replace extension with new format extension\n newFileName = `${getBaseName(namedFile)}.${newExtension}`;\n } else {\n // No naming config, just update extension\n newFileName = fileName.replace(/\\.[^.]+$/, `.${newExtension}`);\n }\n }\n\n return { newType, newFileName };\n };\n\n return yield* createTransformNode({\n id,\n name: \"Optimize\",\n description: \"Optimizes an image for web delivery\",\n nodeTypeId: \"optimize-image\",\n outputTypeId: STORAGE_OUTPUT_TYPE_ID,\n keepOutput: options?.keepOutput,\n // Note: naming is handled in transform since format changes extension\n nodeType: \"optimize\",\n namingVars: { format, quality },\n mode: effectiveMode,\n streamingConfig: options?.streamingConfig,\n // Buffered transform (used when mode is \"buffered\" or \"auto\" selects buffered)\n transform: (inputBytes, file) =>\n Effect.map(\n imageService.optimize(inputBytes, { quality, format }),\n (optimizedBytes) => {\n const { newType, newFileName } = buildOutputMetadata(file);\n return {\n bytes: optimizedBytes,\n type: newType,\n fileName: newFileName,\n } as\n | Uint8Array\n | { bytes: Uint8Array; type: string; fileName?: string };\n },\n ),\n // Streaming transform (used when mode is \"streaming\" or \"auto\" selects streaming)\n streamingTransform: imageService.optimizeStream\n ? (inputStream, file) => {\n const optimizeStreamFn = imageService.optimizeStream;\n if (!optimizeStreamFn) {\n throw UploadistaError.fromCode(\"UNKNOWN_ERROR\");\n }\n return Effect.gen(function* () {\n // Use the streaming optimization\n const outputStream = yield* optimizeStreamFn(inputStream, {\n quality,\n format,\n });\n\n const { newType, newFileName } = buildOutputMetadata(file);\n\n return {\n stream: outputStream,\n type: newType,\n fileName: newFileName,\n };\n });\n }\n : undefined,\n });\n });\n}\n","import { UploadistaError } from \"@uploadista/core/errors\";\nimport {\n applyFileNaming,\n buildNamingContext,\n completeNodeExecution,\n createFlowNode,\n type FileNamingConfig,\n ImageAiPlugin,\n NodeType,\n resolveUploadMetadata,\n STORAGE_OUTPUT_TYPE_ID,\n} from \"@uploadista/core/flow\";\nimport { uploadFileSchema } from \"@uploadista/core/types\";\nimport { UploadEngine } from \"@uploadista/core/upload\";\nimport { Effect } from \"effect\";\nimport { waitForUrlAvailability } from \"./wait-for-url\";\n\n/**\n * Creates a remove-background node that removes backgrounds from images using AI.\n *\n * @param id - Unique node identifier\n * @param options - Optional configuration\n * @param options.credentialId - Optional credential ID for AI service\n * @param options.keepOutput - Whether to keep output in flow results\n * @param options.naming - File naming configuration (auto suffix: `nobg`)\n *\n * @example\n * ```typescript\n * // With auto-naming: \"photo.jpg\" -> \"photo-nobg.jpg\"\n * const node = yield* createRemoveBackgroundNode(\"remove-bg-1\", {\n * naming: { mode: \"auto\" }\n * });\n * ```\n */\nexport function createRemoveBackgroundNode(\n id: string,\n {\n credentialId,\n keepOutput,\n naming,\n }: {\n credentialId?: string;\n keepOutput?: boolean;\n naming?: FileNamingConfig;\n } = {},\n) {\n return Effect.gen(function* () {\n const imageAiService = yield* ImageAiPlugin;\n const uploadEngine = yield* UploadEngine;\n\n return yield* createFlowNode({\n id,\n name: \"Remove Background\",\n description: \"Removes the background from an image\",\n type: NodeType.process,\n nodeTypeId: \"remove-background\",\n outputTypeId: STORAGE_OUTPUT_TYPE_ID,\n keepOutput,\n inputSchema: uploadFileSchema,\n outputSchema: uploadFileSchema,\n // AI service - enable circuit breaker with skip fallback\n circuitBreaker: {\n enabled: true,\n failureThreshold: 5,\n resetTimeout: 60000,\n fallback: { type: \"skip\", passThrough: true },\n },\n run: ({ data: file, flowId, jobId, storageId, clientId }) => {\n return Effect.gen(function* () {\n const flow = {\n flowId,\n nodeId: id,\n jobId,\n };\n\n const fileUrl = file.url;\n\n // Validate input\n if (!fileUrl) {\n return yield* UploadistaError.fromCode(\"FLOW_NODE_ERROR\", {\n cause: \"URL is required for remove background operation\",\n }).toEffect();\n }\n\n yield* Effect.logInfo(\n `Removing background for file ${file.id} at URL: ${file.url}`,\n );\n\n // Wait for URL to be available with retry mechanism\n yield* waitForUrlAvailability(fileUrl);\n\n // Build context for ImageAI plugin\n const context = {\n clientId,\n credentialId,\n };\n\n // Remove background with error handling\n const backgroundRemovalResult = yield* imageAiService\n .removeBackground(fileUrl, context)\n .pipe(\n Effect.catchAll((error) =>\n Effect.gen(function* () {\n yield* Effect.logError(\"Failed to remove background\", error);\n return yield* UploadistaError.fromCode(\"FLOW_NODE_ERROR\", {\n cause:\n error instanceof Error\n ? error.message\n : \"Failed to remove background from image\",\n }).toEffect();\n }),\n ),\n );\n\n const { outputUrl } = backgroundRemovalResult;\n const { type, fileName, metadata, metadataJson } =\n resolveUploadMetadata(file.metadata);\n\n // Apply file naming if configured\n let outputFileName = fileName;\n if (naming) {\n const namingConfig: FileNamingConfig = {\n ...naming,\n autoSuffix: naming.autoSuffix ?? (() => \"nobg\"),\n };\n const namingContext = buildNamingContext(file, {\n flowId,\n jobId,\n nodeId: id,\n nodeType: \"remove-background\",\n });\n outputFileName = applyFileNaming(file, namingContext, namingConfig);\n }\n\n yield* Effect.logInfo(`Uploading processed file to storage`);\n\n // Upload the transformed bytes back to the upload server with error handling\n const result = yield* uploadEngine\n .uploadFromUrl(\n {\n storageId,\n size: 0,\n type,\n fileName: outputFileName,\n lastModified: 0,\n metadata: metadataJson,\n flow,\n },\n clientId,\n outputUrl,\n )\n .pipe(\n Effect.catchAll((error) =>\n Effect.gen(function* () {\n yield* Effect.logError(\n \"Failed to upload processed file\",\n error,\n );\n return yield* UploadistaError.fromCode(\"FLOW_NODE_ERROR\", {\n cause:\n error instanceof Error\n ? error.message\n : \"Failed to upload processed file\",\n }).toEffect();\n }),\n ),\n );\n\n yield* Effect.logInfo(\n `Successfully removed background for file ${file.id}`,\n );\n\n // Update metadata with new filename if naming was applied\n const updatedMetadata = metadata\n ? {\n ...metadata,\n ...(outputFileName !== fileName && {\n fileName: outputFileName,\n originalName: outputFileName,\n name: outputFileName,\n extension:\n outputFileName.split(\".\").pop() || metadata.extension,\n }),\n }\n : result.metadata;\n\n return completeNodeExecution(\n updatedMetadata\n ? {\n ...result,\n metadata: updatedMetadata,\n }\n : result,\n );\n });\n },\n });\n });\n}\n","import {\n createTransformNode,\n type FileNamingConfig,\n ImagePlugin,\n type ResizeParams,\n STORAGE_OUTPUT_TYPE_ID,\n type StreamingConfig,\n type TransformMode,\n} from \"@uploadista/core/flow\";\nimport { Effect } from \"effect\";\n\n/**\n * Creates a resize node that resizes images to specified dimensions.\n *\n * Supports both buffered and streaming modes for memory-efficient processing\n * of large images. In streaming mode, the image is read and processed\n * incrementally, reducing peak memory usage.\n *\n * @param id - Unique node identifier\n * @param params - Resize parameters (width, height, fit)\n * @param options - Optional configuration\n * @param options.keepOutput - Whether to keep output in flow results\n * @param options.naming - File naming configuration (auto suffix: `${width}x${height}`)\n * @param options.mode - Transform mode: \"buffered\", \"streaming\", or \"auto\" (default)\n * @param options.streamingConfig - Streaming configuration (file size threshold, chunk size)\n *\n * @example\n * ```typescript\n * // Auto mode (default) - uses streaming for files > 1MB, otherwise buffered\n * const resize = yield* createResizeNode(\"resize-1\", { width: 800, height: 600 }, {\n * naming: { mode: \"auto\" }\n * });\n *\n * // Force buffered mode for small files\n * const resizeBuffered = yield* createResizeNode(\"resize-2\", { width: 800, height: 600 }, {\n * mode: \"buffered\",\n * naming: { mode: \"auto\" }\n * });\n *\n * // Force streaming mode for memory efficiency\n * const resizeStreaming = yield* createResizeNode(\"resize-3\", { width: 800, height: 600 }, {\n * mode: \"streaming\",\n * naming: { mode: \"auto\" }\n * });\n * ```\n */\nexport function createResizeNode(\n id: string,\n { width, height, fit }: ResizeParams,\n options?: {\n keepOutput?: boolean;\n naming?: FileNamingConfig;\n mode?: TransformMode;\n streamingConfig?: StreamingConfig;\n },\n) {\n return Effect.gen(function* () {\n const imageService = yield* ImagePlugin;\n\n // Determine if streaming is available and requested\n const supportsStreaming = imageService.supportsStreaming ?? false;\n const requestedMode = options?.mode ?? \"auto\";\n\n // If streaming requested but not supported, fall back to buffered\n const effectiveMode: TransformMode =\n requestedMode === \"buffered\"\n ? \"buffered\"\n : supportsStreaming\n ? requestedMode\n : \"buffered\";\n\n // Build naming config with auto suffix for resize\n const namingConfig: FileNamingConfig | undefined = options?.naming\n ? {\n ...options.naming,\n // Provide default auto suffix generator for resize nodes\n autoSuffix:\n options.naming.autoSuffix ??\n ((ctx) => `${ctx.width ?? width}x${ctx.height ?? height}`),\n }\n : undefined;\n\n return yield* createTransformNode({\n id,\n name: \"Resize\",\n description: \"Resizes an image to the specified dimensions\",\n nodeTypeId: \"resize-image\",\n outputTypeId: STORAGE_OUTPUT_TYPE_ID,\n keepOutput: options?.keepOutput,\n naming: namingConfig,\n nodeType: \"resize\",\n namingVars: { width, height },\n mode: effectiveMode,\n streamingConfig: options?.streamingConfig,\n // Buffered transform (used when mode is \"buffered\" or \"auto\" selects buffered)\n transform: (inputBytes) =>\n imageService.resize(inputBytes, { height, width, fit }),\n // Streaming transform (used when mode is \"streaming\" or \"auto\" selects streaming)\n streamingTransform: imageService.resizeStream\n ? (inputStream) =>\n Effect.gen(function* () {\n const resizeStreamFn = imageService.resizeStream;\n if (!resizeStreamFn) {\n throw new Error(\"resizeStream not available\");\n }\n const outputStream = yield* resizeStreamFn(inputStream, {\n width,\n height,\n fit,\n });\n return { stream: outputStream };\n })\n : undefined,\n });\n });\n}\n","import type { UploadistaError } from \"@uploadista/core/errors\";\nimport {\n createTransformNode,\n type FileNamingConfig,\n ImagePlugin,\n STORAGE_OUTPUT_TYPE_ID,\n type StreamingConfig,\n type TransformImageParams,\n type TransformMode,\n} from \"@uploadista/core/flow\";\nimport { Effect, Stream } from \"effect\";\n\n/**\n * Apply a chain of transformations to an image by reducing over the transformations array.\n * Each transformation receives the output of the previous transformation as input.\n *\n * @param imageService - The image plugin service to use for transformations\n * @param inputBytes - The input image bytes\n * @param transformations - Array of transformations to apply in sequence\n * @returns Effect that resolves to the final transformed image bytes\n */\nfunction applyTransformationChain(\n imageService: ReturnType<typeof ImagePlugin.of>,\n inputBytes: Uint8Array,\n transformations: TransformImageParams[\"transformations\"],\n) {\n return Effect.reduce(transformations, inputBytes, (bytes, transformation) =>\n imageService.transform(bytes, transformation),\n );\n}\n\n/**\n * Apply a chain of transformations using streaming where possible.\n * Falls back to buffered processing for transformations that don't support streaming.\n *\n * @param imageService - The image plugin service to use for transformations\n * @param inputStream - The input image as a stream\n * @param transformations - Array of transformations to apply in sequence\n * @returns Effect that resolves to the final transformed image stream\n */\nfunction applyStreamingTransformationChain(\n imageService: ReturnType<typeof ImagePlugin.of>,\n inputStream: Stream.Stream<Uint8Array, UploadistaError>,\n transformations: TransformImageParams[\"transformations\"],\n): Effect.Effect<Stream.Stream<Uint8Array, UploadistaError>, UploadistaError> {\n const transformStreamFn = imageService.transformStream;\n\n if (!transformStreamFn) {\n // If streaming not supported, collect to buffer and use buffered chain\n return Effect.gen(function* () {\n // Collect stream to buffer\n const chunks: Uint8Array[] = [];\n yield* Stream.runForEach(inputStream, (chunk) =>\n Effect.sync(() => {\n chunks.push(chunk);\n }),\n );\n const totalLength = chunks.reduce((sum, c) => sum + c.byteLength, 0);\n const inputBuffer = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n inputBuffer.set(chunk, offset);\n offset += chunk.byteLength;\n }\n\n // Apply transformations\n const result = yield* applyTransformationChain(\n imageService,\n inputBuffer,\n transformations,\n );\n return Stream.make(result);\n });\n }\n\n // Apply each transformation in sequence using streaming\n return Effect.reduce(\n transformations,\n inputStream,\n (currentStream, transformation) =>\n Effect.flatMap(\n transformStreamFn(currentStream, transformation),\n (outputStream) => Effect.succeed(outputStream),\n ),\n );\n}\n\n/**\n * Creates a transform image node that applies multiple transformations sequentially.\n *\n * This node enables complex image processing workflows by chaining multiple transformations\n * together. Each transformation is applied to the output of the previous transformation,\n * allowing for powerful image manipulation pipelines.\n *\n * Supports both buffered and streaming modes for memory-efficient processing\n * of large images. In streaming mode, each transformation is applied in sequence\n * using streaming where supported.\n *\n * Supported transformations include:\n * - Basic: resize, blur, rotate, flip\n * - Filters: grayscale, sepia, brightness, contrast\n * - Effects: sharpen\n * - Advanced: watermark, logo, text (streaming not supported for these)\n *\n * Note: Watermark and logo transformations require imagePath to be a valid URL.\n * Images will be fetched from the provided URL during transformation.\n * Streaming mode is not supported for watermark, logo, and text transformations;\n * these will cause fallback to buffered mode.\n *\n * @param id - Unique identifier for this node\n * @param params - Parameters including the transformations array\n * @param options - Optional configuration\n * @param options.keepOutput - Whether to keep output in flow results\n * @param options.naming - File naming configuration (auto suffix: `transformed`)\n * @param options.mode - Transform mode: \"buffered\", \"streaming\", or \"auto\" (default)\n * @param options.streamingConfig - Streaming configuration (file size threshold, chunk size)\n *\n * @example\n * ```typescript\n * // Auto mode (default) - uses streaming for files > 1MB, otherwise buffered\n * const node = yield* createTransformImageNode(\"transform-1\", {\n * transformations: [\n * { type: 'resize', width: 800, height: 600, fit: 'cover' },\n * { type: 'brightness', value: 20 }\n * ]\n * }, {\n * naming: { mode: \"auto\" }\n * });\n *\n * // Force buffered mode for small files\n * const nodeBuffered = yield* createTransformImageNode(\"transform-2\", {\n * transformations: [\n * { type: 'resize', width: 800, height: 600, fit: 'cover' },\n * { type: 'blur', sigma: 5 }\n * ]\n * }, {\n * mode: \"buffered\",\n * naming: { mode: \"auto\" }\n * });\n *\n * // Force streaming mode for memory efficiency\n * const nodeStreaming = yield* createTransformImageNode(\"transform-3\", {\n * transformations: [{ type: 'grayscale' }]\n * }, {\n * mode: \"streaming\",\n * naming: { mode: \"auto\" }\n * });\n * ```\n */\nexport function createTransformImageNode(\n id: string,\n { transformations }: TransformImageParams,\n options?: {\n keepOutput?: boolean;\n naming?: FileNamingConfig;\n mode?: TransformMode;\n streamingConfig?: StreamingConfig;\n },\n) {\n return Effect.gen(function* () {\n const imageService = yield* ImagePlugin;\n\n // Determine if streaming is available and requested\n const supportsStreaming = imageService.supportsStreaming ?? false;\n const requestedMode = options?.mode ?? \"auto\";\n\n // Check if any transformations don't support streaming\n const hasUnsupportedTransformations = transformations.some(\n (t) => t.type === \"watermark\" || t.type === \"logo\" || t.type === \"text\",\n );\n\n // If streaming requested but not supported or unsupported transformations, fall back to buffered\n const effectiveMode: TransformMode =\n requestedMode === \"buffered\"\n ? \"buffered\"\n : supportsStreaming && !hasUnsupportedTransformations\n ? requestedMode\n : \"buffered\";\n\n // Build naming config with auto suffix for transform-image\n const namingConfig: FileNamingConfig | undefined = options?.naming\n ? {\n ...options.naming,\n autoSuffix: options.naming.autoSuffix ?? (() => \"transformed\"),\n }\n : undefined;\n\n return yield* createTransformNode({\n id,\n name: \"Transform Image\",\n description: `Apply ${transformations.length} transformation${transformations.length === 1 ? \"\" : \"s\"} to the image`,\n nodeTypeId: \"transform-image\",\n outputTypeId: STORAGE_OUTPUT_TYPE_ID,\n keepOutput: options?.keepOutput,\n naming: namingConfig,\n nodeType: \"transform-image\",\n mode: effectiveMode,\n streamingConfig: options?.streamingConfig,\n // Buffered transform (used when mode is \"buffered\" or \"auto\" selects buffered)\n transform: (inputBytes) =>\n applyTransformationChain(imageService, inputBytes, transformations),\n // Streaming transform (used when mode is \"streaming\" or \"auto\" selects streaming)\n streamingTransform:\n supportsStreaming && !hasUnsupportedTransformations\n ? (inputStream) =>\n Effect.gen(function* () {\n const outputStream = yield* applyStreamingTransformationChain(\n imageService,\n inputStream,\n transformations,\n );\n return { stream: outputStream };\n })\n : undefined,\n });\n });\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uploadista/flow-images-nodes",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.1.0-beta.5",
|
|
5
5
|
"description": "Image processing nodes for Uploadista Flow",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "Uploadista",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@uploadista/core": "0.0.
|
|
17
|
+
"@uploadista/core": "0.1.0-beta.5"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
20
|
"effect": "^3.0.0",
|
|
@@ -22,19 +22,19 @@
|
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@effect/vitest": "0.27.0",
|
|
25
|
-
"@types/node": "24.10.
|
|
26
|
-
"effect": "3.19.
|
|
27
|
-
"tsdown": "0.
|
|
28
|
-
"vitest": "4.0.
|
|
29
|
-
"zod": "4.
|
|
30
|
-
"@uploadista/typescript-config": "0.0.
|
|
25
|
+
"@types/node": "24.10.8",
|
|
26
|
+
"effect": "3.19.14",
|
|
27
|
+
"tsdown": "0.19.0",
|
|
28
|
+
"vitest": "4.0.17",
|
|
29
|
+
"zod": "4.3.5",
|
|
30
|
+
"@uploadista/typescript-config": "0.1.0-beta.5"
|
|
31
31
|
},
|
|
32
32
|
"scripts": {
|
|
33
33
|
"build": "tsc --noEmit && tsdown",
|
|
34
34
|
"check": "biome check --write ./src",
|
|
35
35
|
"format": "biome format --write ./src",
|
|
36
36
|
"lint": "biome lint --write ./src",
|
|
37
|
-
"test": "vitest",
|
|
37
|
+
"test": "vitest run",
|
|
38
38
|
"test:run": "vitest run",
|
|
39
39
|
"test:watch": "vitest --watch"
|
|
40
40
|
}
|
|
@@ -14,7 +14,10 @@ import { waitForUrlAvailability } from "./wait-for-url";
|
|
|
14
14
|
|
|
15
15
|
export function createDescribeImageNode(
|
|
16
16
|
id: string,
|
|
17
|
-
{
|
|
17
|
+
{
|
|
18
|
+
credentialId,
|
|
19
|
+
keepOutput,
|
|
20
|
+
}: { credentialId?: string; keepOutput?: boolean } = {},
|
|
18
21
|
) {
|
|
19
22
|
return Effect.gen(function* () {
|
|
20
23
|
const imageAiService = yield* ImageAiPlugin;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { UploadistaError } from "@uploadista/core/errors";
|
|
1
2
|
import {
|
|
2
3
|
createTransformNode,
|
|
3
4
|
type FileNamingConfig,
|
|
@@ -7,7 +8,6 @@ import {
|
|
|
7
8
|
type TransformImageParams,
|
|
8
9
|
type TransformMode,
|
|
9
10
|
} from "@uploadista/core/flow";
|
|
10
|
-
import type { UploadistaError } from "@uploadista/core/errors";
|
|
11
11
|
import { Effect, Stream } from "effect";
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -204,12 +204,11 @@ export function createTransformImageNode(
|
|
|
204
204
|
supportsStreaming && !hasUnsupportedTransformations
|
|
205
205
|
? (inputStream) =>
|
|
206
206
|
Effect.gen(function* () {
|
|
207
|
-
const outputStream =
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
);
|
|
207
|
+
const outputStream = yield* applyStreamingTransformationChain(
|
|
208
|
+
imageService,
|
|
209
|
+
inputStream,
|
|
210
|
+
transformations,
|
|
211
|
+
);
|
|
213
212
|
return { stream: outputStream };
|
|
214
213
|
})
|
|
215
214
|
: undefined,
|
|
@@ -504,9 +504,9 @@ describe("Image Nodes", () => {
|
|
|
504
504
|
expect(result.type).toBe("complete");
|
|
505
505
|
if (result.type === "complete") {
|
|
506
506
|
expect(result.data).toBeDefined();
|
|
507
|
-
expect(result.data.
|
|
508
|
-
expect(typeof result.data.
|
|
509
|
-
expect(result.data.
|
|
507
|
+
expect(result.data.description).toBeDefined();
|
|
508
|
+
expect(typeof result.data.description).toBe("string");
|
|
509
|
+
expect(result.data.description).toContain("test image");
|
|
510
510
|
}
|
|
511
511
|
}).pipe(Effect.provide(TestLayer)),
|
|
512
512
|
);
|
|
@@ -555,7 +555,7 @@ describe("Image Nodes", () => {
|
|
|
555
555
|
expect(result.type).toBe("complete");
|
|
556
556
|
if (result.type === "complete") {
|
|
557
557
|
expect(result.data).toBeDefined();
|
|
558
|
-
expect(result.data.
|
|
558
|
+
expect(result.data.description).toBeDefined();
|
|
559
559
|
}
|
|
560
560
|
}).pipe(Effect.provide(TestLayer)),
|
|
561
561
|
);
|