nuxt-upload-kit 0.1.1

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 (38) hide show
  1. package/README.md +171 -0
  2. package/dist/module.d.mts +14 -0
  3. package/dist/module.json +9 -0
  4. package/dist/module.mjs +29 -0
  5. package/dist/runtime/composables/useFFMpeg.d.ts +14 -0
  6. package/dist/runtime/composables/useFFMpeg.js +66 -0
  7. package/dist/runtime/composables/useUploadKit/index.d.ts +471 -0
  8. package/dist/runtime/composables/useUploadKit/index.js +486 -0
  9. package/dist/runtime/composables/useUploadKit/plugins/image-compressor.d.ts +56 -0
  10. package/dist/runtime/composables/useUploadKit/plugins/image-compressor.js +137 -0
  11. package/dist/runtime/composables/useUploadKit/plugins/index.d.ts +4 -0
  12. package/dist/runtime/composables/useUploadKit/plugins/index.js +4 -0
  13. package/dist/runtime/composables/useUploadKit/plugins/storage/azure-datalake.d.ts +55 -0
  14. package/dist/runtime/composables/useUploadKit/plugins/storage/azure-datalake.js +137 -0
  15. package/dist/runtime/composables/useUploadKit/plugins/storage/index.d.ts +10 -0
  16. package/dist/runtime/composables/useUploadKit/plugins/storage/index.js +1 -0
  17. package/dist/runtime/composables/useUploadKit/plugins/thumbnail-generator.d.ts +8 -0
  18. package/dist/runtime/composables/useUploadKit/plugins/thumbnail-generator.js +99 -0
  19. package/dist/runtime/composables/useUploadKit/plugins/video-compressor.d.ts +72 -0
  20. package/dist/runtime/composables/useUploadKit/plugins/video-compressor.js +111 -0
  21. package/dist/runtime/composables/useUploadKit/types.d.ts +488 -0
  22. package/dist/runtime/composables/useUploadKit/types.js +9 -0
  23. package/dist/runtime/composables/useUploadKit/utils.d.ts +23 -0
  24. package/dist/runtime/composables/useUploadKit/utils.js +45 -0
  25. package/dist/runtime/composables/useUploadKit/validators/allowed-file-types.d.ts +5 -0
  26. package/dist/runtime/composables/useUploadKit/validators/allowed-file-types.js +17 -0
  27. package/dist/runtime/composables/useUploadKit/validators/duplicate-file.d.ts +13 -0
  28. package/dist/runtime/composables/useUploadKit/validators/duplicate-file.js +27 -0
  29. package/dist/runtime/composables/useUploadKit/validators/index.d.ts +4 -0
  30. package/dist/runtime/composables/useUploadKit/validators/index.js +4 -0
  31. package/dist/runtime/composables/useUploadKit/validators/max-file-size.d.ts +5 -0
  32. package/dist/runtime/composables/useUploadKit/validators/max-file-size.js +17 -0
  33. package/dist/runtime/composables/useUploadKit/validators/max-files.d.ts +5 -0
  34. package/dist/runtime/composables/useUploadKit/validators/max-files.js +17 -0
  35. package/dist/runtime/types/index.d.ts +3 -0
  36. package/dist/runtime/types/index.js +3 -0
  37. package/dist/types.d.mts +5 -0
  38. package/package.json +84 -0
