@uploadista/core 0.0.13-beta.5 → 0.0.13

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 (101) hide show
  1. package/README.md +1 -1
  2. package/dist/{checksum-P9C2JlRk.mjs → checksum-CtOagryS.mjs} +2 -2
  3. package/dist/{checksum-P9C2JlRk.mjs.map → checksum-CtOagryS.mjs.map} +1 -1
  4. package/dist/errors/index.d.cts +2 -2
  5. package/dist/errors/index.d.mts +2 -2
  6. package/dist/errors/index.mjs +1 -1
  7. package/dist/flow/index.cjs +1 -1
  8. package/dist/flow/index.d.cts +5 -5
  9. package/dist/flow/index.d.mts +5 -5
  10. package/dist/flow/index.mjs +1 -1
  11. package/dist/{flow-DkTE3siV.cjs → flow-ChADffZ5.cjs} +1 -1
  12. package/dist/{flow-IgE8hj7H.mjs → flow-_J9-Dm_m.mjs} +2 -2
  13. package/dist/flow-_J9-Dm_m.mjs.map +1 -0
  14. package/dist/{index-CrZopnP9.d.cts → index-4VDJDcWM.d.cts} +227 -241
  15. package/dist/index-4VDJDcWM.d.cts.map +1 -0
  16. package/dist/{index-BPBI84iT.d.mts → index-Bi9YYid8.d.mts} +2 -2
  17. package/dist/{index-BPBI84iT.d.mts.map → index-Bi9YYid8.d.mts.map} +1 -1
  18. package/dist/{index-BteFEg-c.d.mts → index-Cbf1OPLp.d.mts} +2 -2
  19. package/dist/{index-BteFEg-c.d.mts.map → index-Cbf1OPLp.d.mts.map} +1 -1
  20. package/dist/{index-DMfADSSJ.d.cts → index-De4wQJwR.d.cts} +2 -2
  21. package/dist/{index-DMfADSSJ.d.cts.map → index-De4wQJwR.d.cts.map} +1 -1
  22. package/dist/{index-DHt7Ht_J.d.mts → index-RgOX4psL.d.mts} +305 -139
  23. package/dist/index-RgOX4psL.d.mts.map +1 -0
  24. package/dist/{index-DubOIur4.d.cts → index-qZ90PVNl.d.cts} +2 -2
  25. package/dist/index-qZ90PVNl.d.cts.map +1 -0
  26. package/dist/index.cjs +1 -1
  27. package/dist/index.d.cts +5 -5
  28. package/dist/index.d.mts +5 -5
  29. package/dist/index.mjs +1 -1
  30. package/dist/{stream-limiter-DFtRZczp.mjs → stream-limiter-D9KSAaoY.mjs} +2 -2
  31. package/dist/{stream-limiter-DFtRZczp.mjs.map → stream-limiter-D9KSAaoY.mjs.map} +1 -1
  32. package/dist/streams/index.d.cts +2 -2
  33. package/dist/streams/index.d.mts +2 -2
  34. package/dist/streams/index.mjs +1 -1
  35. package/dist/testing/index.cjs +1 -0
  36. package/dist/testing/index.d.cts +110 -0
  37. package/dist/testing/index.d.cts.map +1 -0
  38. package/dist/testing/index.d.mts +110 -0
  39. package/dist/testing/index.d.mts.map +1 -0
  40. package/dist/testing/index.mjs +2 -0
  41. package/dist/testing/index.mjs.map +1 -0
  42. package/dist/types/index.d.cts +5 -5
  43. package/dist/types/index.d.mts +5 -5
  44. package/dist/types/index.mjs +1 -1
  45. package/dist/{types-DGZ892my.mjs → types-BI_KmpTc.mjs} +2 -2
  46. package/dist/types-BI_KmpTc.mjs.map +1 -0
  47. package/dist/upload/index.d.cts +5 -5
  48. package/dist/upload/index.d.mts +5 -5
  49. package/dist/upload/index.mjs +1 -1
  50. package/dist/{upload-DJTptYqV.mjs → upload-Yj5lrtZo.mjs} +2 -2
  51. package/dist/{upload-DJTptYqV.mjs.map → upload-Yj5lrtZo.mjs.map} +1 -1
  52. package/dist/{uploadista-error-9yLWP7TC.d.cts → uploadista-error-BQLhNZcY.d.cts} +1 -1
  53. package/dist/{uploadista-error-9yLWP7TC.d.cts.map → uploadista-error-BQLhNZcY.d.cts.map} +1 -1
  54. package/dist/{uploadista-error-nZ_q-EZy.mjs → uploadista-error-Buscq-FR.mjs} +1 -1
  55. package/dist/{uploadista-error-nZ_q-EZy.mjs.map → uploadista-error-Buscq-FR.mjs.map} +1 -1
  56. package/dist/{uploadista-error-CBkvsyZ3.d.mts → uploadista-error-DUWw6OqS.d.mts} +1 -1
  57. package/dist/{uploadista-error-CBkvsyZ3.d.mts.map → uploadista-error-DUWw6OqS.d.mts.map} +1 -1
  58. package/dist/utils/index.d.cts +2 -2
  59. package/dist/utils/index.d.mts +2 -2
  60. package/dist/utils/index.mjs +1 -1
  61. package/dist/{utils-BicUw_lt.mjs → utils-BWiu6lqv.mjs} +2 -2
  62. package/dist/{utils-BicUw_lt.mjs.map → utils-BWiu6lqv.mjs.map} +1 -1
  63. package/package.json +14 -6
  64. package/src/flow/node.ts +4 -4
  65. package/src/flow/nodes/transform-node.ts +23 -2
  66. package/src/flow/plugins/credential-provider.ts +1 -1
  67. package/src/flow/plugins/image-ai-plugin.ts +1 -1
  68. package/src/flow/plugins/image-plugin.ts +1 -1
  69. package/src/flow/plugins/video-plugin.ts +1 -1
  70. package/src/flow/plugins/zip-plugin.ts +1 -1
  71. package/src/flow/types/type-utils.ts +14 -3
  72. package/src/testing/index.ts +14 -0
  73. package/src/testing/mock-image-ai-plugin.ts +33 -0
  74. package/src/testing/mock-image-plugin.ts +56 -0
  75. package/src/testing/mock-upload-server.ts +176 -0
  76. package/src/testing/mock-video-plugin.ts +94 -0
  77. package/src/testing/mock-zip-plugin.ts +41 -0
  78. package/src/types/data-store.ts +1 -1
  79. package/{src/errors/__tests__ → tests/errors}/uploadista-error.test.ts +23 -19
  80. package/{src → tests}/flow/edge.test.ts +1 -1
  81. package/tests/flow/flow.test.ts +853 -0
  82. package/tests/flow/node.test.ts +757 -0
  83. package/{src → tests}/streams/stream-limiter.test.ts +2 -2
  84. package/tests/types/typed-event-emitter.test.ts +282 -0
  85. package/{src → tests}/utils/debounce.test.ts +1 -1
  86. package/{src → tests}/utils/once.test.ts +1 -1
  87. package/tests/utils/test-layers.ts +183 -0
  88. package/{src → tests}/utils/throttle.test.ts +1 -1
  89. package/tsdown.config.ts +1 -0
  90. package/type-tests/flow.test-d.ts +93 -0
  91. package/type-tests/type-utils.test-d.ts +104 -51
  92. package/vitest.config.ts +19 -1
  93. package/dist/flow-IgE8hj7H.mjs.map +0 -1
  94. package/dist/index-CrZopnP9.d.cts.map +0 -1
  95. package/dist/index-DHt7Ht_J.d.mts.map +0 -1
  96. package/dist/index-DubOIur4.d.cts.map +0 -1
  97. package/dist/types-DGZ892my.mjs.map +0 -1
  98. /package/dist/{errors-C0zLx77t.mjs → errors-DEFjN-xn.mjs} +0 -0
  99. /package/dist/{index-BtBZHVmz.d.cts → index-C-svZlpj.d.mts} +0 -0
  100. /package/dist/{index-DEHBdV_z.d.mts → index-_wQ5ClJU.d.cts} +0 -0
  101. /package/dist/{streams-CJKKIAwy.mjs → streams-DPU17bYp.mjs} +0 -0
