@uploadista/flow-utility-nodes 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.
- package/.turbo/turbo-build.log +5 -0
- package/.turbo/turbo-check.log +5 -0
- package/LICENSE +21 -0
- package/README.md +289 -0
- package/dist/conditional-node.d.ts +25 -0
- package/dist/conditional-node.d.ts.map +1 -0
- package/dist/conditional-node.js +34 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/merge-node.d.ts +12 -0
- package/dist/merge-node.d.ts.map +1 -0
- package/dist/merge-node.js +77 -0
- package/dist/multiplex-node.d.ts +42 -0
- package/dist/multiplex-node.d.ts.map +1 -0
- package/dist/multiplex-node.js +67 -0
- package/dist/nodes/conditional-node.d.ts +5 -0
- package/dist/nodes/conditional-node.d.ts.map +1 -0
- package/dist/nodes/conditional-node.js +19 -0
- package/dist/nodes/index.d.ts +5 -0
- package/dist/nodes/index.d.ts.map +1 -0
- package/dist/nodes/index.js +4 -0
- package/dist/nodes/merge-node.d.ts +7 -0
- package/dist/nodes/merge-node.d.ts.map +1 -0
- package/dist/nodes/merge-node.js +82 -0
- package/dist/nodes/multiplex-node.d.ts +7 -0
- package/dist/nodes/multiplex-node.d.ts.map +1 -0
- package/dist/nodes/multiplex-node.js +57 -0
- package/dist/nodes/zip-node.d.ts +8 -0
- package/dist/nodes/zip-node.d.ts.map +1 -0
- package/dist/nodes/zip-node.js +64 -0
- package/dist/types/conditional-node.d.ts +21 -0
- package/dist/types/conditional-node.d.ts.map +1 -0
- package/dist/types/conditional-node.js +13 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/dist/types/merge-node.d.ts +11 -0
- package/dist/types/merge-node.d.ts.map +1 -0
- package/dist/types/merge-node.js +6 -0
- package/dist/types/multiplex-node.d.ts +10 -0
- package/dist/types/multiplex-node.d.ts.map +1 -0
- package/dist/types/multiplex-node.js +5 -0
- package/dist/types/zip-node.d.ts +8 -0
- package/dist/types/zip-node.d.ts.map +1 -0
- package/dist/types/zip-node.js +6 -0
- package/dist/zip-node.d.ts +9 -0
- package/dist/zip-node.d.ts.map +1 -0
- package/dist/zip-node.js +65 -0
- package/package.json +35 -0
- package/src/nodes/conditional-node.ts +28 -0
- package/src/nodes/index.ts +4 -0
- package/src/nodes/merge-node.ts +111 -0
- package/src/nodes/multiplex-node.ts +87 -0
- package/src/nodes/zip-node.ts +92 -0
- package/src/types/conditional-node.ts +16 -0
- package/src/types/index.ts +4 -0
- package/src/types/merge-node.ts +9 -0
- package/src/types/multiplex-node.ts +8 -0
- package/src/types/zip-node.ts +9 -0
- package/tsconfig.json +14 -0
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { UploadistaError } from "@uploadista/core/errors";
|
|
2
|
+
import {
|
|
3
|
+
completeNodeExecution,
|
|
4
|
+
createFlowNode,
|
|
5
|
+
NodeType,
|
|
6
|
+
resolveUploadMetadata,
|
|
7
|
+
} from "@uploadista/core/flow";
|
|
8
|
+
import { type UploadFile, uploadFileSchema } from "@uploadista/core/types";
|
|
9
|
+
import { UploadServer } from "@uploadista/core/upload";
|
|
10
|
+
import { Effect } from "effect";
|
|
11
|
+
import type { MultiplexParams } from "@/types/multiplex-node";
|
|
12
|
+
|
|
13
|
+
export function createMultiplexNode(
|
|
14
|
+
id: string,
|
|
15
|
+
{ outputCount: _outputCount, strategy }: MultiplexParams,
|
|
16
|
+
) {
|
|
17
|
+
return Effect.gen(function* () {
|
|
18
|
+
const uploadServer = yield* UploadServer;
|
|
19
|
+
|
|
20
|
+
return yield* createFlowNode<UploadFile, UploadFile>({
|
|
21
|
+
id,
|
|
22
|
+
name: "Multiplex",
|
|
23
|
+
description: `Multiplexes input using ${strategy} strategy`,
|
|
24
|
+
type: NodeType.multiplex,
|
|
25
|
+
inputSchema: uploadFileSchema,
|
|
26
|
+
outputSchema: uploadFileSchema,
|
|
27
|
+
multiOutput: true,
|
|
28
|
+
run: ({ data: file, storageId, clientId }) => {
|
|
29
|
+
return Effect.gen(function* () {
|
|
30
|
+
const { type, fileName, metadata, metadataJson } =
|
|
31
|
+
resolveUploadMetadata(file.metadata);
|
|
32
|
+
const normalizedFile = metadata ? { ...file, metadata } : file;
|
|
33
|
+
|
|
34
|
+
if (strategy === "copy") {
|
|
35
|
+
// For copy strategy, read and re-upload the file
|
|
36
|
+
const inputBytes = yield* uploadServer.read(
|
|
37
|
+
normalizedFile.id,
|
|
38
|
+
clientId,
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const stream = new ReadableStream({
|
|
42
|
+
start(controller) {
|
|
43
|
+
controller.enqueue(inputBytes);
|
|
44
|
+
controller.close();
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const result = yield* uploadServer.upload(
|
|
49
|
+
{
|
|
50
|
+
storageId,
|
|
51
|
+
size: inputBytes.byteLength,
|
|
52
|
+
type,
|
|
53
|
+
fileName,
|
|
54
|
+
lastModified: 0,
|
|
55
|
+
metadata: metadataJson,
|
|
56
|
+
},
|
|
57
|
+
clientId,
|
|
58
|
+
stream,
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
const resolvedResult = resolveUploadMetadata(result.metadata);
|
|
62
|
+
|
|
63
|
+
return completeNodeExecution(
|
|
64
|
+
resolvedResult.metadata
|
|
65
|
+
? { ...result, metadata: resolvedResult.metadata }
|
|
66
|
+
: result,
|
|
67
|
+
);
|
|
68
|
+
} else if (strategy === "split") {
|
|
69
|
+
// Split strategy is not supported in the new pattern
|
|
70
|
+
// as it would require returning multiple UploadFiles
|
|
71
|
+
return yield* Effect.fail(
|
|
72
|
+
UploadistaError.fromCode("VALIDATION_ERROR", {
|
|
73
|
+
body: "Split strategy is not supported with UploadFile pattern",
|
|
74
|
+
}),
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return yield* Effect.fail(
|
|
79
|
+
UploadistaError.fromCode("VALIDATION_ERROR", {
|
|
80
|
+
body: `Unknown multiplex strategy: ${strategy}`,
|
|
81
|
+
}),
|
|
82
|
+
);
|
|
83
|
+
});
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { UploadistaError } from "@uploadista/core/errors";
|
|
2
|
+
import {
|
|
3
|
+
completeNodeExecution,
|
|
4
|
+
createFlowNode,
|
|
5
|
+
NodeType,
|
|
6
|
+
ZipPlugin,
|
|
7
|
+
} from "@uploadista/core/flow";
|
|
8
|
+
import { type UploadFile, uploadFileSchema } from "@uploadista/core/types";
|
|
9
|
+
import { UploadServer } from "@uploadista/core/upload";
|
|
10
|
+
import { Effect } from "effect";
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
import type { ZipParams } from "@/types/zip-node";
|
|
13
|
+
|
|
14
|
+
const inputSchema = z.record(z.string(), uploadFileSchema);
|
|
15
|
+
const outputSchema = uploadFileSchema;
|
|
16
|
+
|
|
17
|
+
export function createZipNode(
|
|
18
|
+
id: string,
|
|
19
|
+
{ zipName, includeMetadata }: ZipParams,
|
|
20
|
+
) {
|
|
21
|
+
return Effect.gen(function* () {
|
|
22
|
+
const uploadServer = yield* UploadServer;
|
|
23
|
+
const zipPlugin = yield* ZipPlugin;
|
|
24
|
+
return yield* createFlowNode<Record<string, UploadFile>, UploadFile>({
|
|
25
|
+
id,
|
|
26
|
+
name: "Zip Files",
|
|
27
|
+
description: "Combines multiple files into a zip archive",
|
|
28
|
+
type: NodeType.process,
|
|
29
|
+
inputSchema,
|
|
30
|
+
outputSchema,
|
|
31
|
+
multiInput: true,
|
|
32
|
+
run: ({ data: inputs, storageId, clientId }) => {
|
|
33
|
+
return Effect.gen(function* () {
|
|
34
|
+
if (!inputs || Object.keys(inputs).length === 0) {
|
|
35
|
+
return yield* Effect.fail(
|
|
36
|
+
UploadistaError.fromCode("VALIDATION_ERROR", {
|
|
37
|
+
body: "No inputs provided to zip node",
|
|
38
|
+
}),
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
const zipInputs = yield* Effect.forEach(
|
|
44
|
+
Object.values(inputs),
|
|
45
|
+
(input) =>
|
|
46
|
+
Effect.gen(function* () {
|
|
47
|
+
const data = yield* uploadServer.read(input.id, clientId);
|
|
48
|
+
return {
|
|
49
|
+
id: input.id,
|
|
50
|
+
data,
|
|
51
|
+
metadata: input.metadata,
|
|
52
|
+
};
|
|
53
|
+
}),
|
|
54
|
+
{ concurrency: "unbounded" }
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const zipBytes = yield* zipPlugin.zip(zipInputs, { zipName, includeMetadata });
|
|
58
|
+
|
|
59
|
+
// Create a stream from the zip bytes
|
|
60
|
+
const stream = new ReadableStream({
|
|
61
|
+
start(controller) {
|
|
62
|
+
controller.enqueue(zipBytes);
|
|
63
|
+
controller.close();
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Upload the zip file
|
|
68
|
+
const result = yield* uploadServer.upload(
|
|
69
|
+
{
|
|
70
|
+
storageId,
|
|
71
|
+
size: zipBytes.byteLength,
|
|
72
|
+
type: "application/zip",
|
|
73
|
+
fileName: zipName,
|
|
74
|
+
lastModified: 0,
|
|
75
|
+
metadata: JSON.stringify({
|
|
76
|
+
mimeType: "application/zip",
|
|
77
|
+
type: "application/zip",
|
|
78
|
+
originalName: zipName,
|
|
79
|
+
fileName: zipName,
|
|
80
|
+
extension: "zip",
|
|
81
|
+
}),
|
|
82
|
+
},
|
|
83
|
+
clientId,
|
|
84
|
+
stream,
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
return completeNodeExecution(result);
|
|
88
|
+
});
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
export const conditionalParamsSchema = z.object({
|
|
4
|
+
field: z.enum(["mimeType", "size", "width", "height", "extension"]),
|
|
5
|
+
operator: z.enum([
|
|
6
|
+
"equals",
|
|
7
|
+
"notEquals",
|
|
8
|
+
"greaterThan",
|
|
9
|
+
"lessThan",
|
|
10
|
+
"contains",
|
|
11
|
+
"startsWith",
|
|
12
|
+
]),
|
|
13
|
+
value: z.union([z.string(), z.number()]),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export type ConditionalParams = z.infer<typeof conditionalParamsSchema>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
export const mergeParamsSchema = z.object({
|
|
4
|
+
strategy: z.enum(["concat", "batch"]).default("batch"),
|
|
5
|
+
separator: z.string().default("\n").optional(),
|
|
6
|
+
inputCount: z.number().min(2).max(10).default(2),
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export type MergeParams = z.infer<typeof mergeParamsSchema>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
export const zipParamsSchema = z.object({
|
|
4
|
+
zipName: z.string().default("archive.zip"),
|
|
5
|
+
includeMetadata: z.boolean().default(false),
|
|
6
|
+
inputCount: z.number().min(2).max(10).default(2),
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export type ZipParams = z.infer<typeof zipParamsSchema>;
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "@uploadista/typescript-config/server.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"baseUrl": "./",
|
|
5
|
+
"paths": {
|
|
6
|
+
"@/*": ["./src/*"]
|
|
7
|
+
},
|
|
8
|
+
"outDir": "./dist",
|
|
9
|
+
"rootDir": "./src",
|
|
10
|
+
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
|
11
|
+
"types": []
|
|
12
|
+
},
|
|
13
|
+
"include": ["src"]
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["./src/nodes/conditional-node.ts","./src/nodes/index.ts","./src/nodes/merge-node.ts","./src/nodes/multiplex-node.ts","./src/nodes/zip-node.ts","./src/types/conditional-node.ts","./src/types/index.ts","./src/types/merge-node.ts","./src/types/multiplex-node.ts","./src/types/zip-node.ts"],"version":"5.9.3"}
|