@sanvika/cloudinary 0.1.2 → 0.1.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/dist/client.js ADDED
@@ -0,0 +1,139 @@
1
+ "use client";
2
+
3
+ // src/SanvikaCloudinaryProvider.jsx
4
+ import { createContext, useContext, useMemo } from "react";
5
+ import { jsx } from "react/jsx-runtime";
6
+ var SanvikaCloudinaryContext = createContext(null);
7
+ function SanvikaCloudinaryProvider({ appName, cloudName, uploadPreset = "ml_default", children }) {
8
+ const value = useMemo(
9
+ () => ({ appName, cloudName, uploadPreset }),
10
+ [appName, cloudName, uploadPreset]
11
+ );
12
+ return /* @__PURE__ */ jsx(SanvikaCloudinaryContext.Provider, { value, children });
13
+ }
14
+ function useSanvikaCloudinary() {
15
+ const ctx = useContext(SanvikaCloudinaryContext);
16
+ if (!ctx) {
17
+ throw new Error("useSanvikaCloudinary must be used within a SanvikaCloudinaryProvider");
18
+ }
19
+ return ctx;
20
+ }
21
+
22
+ // src/useCloudinaryUpload.js
23
+ import { useState, useCallback } from "react";
24
+ function useCloudinaryUpload(options = {}) {
25
+ const { folder, resourceType = "image", onProgress } = options;
26
+ const { appName, cloudName, uploadPreset } = useSanvikaCloudinary();
27
+ const [uploading, setUploading] = useState(false);
28
+ const [error, setError] = useState(null);
29
+ const reset = useCallback(() => {
30
+ setError(null);
31
+ setUploading(false);
32
+ }, []);
33
+ const upload = useCallback(
34
+ async (file) => {
35
+ setError(null);
36
+ setUploading(true);
37
+ try {
38
+ const folderPath = folder ? `${appName}/${folder}` : appName;
39
+ const formData = new FormData();
40
+ formData.append("file", file);
41
+ formData.append("upload_preset", uploadPreset);
42
+ formData.append("folder", folderPath);
43
+ const xhr = new XMLHttpRequest();
44
+ const url = `https://api.cloudinary.com/v1_1/${cloudName}/${resourceType}/upload`;
45
+ const result = await new Promise((resolve, reject) => {
46
+ xhr.open("POST", url);
47
+ if (onProgress) {
48
+ xhr.upload.onprogress = (e) => {
49
+ if (e.lengthComputable) onProgress(Math.round(e.loaded / e.total * 100));
50
+ };
51
+ }
52
+ xhr.onload = () => {
53
+ if (xhr.status >= 200 && xhr.status < 300) {
54
+ resolve(JSON.parse(xhr.responseText));
55
+ } else {
56
+ reject(new Error(xhr.responseText || "Upload failed"));
57
+ }
58
+ };
59
+ xhr.onerror = () => reject(new Error("Network error during upload"));
60
+ xhr.send(formData);
61
+ });
62
+ return result;
63
+ } catch (err) {
64
+ const msg = (err == null ? void 0 : err.message) || "Upload failed";
65
+ setError(msg);
66
+ throw err;
67
+ } finally {
68
+ setUploading(false);
69
+ }
70
+ },
71
+ [appName, cloudName, uploadPreset, folder, resourceType, onProgress]
72
+ );
73
+ return { upload, uploading, error, reset };
74
+ }
75
+
76
+ // src/cloudinaryUtils.js
77
+ function isCloudinaryUrl(url) {
78
+ return typeof url === "string" && (url.includes("res.cloudinary.com") || url.includes("cloudinary.com"));
79
+ }
80
+ function extractPublicId(url) {
81
+ if (!isCloudinaryUrl(url)) return null;
82
+ try {
83
+ const parts = url.split("/");
84
+ const uploadIdx = parts.indexOf("upload");
85
+ if (uploadIdx === -1) return null;
86
+ let publicIdPath = parts.slice(uploadIdx + 1).join("/");
87
+ const versionMatch = publicIdPath.match(/^v\d+\//);
88
+ if (versionMatch) {
89
+ publicIdPath = publicIdPath.substring(versionMatch[0].length);
90
+ }
91
+ const lastDot = publicIdPath.lastIndexOf(".");
92
+ if (lastDot !== -1) {
93
+ const ext = publicIdPath.substring(lastDot + 1);
94
+ if (/^[a-zA-Z0-9]{2,5}$/.test(ext)) {
95
+ publicIdPath = publicIdPath.substring(0, lastDot);
96
+ }
97
+ }
98
+ return publicIdPath || null;
99
+ } catch {
100
+ return null;
101
+ }
102
+ }
103
+ function validatePublicId(publicId) {
104
+ if (!publicId || typeof publicId !== "string") return false;
105
+ const parts = publicId.split("/");
106
+ return parts.length >= 2 && parts.every((p) => p.length > 0);
107
+ }
108
+ function getFolderPath(appName, subfolder) {
109
+ if (!appName) throw new Error("appName is required for getFolderPath");
110
+ const parts = [appName];
111
+ if (subfolder) {
112
+ const cleaned = subfolder.replace(/^\/+|\/+$/g, "").split("/").filter(Boolean).join("/");
113
+ if (cleaned) parts.push(cleaned);
114
+ }
115
+ return parts.join("/");
116
+ }
117
+ function getOptimizedUrl(cloudName, publicId, transforms = {}, resourceType = "image") {
118
+ const base = `https://res.cloudinary.com/${cloudName}/${resourceType}/upload`;
119
+ const parts = Object.entries(transforms).map(([k, v]) => `${k}_${v}`).join(",");
120
+ return parts ? `${base}/${parts}/${publicId}` : `${base}/${publicId}`;
121
+ }
122
+ var TRANSFORM_PRESETS = {
123
+ thumbnail: { w: 150, h: 150, c: "fill", g: "auto", q: "auto", f: "auto" },
124
+ adCard: { w: 300, h: 200, c: "fill", g: "auto", q: "auto", f: "auto" },
125
+ profilePicture: { w: 100, h: 100, c: "fill", g: "face", r: "max", q: "auto", f: "auto" },
126
+ adDetail: { w: 800, h: 600, c: "fill", q: "auto", f: "auto" },
127
+ responsive: { w: "auto", dpr: "auto", q: "auto", f: "auto" }
128
+ };
129
+ export {
130
+ SanvikaCloudinaryProvider,
131
+ TRANSFORM_PRESETS,
132
+ extractPublicId,
133
+ getFolderPath,
134
+ getOptimizedUrl,
135
+ isCloudinaryUrl,
136
+ useCloudinaryUpload,
137
+ useSanvikaCloudinary,
138
+ validatePublicId
139
+ };
package/dist/index.js CHANGED
@@ -1,5 +1,3 @@
1
- "use client";
2
-
3
1
  // src/cloudinaryCore.js
4
2
  import { v2 as cloudinary } from "cloudinary";
5
3
 
@@ -255,82 +253,8 @@ async function pingCloudinary() {
255
253
  ensureConfigured();
256
254
  return cloudinary.api.ping();
257
255
  }
258
-
259
- // src/SanvikaCloudinaryProvider.jsx
260
- import { createContext, useContext, useMemo } from "react";
261
- import { jsx } from "react/jsx-runtime";
262
- var SanvikaCloudinaryContext = createContext(null);
263
- function SanvikaCloudinaryProvider({ appName, cloudName, uploadPreset = "ml_default", children }) {
264
- const value = useMemo(
265
- () => ({ appName, cloudName, uploadPreset }),
266
- [appName, cloudName, uploadPreset]
267
- );
268
- return /* @__PURE__ */ jsx(SanvikaCloudinaryContext.Provider, { value, children });
269
- }
270
- function useSanvikaCloudinary() {
271
- const ctx = useContext(SanvikaCloudinaryContext);
272
- if (!ctx) {
273
- throw new Error("useSanvikaCloudinary must be used within a SanvikaCloudinaryProvider");
274
- }
275
- return ctx;
276
- }
277
-
278
- // src/useCloudinaryUpload.js
279
- import { useState, useCallback } from "react";
280
- function useCloudinaryUpload(options = {}) {
281
- const { folder, resourceType = "image", onProgress } = options;
282
- const { appName, cloudName, uploadPreset } = useSanvikaCloudinary();
283
- const [uploading, setUploading] = useState(false);
284
- const [error, setError] = useState(null);
285
- const reset = useCallback(() => {
286
- setError(null);
287
- setUploading(false);
288
- }, []);
289
- const upload = useCallback(
290
- async (file) => {
291
- setError(null);
292
- setUploading(true);
293
- try {
294
- const folderPath = folder ? `${appName}/${folder}` : appName;
295
- const formData = new FormData();
296
- formData.append("file", file);
297
- formData.append("upload_preset", uploadPreset);
298
- formData.append("folder", folderPath);
299
- const xhr = new XMLHttpRequest();
300
- const url = `https://api.cloudinary.com/v1_1/${cloudName}/${resourceType}/upload`;
301
- const result = await new Promise((resolve, reject) => {
302
- xhr.open("POST", url);
303
- if (onProgress) {
304
- xhr.upload.onprogress = (e) => {
305
- if (e.lengthComputable) onProgress(Math.round(e.loaded / e.total * 100));
306
- };
307
- }
308
- xhr.onload = () => {
309
- if (xhr.status >= 200 && xhr.status < 300) {
310
- resolve(JSON.parse(xhr.responseText));
311
- } else {
312
- reject(new Error(xhr.responseText || "Upload failed"));
313
- }
314
- };
315
- xhr.onerror = () => reject(new Error("Network error during upload"));
316
- xhr.send(formData);
317
- });
318
- return result;
319
- } catch (err) {
320
- const msg = (err == null ? void 0 : err.message) || "Upload failed";
321
- setError(msg);
322
- throw err;
323
- } finally {
324
- setUploading(false);
325
- }
326
- },
327
- [appName, cloudName, uploadPreset, folder, resourceType, onProgress]
328
- );
329
- return { upload, uploading, error, reset };
330
- }
331
256
  export {
332
257
  CloudinaryError,
333
- SanvikaCloudinaryProvider,
334
258
  TRANSFORM_PRESETS,
335
259
  configureSanvikaCloudinary,
336
260
  deleteImage,
@@ -346,8 +270,6 @@ export {
346
270
  uploadImages,
347
271
  uploadRawFile,
348
272
  uploadVideo,
349
- useCloudinaryUpload,
350
- useSanvikaCloudinary,
351
273
  validatePublicId,
352
274
  withRetry
353
275
  };
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@sanvika/cloudinary",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Centralized Cloudinary SDK for the Sanvika ecosystem — upload, delete, transform, and manage media across 50+ projects",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",
8
8
  "exports": {
9
- ".": "./dist/index.js"
9
+ ".": "./dist/index.js",
10
+ "./client": "./dist/client.js"
10
11
  },
11
12
  "files": [
12
13
  "dist"
@@ -36,8 +37,12 @@
36
37
  "react-dom": ">=18.0.0"
37
38
  },
38
39
  "peerDependenciesMeta": {
39
- "react": { "optional": true },
40
- "react-dom": { "optional": true }
40
+ "react": {
41
+ "optional": true
42
+ },
43
+ "react-dom": {
44
+ "optional": true
45
+ }
41
46
  },
42
47
  "engines": {
43
48
  "node": ">=18.0.0"