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.
- package/README.md +171 -0
- package/dist/module.d.mts +14 -0
- package/dist/module.json +9 -0
- package/dist/module.mjs +29 -0
- package/dist/runtime/composables/useFFMpeg.d.ts +14 -0
- package/dist/runtime/composables/useFFMpeg.js +66 -0
- package/dist/runtime/composables/useUploadKit/index.d.ts +471 -0
- package/dist/runtime/composables/useUploadKit/index.js +486 -0
- package/dist/runtime/composables/useUploadKit/plugins/image-compressor.d.ts +56 -0
- package/dist/runtime/composables/useUploadKit/plugins/image-compressor.js +137 -0
- package/dist/runtime/composables/useUploadKit/plugins/index.d.ts +4 -0
- package/dist/runtime/composables/useUploadKit/plugins/index.js +4 -0
- package/dist/runtime/composables/useUploadKit/plugins/storage/azure-datalake.d.ts +55 -0
- package/dist/runtime/composables/useUploadKit/plugins/storage/azure-datalake.js +137 -0
- package/dist/runtime/composables/useUploadKit/plugins/storage/index.d.ts +10 -0
- package/dist/runtime/composables/useUploadKit/plugins/storage/index.js +1 -0
- package/dist/runtime/composables/useUploadKit/plugins/thumbnail-generator.d.ts +8 -0
- package/dist/runtime/composables/useUploadKit/plugins/thumbnail-generator.js +99 -0
- package/dist/runtime/composables/useUploadKit/plugins/video-compressor.d.ts +72 -0
- package/dist/runtime/composables/useUploadKit/plugins/video-compressor.js +111 -0
- package/dist/runtime/composables/useUploadKit/types.d.ts +488 -0
- package/dist/runtime/composables/useUploadKit/types.js +9 -0
- package/dist/runtime/composables/useUploadKit/utils.d.ts +23 -0
- package/dist/runtime/composables/useUploadKit/utils.js +45 -0
- package/dist/runtime/composables/useUploadKit/validators/allowed-file-types.d.ts +5 -0
- package/dist/runtime/composables/useUploadKit/validators/allowed-file-types.js +17 -0
- package/dist/runtime/composables/useUploadKit/validators/duplicate-file.d.ts +13 -0
- package/dist/runtime/composables/useUploadKit/validators/duplicate-file.js +27 -0
- package/dist/runtime/composables/useUploadKit/validators/index.d.ts +4 -0
- package/dist/runtime/composables/useUploadKit/validators/index.js +4 -0
- package/dist/runtime/composables/useUploadKit/validators/max-file-size.d.ts +5 -0
- package/dist/runtime/composables/useUploadKit/validators/max-file-size.js +17 -0
- package/dist/runtime/composables/useUploadKit/validators/max-files.d.ts +5 -0
- package/dist/runtime/composables/useUploadKit/validators/max-files.js +17 -0
- package/dist/runtime/types/index.d.ts +3 -0
- package/dist/runtime/types/index.js +3 -0
- package/dist/types.d.mts +5 -0
- 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 };
|
package/dist/module.json
ADDED
package/dist/module.mjs
ADDED
|
@@ -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
|
+
};
|