package/README.md ADDED
@@ -0,0 +1,171 @@
1
+ <p align="center">
2
+ <img src="docs/public/logo.png" alt="Nuxt Upload Kit" width="300" />
3
+ </p>
4
+
5
+ <h1 align="center">Nuxt Upload Kit</h1>
6
+
7
+ <p align="center">A powerful, plugin-based file upload manager for Nuxt applications.</p>
8
+
9
+ ## Features
10
+
11
+ - 🔌 **Plugin System** - Extensible architecture with built-in plugins for validation, compression, and storage
12
+ - 📤 **Multi-provider Storage** - Azure Data Lake support with S3, Cloudinary coming soon
13
+ - 🖼️ **Image Processing** - Automatic thumbnail generation and image compression
14
+ - 🎥 **Video Compression** - FFmpeg-powered video compression (optional)
15
+ - ✅ **Validation** - File type, size, and count validation out of the box
16
+ - 📊 **Progress Tracking** - Real-time upload progress with events
17
+ - 🔄 **File Lifecycle** - Complete control over file preprocessing, processing, and post-upload
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ pnpm add nuxt-upload-kit
23
+ # or
24
+ npm install nuxt-upload-kit
25
+ # or
26
+ yarn add nuxt-upload-kit
27
+ ```
28
+
29
+ ## Setup
30
+
31
+ Add the module to your `nuxt.config.ts`:
32
+
33
+ ```typescript
34
+ export default defineNuxtConfig({
35
+ modules: ["nuxt-upload-kit"],
36
+ })
37
+ ```
38
+
39
+ ## Quick Start
40
+
41
+ ```vue
42
+ <script setup lang="ts">
43
+ const uploader = useUploadKit({
44
+ maxFiles: 10,
45
+ maxFileSize: 50 * 1024 * 1024, // 50MB
46
+ allowedFileTypes: ["image/jpeg", "image/png", "video/mp4"],
47
+ thumbnails: true,
48
+ imageCompression: {
49
+ maxWidth: 1920,
50
+ quality: 0.85,
51
+ },
52
+ })
53
+
54
+ // Configure upload handler
55
+ uploader.onUpload(async (file, onProgress) => {
56
+ const formData = new FormData()
57
+ formData.append("file", file.data as Blob)
58
+
59
+ const response = await fetch("/api/upload", {
60
+ method: "POST",
61
+ body: formData,
62
+ })
63
+
64
+ return await response.json()
65
+ })
66
+
67
+ // Add files
68
+ const onFileSelect = async (event: Event) => {
69
+ const input = event.target as HTMLInputElement
70
+ if (input.files) {
71
+ await uploader.addFiles(Array.from(input.files))
72
+ }
73
+ }
74
+
75
+ // Upload all files
76
+ const handleUpload = () => uploader.upload()
77
+ </script>
78
+
79
+ <template>
80
+ <div>
81
+ <input type="file" multiple @change="onFileSelect" />
82
+
83
+ <div v-for="file in uploader.files" :key="file.id">
84
+ <img v-if="file.preview" :src="file.preview" />
85
+ <span>{{ file.name }} - {{ file.status }}</span>
86
+ <progress :value="file.progress.percentage" max="100" />
87
+ </div>
88
+
89
+ <button @click="handleUpload">Upload</button>
90
+ </div>
91
+ </template>
92
+ ```
93
+
94
+ ## Using Storage Plugins
95
+
96
+ ### Azure Data Lake Storage
97
+
98
+ ```typescript
99
+ import { PluginAzureDataLake } from "nuxt-upload-kit"
100
+
101
+ const uploader = useUploadKit({
102
+ storage: PluginAzureDataLake({
103
+ sasURL: "https://your-storage.blob.core.windows.net/container?sv=...",
104
+ path: "uploads/images",
105
+ }),
106
+ thumbnails: true,
107
+ })
108
+ ```
109
+
110
+ ## Configuration Options
111
+
112
+ | Option | Type | Default | Description |
113
+ | ------------------ | ------------------------------- | ------- | ------------------------------- |
114
+ | `storage` | `StoragePlugin` | - | Storage plugin for file uploads |
115
+ | `plugins` | `ProcessingPlugin[]` | `[]` | Additional processing plugins |
116
+ | `maxFiles` | `number \| false` | `false` | Maximum number of files |
117
+ | `maxFileSize` | `number \| false` | `false` | Maximum file size in bytes |
118
+ | `allowedFileTypes` | `string[] \| false` | `false` | Allowed MIME types |
119
+ | `thumbnails` | `boolean \| ThumbnailOptions` | `false` | Enable thumbnail generation |
120
+ | `imageCompression` | `boolean \| CompressionOptions` | `false` | Enable image compression |
121
+ | `autoProceed` | `boolean` | `false` | Auto-upload after adding files |
122
+
123
+ ## Events
124
+
125
+ ```typescript
126
+ uploader.on("file:added", (file) => console.log("Added:", file.name))
127
+ uploader.on("file:removed", (file) => console.log("Removed:", file.name))
128
+ uploader.on("file:error", ({ file, error }) => console.error(error))
129
+ uploader.on("upload:start", (files) => console.log("Starting upload"))
130
+ uploader.on("upload:progress", ({ file, progress }) => console.log(progress))
131
+ uploader.on("upload:complete", (files) => console.log("Complete!"))
132
+ ```
133
+
134
+ ## Creating Custom Plugins
135
+
136
+ ```typescript
137
+ import { defineProcessingPlugin } from "nuxt-upload-kit"
138
+
139
+ const MyPlugin = defineProcessingPlugin<{ option: string }>((options) => ({
140
+ id: "my-plugin",
141
+ hooks: {
142
+ validate: async (file, context) => {
143
+ // Validation logic
144
+ return file
145
+ },
146
+ process: async (file, context) => {
147
+ // Processing logic
148
+ context.emit("processed", { file })
149
+ return file
150
+ },
151
+ },
152
+ }))
153
+ ```
154
+
155
+ ## Optional Dependencies
156
+
157
+ For video compression, install FFmpeg:
158
+
159
+ ```bash
160
+ pnpm add @ffmpeg/ffmpeg @ffmpeg/util
161
+ ```
162
+
163
+ For Azure storage, install the Azure SDK:
164
+
165
+ ```bash
166
+ pnpm add @azure/storage-file-datalake
167
+ ```
168
+
169
+ ## License
170
+
171
+ MIT
@@ -0,0 +1,14 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+ export * from '../dist/runtime/types/index.js';
3
+
4
+ interface ModuleOptions {
5
+ /**
6
+ * Enable auto-import of useUploadKit composable
7
+ * @default true
8
+ */
9
+ autoImport?: boolean;
10
+ }
11
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
12
+
13
+ export { _default as default };
14
+ export type { ModuleOptions };
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "nuxt-upload-kit",
3
+ "configKey": "uploadKit",
4
+ "version": "0.1.1",
5
+ "builder": {
6
+ "@nuxt/module-builder": "1.0.2",
7
+ "unbuild": "unknown"
8
+ }
9
+ }
@@ -0,0 +1,29 @@
1
+ import { defineNuxtModule, createResolver, addImports } from '@nuxt/kit';
2
+
3
+ const module$1 = defineNuxtModule({
4
+ meta: {
5
+ name: "nuxt-upload-kit",
6
+ configKey: "uploadKit"
7
+ },
8
+ defaults: {
9
+ autoImport: true
10
+ },
11
+ setup(options, _nuxt) {
12
+ const resolver = createResolver(import.meta.url);
13
+ if (options.autoImport) {
14
+ addImports([
15
+ {
16
+ name: "useUploadKit",
17
+ from: resolver.resolve("./runtime/composables/useUploadKit")
18
+ },
19
+ {
20
+ name: "useFFMpeg",
21
+ from: resolver.resolve("./runtime/composables/useFFMpeg")
22
+ }
23
+ ]);
24
+ }
25
+ _nuxt.options.alias["#upload-kit"] = resolver.resolve("./runtime");
26
+ }
27
+ });
28
+
29
+ export { module$1 as default };
@@ -0,0 +1,14 @@
1
+ interface FFMPegOptions {
2
+ inputUrl: string;
3
+ convertOptions?: string[];
4
+ }
5
+ export declare const useFFMpeg: (options: FFMPegOptions) => {
6
+ status: import("@vue/reactivity").Ref<"paused" | "converting" | "success" | "error", "paused" | "converting" | "success" | "error">;
7
+ progress: import("@vue/reactivity").Ref<number, number>;
8
+ convertedFile: import("@vue/reactivity").Ref<File | undefined, File | undefined>;
9
+ load: () => Promise<void>;
10
+ unload: () => void;
11
+ convert: (convertOptions: string[]) => Promise<File | undefined>;
12
+ onConvertSuccess: (callback: (updatedVideo: File) => void) => (updatedVideo: File) => void;
13
+ };
14
+ export {};
@@ -0,0 +1,66 @@
1
+ import { FFmpeg } from "@ffmpeg/ffmpeg";
2
+ import { fetchFile, toBlobURL } from "@ffmpeg/util";
3
+ import { ref } from "vue";
4
+ const defaultOptions = {
5
+ convertOptions: []
6
+ };
7
+ const baseURL = "https://unpkg.com/@ffmpeg/core@0.12.6/dist/esm";
8
+ export const useFFMpeg = (options) => {
9
+ options = { ...defaultOptions, ...options };
10
+ const ffmpeg = new FFmpeg();
11
+ const status = ref("paused");
12
+ const progress = ref(0);
13
+ const originalFile = ref();
14
+ const convertedFile = ref();
15
+ let _onConvertSuccess;
16
+ ffmpeg.on("progress", ({ time }) => {
17
+ progress.value = time / 1e6;
18
+ });
19
+ const load = async () => {
20
+ await ffmpeg.load({
21
+ coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, "text/javascript"),
22
+ wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`, "application/wasm")
23
+ });
24
+ };
25
+ const unload = () => ffmpeg.terminate();
26
+ const convert = async (convertOptions) => {
27
+ status.value = "converting";
28
+ const command = ["-i", "input.avi", ...options.convertOptions, ...convertOptions, "-c", "copy", "output.mp4"];
29
+ try {
30
+ originalFile.value = await fetchFile(options.inputUrl);
31
+ await ffmpeg.writeFile("input.avi", originalFile.value);
32
+ await ffmpeg.exec(command);
33
+ convertedFile.value = await getModifiedVideo();
34
+ await ffmpeg.deleteFile("input.avi");
35
+ status.value = "success";
36
+ if (_onConvertSuccess) _onConvertSuccess(convertedFile.value);
37
+ return convertedFile.value;
38
+ } catch (error) {
39
+ if (import.meta.env.DEV) console.error(error);
40
+ status.value = "error";
41
+ }
42
+ };
43
+ const getModifiedVideo = async () => {
44
+ const data = await ffmpeg.readFile("output.mp4");
45
+ let bytes;
46
+ if (typeof data === "string") {
47
+ bytes = new TextEncoder().encode(data);
48
+ } else {
49
+ const buffer = new ArrayBuffer(data.byteLength);
50
+ new Uint8Array(buffer).set(data);
51
+ bytes = new Uint8Array(buffer);
52
+ }
53
+ const updatedFile = new File([bytes], "output.mp4", { type: "video/mp4" });
54
+ return updatedFile;
55
+ };
56
+ const onConvertSuccess = (callback) => _onConvertSuccess = callback;
57
+ return {
58
+ status,
59
+ progress,
60
+ convertedFile,
61
+ load,
62
+ unload,
63
+ convert,
64
+ onConvertSuccess
65
+ };
66
+ };