@@ -8,6 +8,25 @@
8
8
 
9
9
  import { Effect, Layer } from "effect";
10
10
  import { expectType } from "tsd";
11
+
12
+ import {
13
+ type UploadistaError,
14
+ VideoPlugin,
15
+ type ZipInput,
16
+ type ZipParams,
17
+ ZipPlugin,
18
+ } from "../src";
19
+ import { ImagePlugin } from "../src/flow/plugins/image-plugin";
20
+ import type {
21
+ DescribeVideoMetadata,
22
+ ExtractFrameVideoParams,
23
+ ResizeParams,
24
+ ResizeVideoParams,
25
+ TranscodeVideoParams,
26
+ TrimVideoParams,
27
+ } from "../src/flow/plugins/types";
28
+ import type { OptimizeParams } from "../src/flow/plugins/types/optimize-node";
29
+ import type { Transformation } from "../src/flow/plugins/types/transform-image-node";
11
30
  import type {
12
31
  ExtractEffectError,
13
32
  ExtractEffectRequirements,
@@ -20,69 +39,87 @@ import type {
20
39
  // Test Services and Layers
21
40
  // ============================================================================
22
41
 
23
- class ImageService {
24
- readonly _tag = "ImageService";
25
- resize(data: Buffer, width: number): Buffer {
26
- return data;
27
- }
28
- }
29
-
30
- class ZipService {
31
- readonly _tag = "ZipService";
32
- compress(files: Buffer[]): Buffer {
33
- return Buffer.from([]);
34
- }
35
- }
36
-
37
- class LogService {
38
- readonly _tag = "LogService";
39
- log(message: string): void {
40
- console.log(message);
41
- }
42
- }
43
-
44
42
  // Create test layers
45
- const ImageLayer = Layer.succeed(ImageService, new ImageService());
46
- const ZipLayer = Layer.succeed(ZipService, new ZipService());
47
- const LogLayer = Layer.succeed(LogService, new LogService());
43
+ const ImageLayer = Layer.succeed(
44
+ ImagePlugin,
45
+ ImagePlugin.of({
46
+ optimize: (input: Uint8Array, _options: OptimizeParams) =>
47
+ Effect.succeed(input),
48
+ resize: (input: Uint8Array, _options: ResizeParams) =>
49
+ Effect.succeed(input),
50
+ transform: (input: Uint8Array, _options: Transformation) =>
51
+ Effect.succeed(input),
52
+ }),
53
+ );
54
+ const ZipLayer = Layer.succeed(
55
+ ZipPlugin,
56
+ ZipPlugin.of({
57
+ zip: (_inputs: ZipInput[], _options: ZipParams) =>
58
+ Effect.succeed(new Uint8Array([])),
59
+ }),
60
+ );
61
+ const VideoLayer = Layer.succeed(
62
+ VideoPlugin,
63
+ VideoPlugin.of({
64
+ transcode: (input: Uint8Array, _options: TranscodeVideoParams) =>
65
+ Effect.succeed(input),
66
+ resize: (input: Uint8Array, _options: ResizeVideoParams) =>
67
+ Effect.succeed(input),
68
+ trim: (input: Uint8Array, _options: TrimVideoParams) =>
69
+ Effect.succeed(input),
70
+ extractFrame: (
71
+ _input: Uint8Array,
72
+ _options: ExtractFrameVideoParams,
73
+ ): Effect.Effect<Uint8Array, UploadistaError> => {
74
+ throw new Error("Function not implemented.");
75
+ },
76
+ describe: (
77
+ _input: Uint8Array,
78
+ ): Effect.Effect<DescribeVideoMetadata, UploadistaError> => {
79
+ throw new Error("Function not implemented.");
80
+ },
81
+ }),
82
+ );
48
83
 
49
84
  // ============================================================================
50
85
  // ExtractLayerService Tests
51
86
  // ============================================================================
52
87
 
53
88
  // Test: Should extract service from a single layer
54
- expectType<ImageService>({} as ExtractLayerService<typeof ImageLayer>);
89
+ expectType<ImagePlugin>({} as ExtractLayerService<typeof ImageLayer>);
55
90
 
56
- expectType<ZipService>({} as ExtractLayerService<typeof ZipLayer>);
91
+ expectType<ZipPlugin>({} as ExtractLayerService<typeof ZipLayer>);
57
92
 
58
93
  // Test: Should return never for non-layer types
59
94
  expectType<never>({} as ExtractLayerService<string>);
60
95
  expectType<never>({} as ExtractLayerService<number>);
61
- expectType<never>({} as ExtractLayerService<{}>);
96
+ expectType<never>({} as ExtractLayerService<Record<string, never>>);
62
97
 
63
98
  // ============================================================================
64
99
  // ExtractLayerServices Tests
65
100
  // ============================================================================
66
101
 
67
102
  // Test: Should extract union of services from layer tuple
68
- expectType<ImageService | ZipService>(
103
+ expectType<ImagePlugin | ZipPlugin>(
69
104
  {} as ExtractLayerServices<[typeof ImageLayer, typeof ZipLayer]>,
70
105
  );
71
106
 
72
- expectType<ImageService | ZipService | LogService>(
107
+ expectType<ImagePlugin | ZipPlugin | VideoPlugin>(
73
108
  {} as ExtractLayerServices<
74
- [typeof ImageLayer, typeof ZipLayer, typeof LogLayer]
109
+ [typeof ImageLayer, typeof ZipLayer, typeof VideoLayer]
75
110
  >,
76
111
  );
77
112
 
78
113
  // Test: Should handle single layer in tuple
79
- expectType<ImageService>({} as ExtractLayerServices<[typeof ImageLayer]>);
114
+ expectType<ImagePlugin>({} as ExtractLayerServices<[typeof ImageLayer]>);
80
115
 
81
116
  // Test: Should return never for empty tuple
82
- expectType<never>({} as ExtractLayerServices<[]>);
117
+ type EmptyTuple = [];
118
+ type EmptyTupleExtracted = ExtractLayerServices<EmptyTuple>;
119
+ expectType<never>({} as EmptyTupleExtracted);
83
120
 
84
121
  // Test: Should work with readonly arrays
85
- expectType<ImageService | ZipService>(
122
+ expectType<ImagePlugin | ZipPlugin>(
86
123
  {} as ExtractLayerServices<readonly [typeof ImageLayer, typeof ZipLayer]>,
87
124
  );
88
125
 
@@ -95,14 +132,14 @@ expectType<string>({} as ResolveEffect<Effect.Effect<string, Error, never>>);
95
132
 
96
133
  expectType<number>({} as ResolveEffect<Effect.Effect<number, never, never>>);
97
134
 
98
- expectType<ImageService>(
99
- {} as ResolveEffect<Effect.Effect<ImageService, Error, ZipService>>,
135
+ expectType<ImagePlugin>(
136
+ {} as ResolveEffect<Effect.Effect<ImagePlugin, Error, ImagePlugin>>,
100
137
  );
101
138
 
102
139
  // Test: Should return the type itself if not an Effect
103
140
  expectType<string>({} as ResolveEffect<string>);
104
141
  expectType<number>({} as ResolveEffect<number>);
105
- expectType<ImageService>({} as ResolveEffect<ImageService>);
142
+ expectType<ImagePlugin>({} as ResolveEffect<ImagePlugin>);
106
143
 
107
144
  // Test: Should work with nested structures
108
145
  expectType<{ data: string }>(
@@ -141,12 +178,12 @@ expectType<Error | TypeError>(
141
178
  // ============================================================================
142
179
 
143
180
  // Test: Should extract requirements type from Effect
144
- expectType<ImageService>(
145
- {} as ExtractEffectRequirements<Effect.Effect<string, Error, ImageService>>,
181
+ expectType<ImagePlugin>(
182
+ {} as ExtractEffectRequirements<Effect.Effect<string, Error, ImagePlugin>>,
146
183
  );
147
184
 
148
- expectType<ZipService>(
149
- {} as ExtractEffectRequirements<Effect.Effect<number, never, ZipService>>,
185
+ expectType<ZipPlugin>(
186
+ {} as ExtractEffectRequirements<Effect.Effect<number, never, ZipPlugin>>,
150
187
  );
151
188
 
152
189
  // Test: Should extract never for Effects with no requirements
@@ -159,20 +196,20 @@ expectType<never>({} as ExtractEffectRequirements<string>);
159
196
  expectType<never>({} as ExtractEffectRequirements<number>);
160
197
 
161
198
  // Test: Should handle union requirement types
162
- expectType<ImageService | ZipService>(
199
+ expectType<ImagePlugin | ZipPlugin>(
163
200
  {} as ExtractEffectRequirements<
164
- Effect.Effect<string, Error, ImageService | ZipService>
201
+ Effect.Effect<string, Error, ImagePlugin | ZipPlugin>
165
202
  >,
166
203
  );
167
204
 
168
205
  // Test: Should work with complex Effect chains
169
206
  const complexEffect = Effect.gen(function* () {
170
- const imageService = yield* ImageService;
171
- const zipService = yield* ZipService;
207
+ const imageService = yield* ImagePlugin;
208
+ const zipService = yield* ZipPlugin;
172
209
  return { imageService, zipService };
173
210
  });
174
211
 
175
- expectType<ImageService | ZipService>(
212
+ expectType<ImagePlugin | ZipPlugin>(
176
213
  {} as ExtractEffectRequirements<typeof complexEffect>,
177
214
  );
178
215
 
@@ -184,19 +221,29 @@ expectType<ImageService | ZipService>(
184
221
  const pluginLayers = [ImageLayer, ZipLayer] as const;
185
222
 
186
223
  type PluginServices = ExtractLayerServices<typeof pluginLayers>;
187
- expectType<ImageService | ZipService>({} as PluginServices);
224
+ expectType<ImagePlugin | ZipPlugin>({} as PluginServices);
188
225
 
189
226
  // Test: Realistic flow scenario - validate Effect requirements match plugins
190
- type FlowEffect = Effect.Effect<Buffer, Error, ImageService | ZipService>;
227
+ type FlowEffect = Effect.Effect<Buffer, Error, ImagePlugin | ZipPlugin>;
191
228
  type FlowRequirements = ExtractEffectRequirements<FlowEffect>;
192
229
 
230
+ // Debug: Check if both types are the same
231
+ type DebugPluginServices = PluginServices;
232
+ type DebugFlowRequirements = FlowRequirements;
233
+
234
+ // Both should be ImagePlugin | ZipPlugin
235
+ expectType<ImagePlugin | ZipPlugin>({} as DebugPluginServices);
236
+ expectType<ImagePlugin | ZipPlugin>({} as DebugFlowRequirements);
237
+
193
238
  // This should compile: flow requirements are subset of plugin services
194
- type ValidationTest = FlowRequirements extends PluginServices ? true : false;
239
+ // Note: This tests that the union is compatible
240
+ type ValidationTest =
241
+ [FlowRequirements] extends [PluginServices] ? true : false;
195
242
  expectType<true>({} as ValidationTest);
196
243
 
197
244
  // Test: Should detect missing requirements
198
245
  type IncompletePlugins = ExtractLayerServices<[typeof ImageLayer]>;
199
- type MissingTest = ImageService | ZipService extends IncompletePlugins
246
+ type MissingTest = ImagePlugin | ZipPlugin extends IncompletePlugins
200
247
  ? true
201
248
  : false;
202
249
  expectType<false>({} as MissingTest);
@@ -229,7 +276,13 @@ expectType<Promise<string>>(
229
276
  function genericTest<T>() {
230
277
  expectType<T>({} as ResolveEffect<Effect.Effect<T, Error, never>>);
231
278
  expectType<Error>({} as ExtractEffectError<Effect.Effect<T, Error, never>>);
232
- expectType<ImageService>(
233
- {} as ExtractEffectRequirements<Effect.Effect<T, Error, ImageService>>,
279
+ expectType<ImagePlugin>(
280
+ {} as ExtractEffectRequirements<Effect.Effect<T, Error, ImagePlugin>>,
234
281
  );
235
282
  }
283
+
284
+ genericTest<string>();
285
+ genericTest<number>();
286
+ genericTest<ImagePlugin>();
287
+ genericTest<ZipPlugin>();
288
+ genericTest<VideoPlugin>();
package/vitest.config.ts CHANGED
@@ -1,10 +1,27 @@
1
1
  import { defineConfig } from "vitest/config";
2
2
 
3
+ /**
4
+ * Shared vitest configuration template for uploadista-sdk packages
5
+ *
6
+ * This template should be used by all SDK packages to ensure consistent
7
+ * testing configuration across the monorepo.
8
+ *
9
+ * Key features:
10
+ * - Tests in dedicated `tests/` directories (not colocated with src)
11
+ * - Node environment for server-side code
12
+ * - V8 coverage provider
13
+ * - Global test functions available
14
+ * - Effect testing support via @effect/vitest
15
+ *
16
+ * Usage:
17
+ * Copy this file to your package root as `vitest.config.ts` and customize
18
+ * if needed (though most packages should use this as-is).
19
+ */
3
20
  export default defineConfig({
4
21
  test: {
5
22
  globals: true,
6
23
  environment: "node",
7
- include: ["src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
24
+ include: ["tests/**/*.test.ts"],
8
25
  exclude: ["node_modules", "dist"],
9
26
  coverage: {
10
27
  provider: "v8",
@@ -15,6 +32,7 @@ export default defineConfig({
15
32
  "**/*.d.ts",
16
33
  "**/*.test.ts",
17
34
  "**/*.spec.ts",
35
+ "tests/",
18
36
  ],
19
37
  },
20
38
  },