@igorvaryvoda/sirv-upload-widget 0.1.0

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 (2) hide show
  1. package/README.md +185 -0
  2. package/package.json +77 -0
package/README.md ADDED
@@ -0,0 +1,185 @@
1
+ # @sirv/upload-widget
2
+
3
+ A React file upload widget for [Sirv CDN](https://sirv.com) with batch uploads, CSV/Excel import, and file browser.
4
+
5
+ ## Features
6
+
7
+ - **Drag & drop** file upload with progress tracking
8
+ - **Batch uploads** with configurable concurrency
9
+ - **CSV/Excel import** for bulk URL imports
10
+ - **Sirv file picker** to browse existing files
11
+ - **HEIC/HEIF conversion** for iPhone photos
12
+ - **Presigned URL support** for secure direct uploads
13
+ - **Customizable styling** via CSS variables
14
+ - **TypeScript** support with full type definitions
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @sirv/upload-widget
20
+ # or
21
+ yarn add @sirv/upload-widget
22
+ # or
23
+ pnpm add @sirv/upload-widget
24
+ ```
25
+
26
+ ## Quick Start
27
+
28
+ ### 1. Create a presign endpoint on your backend
29
+
30
+ The widget uploads directly to Sirv using presigned URLs. Your backend just needs one endpoint:
31
+
32
+ ```typescript
33
+ // app/api/sirv/presign/route.ts (Next.js)
34
+ import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'
35
+ import { getSignedUrl } from '@aws-sdk/s3-request-presigner'
36
+
37
+ const s3 = new S3Client({
38
+ endpoint: 'https://s3.sirv.com',
39
+ region: 'us-east-1',
40
+ credentials: {
41
+ accessKeyId: process.env.SIRV_S3_KEY!,
42
+ secretAccessKey: process.env.SIRV_S3_SECRET!,
43
+ },
44
+ forcePathStyle: true,
45
+ })
46
+
47
+ export async function POST(req: Request) {
48
+ const { filename, contentType, folder } = await req.json()
49
+ const key = `${folder}/${filename}`.replace(/^\/+/, '')
50
+
51
+ const uploadUrl = await getSignedUrl(s3, new PutObjectCommand({
52
+ Bucket: process.env.SIRV_BUCKET!,
53
+ Key: key,
54
+ ContentType: contentType,
55
+ }), { expiresIn: 300 })
56
+
57
+ return Response.json({
58
+ uploadUrl,
59
+ publicUrl: `https://${process.env.SIRV_BUCKET}.sirv.com/${key}`,
60
+ path: '/' + key,
61
+ })
62
+ }
63
+ ```
64
+
65
+ ### 2. Use the widget in your React app
66
+
67
+ ```tsx
68
+ import { SirvUploader } from '@sirv/upload-widget'
69
+ import '@sirv/upload-widget/styles.css'
70
+
71
+ export default function UploadPage() {
72
+ return (
73
+ <SirvUploader
74
+ presignEndpoint="/api/sirv/presign"
75
+ folder="/uploads"
76
+ onUpload={(files) => {
77
+ console.log('Uploaded files:', files)
78
+ }}
79
+ />
80
+ )
81
+ }
82
+ ```
83
+
84
+ ## Props
85
+
86
+ | Prop | Type | Default | Description |
87
+ |------|------|---------|-------------|
88
+ | `presignEndpoint` | `string` | - | **Recommended.** URL to get presigned upload URLs |
89
+ | `proxyEndpoint` | `string` | - | Alternative: URL for full proxy mode |
90
+ | `folder` | `string` | `"/"` | Default upload folder |
91
+ | `onUpload` | `(files: SirvFile[]) => void` | - | Callback when files are uploaded |
92
+ | `onError` | `(error: string, file?: SirvFile) => void` | - | Callback on upload errors |
93
+ | `features` | `object` | - | Enable/disable features (see below) |
94
+ | `maxFiles` | `number` | `50` | Maximum files for batch upload |
95
+ | `maxFileSize` | `number` | `10485760` | Maximum file size in bytes |
96
+ | `autoUpload` | `boolean` | `true` | Start upload immediately on file selection |
97
+ | `concurrency` | `number` | `3` | Number of concurrent uploads |
98
+ | `onConflict` | `'overwrite' \| 'rename' \| 'skip' \| 'ask'` | `'rename'` | Filename conflict handling |
99
+ | `disabled` | `boolean` | `false` | Disable the widget |
100
+ | `compact` | `boolean` | `false` | Compact mode for smaller spaces |
101
+ | `labels` | `object` | - | Custom labels for i18n |
102
+ | `className` | `string` | - | Custom CSS class |
103
+
104
+ ### Features Object
105
+
106
+ ```typescript
107
+ features?: {
108
+ batch?: boolean // Enable batch upload (default: true)
109
+ csvImport?: boolean // Enable CSV/Excel import (default: true)
110
+ filePicker?: boolean // Enable Sirv file browser (default: true)
111
+ dragDrop?: boolean // Enable drag & drop (default: true)
112
+ }
113
+ ```
114
+
115
+ ## Styling
116
+
117
+ Customize the widget using CSS variables:
118
+
119
+ ```css
120
+ .sirv-uploader {
121
+ --sirv-primary: #0066cc;
122
+ --sirv-primary-hover: #0052a3;
123
+ --sirv-bg: #ffffff;
124
+ --sirv-text: #1e293b;
125
+ --sirv-border: #e2e8f0;
126
+ --sirv-radius: 8px;
127
+ /* ... see styles.css for all variables */
128
+ }
129
+ ```
130
+
131
+ ## Individual Components
132
+
133
+ For custom layouts, you can use the components individually:
134
+
135
+ ```tsx
136
+ import {
137
+ DropZone,
138
+ FileList,
139
+ FilePicker,
140
+ SpreadsheetImport,
141
+ useSirvUpload,
142
+ } from '@sirv/upload-widget'
143
+ ```
144
+
145
+ ## TypeScript
146
+
147
+ Full TypeScript support with exported types:
148
+
149
+ ```typescript
150
+ import type {
151
+ SirvFile,
152
+ SirvUploaderProps,
153
+ PresignRequest,
154
+ PresignResponse,
155
+ } from '@sirv/upload-widget'
156
+ ```
157
+
158
+ ## Backend Examples
159
+
160
+ ### Cloudflare Workers (One-Click Deploy)
161
+
162
+ [![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/IgorVaryvoda/sirv-uploader/tree/main/examples/cloudflare-worker)
163
+
164
+ You'll be prompted for your Sirv account name and S3 credentials during deployment.
165
+
166
+ ### Other Examples
167
+
168
+ See the `/examples` folder for:
169
+ - `cloudflare-worker/` - Cloudflare Workers (with deploy button)
170
+ - `nextjs-presign.ts` - Next.js API route
171
+ - `express-presign.ts` - Express.js server
172
+
173
+ ## How It Works
174
+
175
+ 1. User selects files in the widget
176
+ 2. Widget requests a presigned URL from your backend
177
+ 3. Your backend generates the URL using AWS SDK with Sirv's S3 endpoint
178
+ 4. Widget uploads directly to Sirv using the presigned URL
179
+ 5. File is available at `https://youraccount.sirv.com/path/to/file.jpg`
180
+
181
+ This approach keeps your Sirv credentials secure on the server while allowing fast, direct uploads from the browser.
182
+
183
+ ## License
184
+
185
+ MIT
package/package.json ADDED
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "@igorvaryvoda/sirv-upload-widget",
3
+ "version": "0.1.0",
4
+ "description": "A React file upload widget for Sirv CDN with batch uploads, CSV/Excel import, and file browser",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ },
14
+ "./styles.css": "./dist/styles.css"
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "sideEffects": [
20
+ "*.css"
21
+ ],
22
+ "scripts": {
23
+ "build": "tsup",
24
+ "dev": "tsup --watch",
25
+ "typecheck": "tsc --noEmit",
26
+ "clean": "rm -rf dist",
27
+ "test": "vitest",
28
+ "test:run": "vitest run",
29
+ "test:coverage": "vitest run --coverage"
30
+ },
31
+ "peerDependencies": {
32
+ "react": "^18.0.0 || ^19.0.0",
33
+ "react-dom": "^18.0.0 || ^19.0.0"
34
+ },
35
+ "dependencies": {
36
+ "clsx": "^2.1.0"
37
+ },
38
+ "devDependencies": {
39
+ "@testing-library/dom": "^10.4.1",
40
+ "@testing-library/jest-dom": "^6.9.1",
41
+ "@testing-library/react": "^16.3.2",
42
+ "@types/react": "^19.0.0",
43
+ "@types/react-dom": "^19.0.0",
44
+ "@vitejs/plugin-react": "^5.1.2",
45
+ "jsdom": "^27.4.0",
46
+ "react": "^19.0.0",
47
+ "react-dom": "^19.0.0",
48
+ "tsup": "^8.0.0",
49
+ "typescript": "^5.0.0",
50
+ "vitest": "^4.0.17"
51
+ },
52
+ "optionalDependencies": {
53
+ "exceljs": "^4.4.0",
54
+ "heic2any": "^0.0.4"
55
+ },
56
+ "keywords": [
57
+ "sirv",
58
+ "upload",
59
+ "file-upload",
60
+ "react",
61
+ "cdn",
62
+ "image-upload",
63
+ "batch-upload",
64
+ "csv-import",
65
+ "drag-drop"
66
+ ],
67
+ "author": "Sirv",
68
+ "license": "MIT",
69
+ "publishConfig": {
70
+ "access": "public"
71
+ },
72
+ "repository": {
73
+ "type": "git",
74
+ "url": "https://github.com/sirv/upload-widget"
75
+ },
76
+ "homepage": "https://sirv.com"
77
+ }