@frybynite/image-cloud 0.6.4 → 0.6.5

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.
@@ -1,38 +1,5 @@
1
- const i = class t {
2
- /**
3
- * Register a loader implementation with the registry
4
- * @param name - Loader identifier (e.g., 'static', 'google-drive', 'composite')
5
- * @param Loader - Loader class constructor to register
6
- */
7
- static registerLoader(e, r) {
8
- t.registry.set(e, r);
9
- }
10
- /**
11
- * Get a registered loader implementation
12
- * @param name - Loader identifier
13
- * @returns Loader class constructor
14
- * @throws Error if loader is not registered
15
- */
16
- static getLoader(e) {
17
- const r = t.registry.get(e);
18
- if (!r)
19
- throw new Error(
20
- `Loader "${e}" is not registered. Import "@frybynite/image-cloud/loaders/${e}" or "@frybynite/image-cloud/loaders/all".`
21
- );
22
- return r;
23
- }
24
- /**
25
- * Check if a loader is registered
26
- * @param name - Loader identifier
27
- * @returns True if the loader is registered, false otherwise
28
- */
29
- static isRegistered(e) {
30
- return t.registry.has(e);
31
- }
32
- };
33
- i.registry = /* @__PURE__ */ new Map();
34
- let d = i;
35
- class l {
1
+ import { e as t } from "./image-cloud-CO9PMUGK.js";
2
+ class a {
36
3
  constructor(e) {
37
4
  if (this._prepared = !1, this._discoveredUrls = [], this.loaders = e.loaders, this.debugLogging = e.debugLogging ?? !1, !this.loaders || this.loaders.length === 0)
38
5
  throw new Error("CompositeLoader requires at least one loader to be configured");
@@ -44,15 +11,15 @@ class l {
44
11
  */
45
12
  async prepare(e) {
46
13
  this._discoveredUrls = [], this.log(`Preparing ${this.loaders.length} loader(s) in parallel`);
47
- const r = this.loaders.map((s, o) => s.prepare(e).then(() => {
48
- this.log(`Loader ${o} prepared with ${s.imagesLength()} images`);
49
- }).catch((a) => {
50
- console.warn(`Loader ${o} failed to prepare:`, a);
14
+ const s = this.loaders.map((r, o) => r.prepare(e).then(() => {
15
+ this.log(`Loader ${o} prepared with ${r.imagesLength()} images`);
16
+ }).catch((i) => {
17
+ console.warn(`Loader ${o} failed to prepare:`, i);
51
18
  }));
52
- await Promise.all(r);
53
- for (const s of this.loaders)
54
- if (s.isPrepared()) {
55
- const o = s.imageURLs();
19
+ await Promise.all(s);
20
+ for (const r of this.loaders)
21
+ if (r.isPrepared()) {
22
+ const o = r.imageURLs();
56
23
  this._discoveredUrls.push(...o);
57
24
  }
58
25
  this._prepared = !0, this.log(`CompositeLoader prepared with ${this._discoveredUrls.length} total images`);
@@ -89,8 +56,8 @@ class l {
89
56
  this.debugLogging && typeof console < "u" && console.log("[CompositeLoader]", ...e);
90
57
  }
91
58
  }
92
- d.registerLoader("composite", l);
59
+ t.registerLoader("composite", a);
93
60
  export {
94
- l as CompositeLoader
61
+ a as CompositeLoader
95
62
  };
96
- //# sourceMappingURL=composite-CtUxtN2l.js.map
63
+ //# sourceMappingURL=composite-BSJXKGwG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composite-BSJXKGwG.js","sources":["loaders/composite.js"],"sourcesContent":["import { LoaderRegistry as t } from \"@frybynite/image-cloud\";\nclass a {\n constructor(e) {\n if (this._prepared = !1, this._discoveredUrls = [], this.loaders = e.loaders, this.debugLogging = e.debugLogging ?? !1, !this.loaders || this.loaders.length === 0)\n throw new Error(\"CompositeLoader requires at least one loader to be configured\");\n this.log(`CompositeLoader initialized with ${this.loaders.length} loader(s)`);\n }\n /**\n * Prepare all loaders in parallel and combine their results\n * @param filter - Filter to apply to discovered images\n */\n async prepare(e) {\n this._discoveredUrls = [], this.log(`Preparing ${this.loaders.length} loader(s) in parallel`);\n const o = this.loaders.map((r, s) => r.prepare(e).then(() => {\n this.log(`Loader ${s} prepared with ${r.imagesLength()} images`);\n }).catch((i) => {\n console.warn(`Loader ${s} failed to prepare:`, i);\n }));\n await Promise.all(o);\n for (const r of this.loaders)\n if (r.isPrepared()) {\n const s = r.imageURLs();\n this._discoveredUrls.push(...s);\n }\n this._prepared = !0, this.log(`CompositeLoader prepared with ${this._discoveredUrls.length} total images`);\n }\n /**\n * Get the combined number of discovered images\n * @throws Error if called before prepare()\n */\n imagesLength() {\n if (!this._prepared)\n throw new Error(\"CompositeLoader.imagesLength() called before prepare()\");\n return this._discoveredUrls.length;\n }\n /**\n * Get the combined ordered list of image URLs\n * @throws Error if called before prepare()\n */\n imageURLs() {\n if (!this._prepared)\n throw new Error(\"CompositeLoader.imageURLs() called before prepare()\");\n return [...this._discoveredUrls];\n }\n /**\n * Check if the loader has been prepared\n */\n isPrepared() {\n return this._prepared;\n }\n /**\n * Debug logging helper\n * @param args - Arguments to log\n */\n log(...e) {\n this.debugLogging && typeof console < \"u\" && console.log(\"[CompositeLoader]\", ...e);\n }\n}\nt.registerLoader(\"composite\", a);\nexport {\n a as CompositeLoader\n};\n//# sourceMappingURL=composite.js.map\n"],"names":["o","s","t"],"mappings":";AACA,MAAM,EAAE;AAAA,EACN,YAAY,GAAG;AACb,QAAI,KAAK,YAAY,IAAI,KAAK,kBAAkB,CAAA,GAAI,KAAK,UAAU,EAAE,SAAS,KAAK,eAAe,EAAE,gBAAgB,IAAI,CAAC,KAAK,WAAW,KAAK,QAAQ,WAAW;AAC/J,YAAM,IAAI,MAAM,+DAA+D;AACjF,SAAK,IAAI,oCAAoC,KAAK,QAAQ,MAAM,YAAY;AAAA,EAC9E;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ,GAAG;AACf,SAAK,kBAAkB,IAAI,KAAK,IAAI,aAAa,KAAK,QAAQ,MAAM,wBAAwB;AAC5F,UAAMA,IAAI,KAAK,QAAQ,IAAI,CAAC,GAAGC,MAAM,EAAE,QAAQ,CAAC,EAAE,KAAK,MAAM;AAC3D,WAAK,IAAI,UAAUA,CAAC,kBAAkB,EAAE,cAAc,SAAS;AAAA,IACjE,CAAC,EAAE,MAAM,CAAC,MAAM;AACd,cAAQ,KAAK,UAAUA,CAAC,uBAAuB,CAAC;AAAA,IAClD,CAAC,CAAC;AACF,UAAM,QAAQ,IAAID,CAAC;AACnB,eAAW,KAAK,KAAK;AACnB,UAAI,EAAE,cAAc;AAClB,cAAMC,IAAI,EAAE,UAAS;AACrB,aAAK,gBAAgB,KAAK,GAAGA,CAAC;AAAA,MAChC;AACF,SAAK,YAAY,IAAI,KAAK,IAAI,iCAAiC,KAAK,gBAAgB,MAAM,eAAe;AAAA,EAC3G;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe;AACb,QAAI,CAAC,KAAK;AACR,YAAM,IAAI,MAAM,wDAAwD;AAC1E,WAAO,KAAK,gBAAgB;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY;AACV,QAAI,CAAC,KAAK;AACR,YAAM,IAAI,MAAM,qDAAqD;AACvE,WAAO,CAAC,GAAG,KAAK,eAAe;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAIA,aAAa;AACX,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,GAAG;AACR,SAAK,gBAAgB,OAAO,UAAU,OAAO,QAAQ,IAAI,qBAAqB,GAAG,CAAC;AAAA,EACpF;AACF;AACAC,EAAE,eAAe,aAAa,CAAC;"}
@@ -1,38 +1,5 @@
1
- const h = class d {
2
- /**
3
- * Register a loader implementation with the registry
4
- * @param name - Loader identifier (e.g., 'static', 'google-drive', 'composite')
5
- * @param Loader - Loader class constructor to register
6
- */
7
- static registerLoader(e, t) {
8
- d.registry.set(e, t);
9
- }
10
- /**
11
- * Get a registered loader implementation
12
- * @param name - Loader identifier
13
- * @returns Loader class constructor
14
- * @throws Error if loader is not registered
15
- */
16
- static getLoader(e) {
17
- const t = d.registry.get(e);
18
- if (!t)
19
- throw new Error(
20
- `Loader "${e}" is not registered. Import "@frybynite/image-cloud/loaders/${e}" or "@frybynite/image-cloud/loaders/all".`
21
- );
22
- return t;
23
- }
24
- /**
25
- * Check if a loader is registered
26
- * @param name - Loader identifier
27
- * @returns True if the loader is registered, false otherwise
28
- */
29
- static isRegistered(e) {
30
- return d.registry.has(e);
31
- }
32
- };
33
- h.registry = /* @__PURE__ */ new Map();
34
- let f = h;
35
- class m {
1
+ import { e as c } from "./image-cloud-CO9PMUGK.js";
2
+ class g {
36
3
  constructor(e) {
37
4
  if (this._prepared = !1, this._discoveredUrls = [], this.apiKey = e.apiKey ?? "", this.apiEndpoint = e.apiEndpoint ?? "https://www.googleapis.com/drive/v3/files", this.debugLogging = e.debugLogging ?? !1, this.sources = e.sources ?? [], !this.sources || this.sources.length === 0)
38
5
  throw new Error("GoogleDriveLoader requires at least one source to be configured");
@@ -43,15 +10,15 @@ class m {
43
10
  */
44
11
  async prepare(e) {
45
12
  this._discoveredUrls = [];
46
- for (const t of this.sources)
47
- if ("folders" in t)
48
- for (const r of t.folders) {
49
- const i = t.recursive !== void 0 ? t.recursive : !0, s = await this.loadFromFolder(r, e, i);
50
- this._discoveredUrls.push(...s);
13
+ for (const i of this.sources)
14
+ if ("folders" in i)
15
+ for (const o of i.folders) {
16
+ const t = i.recursive !== void 0 ? i.recursive : !0, r = await this.loadFromFolder(o, e, t);
17
+ this._discoveredUrls.push(...r);
51
18
  }
52
- else if ("files" in t) {
53
- const r = await this.loadFiles(t.files, e);
54
- this._discoveredUrls.push(...r);
19
+ else if ("files" in i) {
20
+ const o = await this.loadFiles(i.files, e);
21
+ this._discoveredUrls.push(...o);
55
22
  }
56
23
  this._prepared = !0;
57
24
  }
@@ -85,16 +52,16 @@ class m {
85
52
  * @returns Folder ID or null if invalid
86
53
  */
87
54
  extractFolderId(e) {
88
- const t = [
55
+ const i = [
89
56
  /\/folders\/([a-zA-Z0-9_-]+)/,
90
57
  // Standard format
91
58
  /id=([a-zA-Z0-9_-]+)/
92
59
  // Alternative format
93
60
  ];
94
- for (const r of t) {
95
- const i = e.match(r);
96
- if (i && i[1])
97
- return i[1];
61
+ for (const o of i) {
62
+ const t = e.match(o);
63
+ if (t && t[1])
64
+ return t[1];
98
65
  }
99
66
  return null;
100
67
  }
@@ -105,16 +72,16 @@ class m {
105
72
  * @param recursive - Whether to include images from subfolders
106
73
  * @returns Promise resolving to array of image URLs
107
74
  */
108
- async loadFromFolder(e, t, r = !0) {
109
- const i = this.extractFolderId(e);
110
- if (!i)
75
+ async loadFromFolder(e, i, o = !0) {
76
+ const t = this.extractFolderId(e);
77
+ if (!t)
111
78
  throw new Error("Invalid Google Drive folder URL. Please check the URL format.");
112
79
  if (!this.apiKey || this.apiKey === "YOUR_API_KEY_HERE")
113
- return this.loadImagesDirectly(i, t);
80
+ return this.loadImagesDirectly(t, i);
114
81
  try {
115
- return r ? await this.loadImagesRecursively(i, t) : await this.loadImagesFromSingleFolder(i, t);
116
- } catch (s) {
117
- return console.error("Error loading from Google Drive API:", s), this.loadImagesDirectly(i, t);
82
+ return o ? await this.loadImagesRecursively(t, i) : await this.loadImagesFromSingleFolder(t, i);
83
+ } catch (r) {
84
+ return console.error("Error loading from Google Drive API:", r), this.loadImagesDirectly(t, i);
118
85
  }
119
86
  }
120
87
  /**
@@ -123,16 +90,16 @@ class m {
123
90
  * @param filter - Filter to apply to discovered images
124
91
  * @returns Promise resolving to array of image URLs
125
92
  */
126
- async loadImagesFromSingleFolder(e, t) {
127
- const r = [], i = `'${e}' in parents and trashed=false`, s = `${this.apiEndpoint}?q=${encodeURIComponent(i)}&fields=files(id,name,mimeType,thumbnailLink)&key=${this.apiKey}`, a = await fetch(s);
93
+ async loadImagesFromSingleFolder(e, i) {
94
+ const o = [], t = `'${e}' in parents and trashed=false`, r = `${this.apiEndpoint}?q=${encodeURIComponent(t)}&fields=files(id,name,mimeType,thumbnailLink)&key=${this.apiKey}`, a = await fetch(r);
128
95
  if (!a.ok)
129
96
  throw new Error(`API request failed: ${a.status} ${a.statusText}`);
130
97
  const l = (await a.json()).files.filter(
131
- (o) => o.mimeType.startsWith("image/") && t.isAllowed(o.name)
98
+ (s) => s.mimeType.startsWith("image/") && i.isAllowed(s.name)
132
99
  );
133
- return this.log(`Found ${l.length} images in folder ${e} (non-recursive)`), l.forEach((o) => {
134
- r.push(`https://lh3.googleusercontent.com/d/${o.id}=s1600`), this.log(`Added file: ${o.name}`);
135
- }), r;
100
+ return this.log(`Found ${l.length} images in folder ${e} (non-recursive)`), l.forEach((s) => {
101
+ o.push(`https://lh3.googleusercontent.com/d/${s.id}=s1600`), this.log(`Added file: ${s.name}`);
102
+ }), o;
136
103
  }
137
104
  /**
138
105
  * Load specific files by their URLs or IDs
@@ -140,29 +107,29 @@ class m {
140
107
  * @param filter - Filter to apply to discovered images
141
108
  * @returns Promise resolving to array of image URLs
142
109
  */
143
- async loadFiles(e, t) {
144
- const r = [];
145
- for (const i of e) {
146
- const s = this.extractFileId(i);
147
- if (!s) {
148
- this.log(`Skipping invalid file URL: ${i}`);
110
+ async loadFiles(e, i) {
111
+ const o = [];
112
+ for (const t of e) {
113
+ const r = this.extractFileId(t);
114
+ if (!r) {
115
+ this.log(`Skipping invalid file URL: ${t}`);
149
116
  continue;
150
117
  }
151
118
  if (this.apiKey && this.apiKey !== "YOUR_API_KEY_HERE")
152
119
  try {
153
- const a = `${this.apiEndpoint}/${s}?fields=name,mimeType&key=${this.apiKey}`, l = await fetch(a);
120
+ const a = `${this.apiEndpoint}/${r}?fields=name,mimeType&key=${this.apiKey}`, l = await fetch(a);
154
121
  if (l.ok) {
155
- const o = await l.json();
156
- o.mimeType.startsWith("image/") && t.isAllowed(o.name) ? (r.push(`https://lh3.googleusercontent.com/d/${s}=s1600`), this.log(`Added file: ${o.name}`)) : this.log(`Skipping non-image file: ${o.name} (${o.mimeType})`);
122
+ const s = await l.json();
123
+ s.mimeType.startsWith("image/") && i.isAllowed(s.name) ? (o.push(`https://lh3.googleusercontent.com/d/${r}=s1600`), this.log(`Added file: ${s.name}`)) : this.log(`Skipping non-image file: ${s.name} (${s.mimeType})`);
157
124
  } else
158
- this.log(`Failed to fetch metadata for file ${s}: ${l.status}`);
125
+ this.log(`Failed to fetch metadata for file ${r}: ${l.status}`);
159
126
  } catch (a) {
160
- this.log(`Error fetching metadata for file ${s}:`, a);
127
+ this.log(`Error fetching metadata for file ${r}:`, a);
161
128
  }
162
129
  else
163
- r.push(`https://lh3.googleusercontent.com/d/${s}=s1600`);
130
+ o.push(`https://lh3.googleusercontent.com/d/${r}=s1600`);
164
131
  }
165
- return r;
132
+ return o;
166
133
  }
167
134
  /**
168
135
  * Extract file ID from Google Drive file URL
@@ -172,7 +139,7 @@ class m {
172
139
  extractFileId(e) {
173
140
  if (!/[/:.]/.test(e))
174
141
  return e;
175
- const t = [
142
+ const i = [
176
143
  /\/file\/d\/([a-zA-Z0-9_-]+)/,
177
144
  // Standard file format
178
145
  /\/open\?id=([a-zA-Z0-9_-]+)/,
@@ -180,10 +147,10 @@ class m {
180
147
  /id=([a-zA-Z0-9_-]+)/
181
148
  // Generic id parameter
182
149
  ];
183
- for (const r of t) {
184
- const i = e.match(r);
185
- if (i && i[1])
186
- return i[1];
150
+ for (const o of i) {
151
+ const t = e.match(o);
152
+ if (t && t[1])
153
+ return t[1];
187
154
  }
188
155
  return null;
189
156
  }
@@ -193,24 +160,24 @@ class m {
193
160
  * @param filter - Filter to apply to discovered images
194
161
  * @returns Promise resolving to array of image URLs
195
162
  */
196
- async loadImagesRecursively(e, t) {
197
- const r = [], i = `'${e}' in parents and trashed=false`, s = `${this.apiEndpoint}?q=${encodeURIComponent(i)}&fields=files(id,name,mimeType,thumbnailLink)&key=${this.apiKey}`, a = await fetch(s);
163
+ async loadImagesRecursively(e, i) {
164
+ const o = [], t = `'${e}' in parents and trashed=false`, r = `${this.apiEndpoint}?q=${encodeURIComponent(t)}&fields=files(id,name,mimeType,thumbnailLink)&key=${this.apiKey}`, a = await fetch(r);
198
165
  if (!a.ok)
199
166
  throw new Error(`API request failed: ${a.status} ${a.statusText}`);
200
- const l = await a.json(), o = l.files.filter(
201
- (n) => n.mimeType.startsWith("image/") && t.isAllowed(n.name)
202
- ), c = l.files.filter(
167
+ const l = await a.json(), s = l.files.filter(
168
+ (n) => n.mimeType.startsWith("image/") && i.isAllowed(n.name)
169
+ ), d = l.files.filter(
203
170
  (n) => n.mimeType === "application/vnd.google-apps.folder"
204
171
  );
205
- this.log(`Found ${l.files.length} total items in folder ${e}`), l.files.forEach((n) => this.log(` - File: ${n.name} (${n.mimeType})`)), this.log(`- ${o.length} valid files (images only)`), this.log(`- ${c.length} subfolders`), o.forEach((n) => {
206
- r.push(`https://lh3.googleusercontent.com/d/${n.id}=s1600`), this.log(`Added file: ${n.name}`);
172
+ this.log(`Found ${l.files.length} total items in folder ${e}`), l.files.forEach((n) => this.log(` - File: ${n.name} (${n.mimeType})`)), this.log(`- ${s.length} valid files (images only)`), this.log(`- ${d.length} subfolders`), s.forEach((n) => {
173
+ o.push(`https://lh3.googleusercontent.com/d/${n.id}=s1600`), this.log(`Added file: ${n.name}`);
207
174
  });
208
- for (const n of c) {
175
+ for (const n of d) {
209
176
  this.log(`Loading images from subfolder: ${n.name}`);
210
- const g = await this.loadImagesRecursively(n.id, t);
211
- r.push(...g);
177
+ const h = await this.loadImagesRecursively(n.id, i);
178
+ o.push(...h);
212
179
  }
213
- return r;
180
+ return o;
214
181
  }
215
182
  /**
216
183
  * Direct loading method (no API key required, but less reliable)
@@ -219,17 +186,17 @@ class m {
219
186
  * @param filter - Filter to apply (not used in fallback mode)
220
187
  * @returns Promise resolving to array of image URLs
221
188
  */
222
- async loadImagesDirectly(e, t) {
189
+ async loadImagesDirectly(e, i) {
223
190
  try {
224
- const r = `https://drive.google.com/embeddedfolderview?id=${e}`, i = await fetch(r, { mode: "cors" });
225
- if (!i.ok)
191
+ const o = `https://drive.google.com/embeddedfolderview?id=${e}`, t = await fetch(o, { mode: "cors" });
192
+ if (!t.ok)
226
193
  throw new Error("Cannot access folder directly (CORS or permissions issue)");
227
- const s = await i.text(), a = /\/file\/d\/([a-zA-Z0-9_-]+)/g, l = [...s.matchAll(a)];
228
- return [...new Set(l.map((o) => o[1]))].map(
229
- (o) => `https://drive.google.com/uc?export=view&id=${o}`
194
+ const r = await t.text(), a = /\/file\/d\/([a-zA-Z0-9_-]+)/g, l = [...r.matchAll(a)];
195
+ return [...new Set(l.map((s) => s[1]))].map(
196
+ (s) => `https://drive.google.com/uc?export=view&id=${s}`
230
197
  );
231
- } catch (r) {
232
- throw console.error("Direct loading failed:", r), new Error(
198
+ } catch (o) {
199
+ throw console.error("Direct loading failed:", o), new Error(
233
200
  `Unable to load images. Please ensure:
234
201
  1. The folder is shared publicly (Anyone with the link can view)
235
202
  2. The folder contains image files
@@ -243,7 +210,7 @@ class m {
243
210
  * @returns Array of direct image URLs
244
211
  */
245
212
  manualImageUrls(e) {
246
- return e.map((t) => `https://drive.google.com/uc?export=view&id=${t}`);
213
+ return e.map((i) => `https://drive.google.com/uc?export=view&id=${i}`);
247
214
  }
248
215
  /**
249
216
  * Debug logging helper
@@ -253,8 +220,8 @@ class m {
253
220
  this.debugLogging && typeof console < "u" && console.log(...e);
254
221
  }
255
222
  }
256
- f.registerLoader("google-drive", m);
223
+ c.registerLoader("google-drive", g);
257
224
  export {
258
- m as GoogleDriveLoader
225
+ g as GoogleDriveLoader
259
226
  };
260
- //# sourceMappingURL=google-drive-CC-qFSV1.js.map
227
+ //# sourceMappingURL=google-drive-DK2v0Xay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google-drive-DK2v0Xay.js","sources":["loaders/google-drive.js"],"sourcesContent":["import { LoaderRegistry as g } from \"@frybynite/image-cloud\";\nclass m {\n constructor(e) {\n if (this._prepared = !1, this._discoveredUrls = [], this.apiKey = e.apiKey ?? \"\", this.apiEndpoint = e.apiEndpoint ?? \"https://www.googleapis.com/drive/v3/files\", this.debugLogging = e.debugLogging ?? !1, this.sources = e.sources ?? [], !this.sources || this.sources.length === 0)\n throw new Error(\"GoogleDriveLoader requires at least one source to be configured\");\n }\n /**\n * Prepare the loader by discovering all images from configured sources\n * @param filter - Filter to apply to discovered images\n */\n async prepare(e) {\n this._discoveredUrls = [];\n for (const s of this.sources)\n if (\"folders\" in s)\n for (const o of s.folders) {\n const t = s.recursive !== void 0 ? s.recursive : !0, r = await this.loadFromFolder(o, e, t);\n this._discoveredUrls.push(...r);\n }\n else if (\"files\" in s) {\n const o = await this.loadFiles(s.files, e);\n this._discoveredUrls.push(...o);\n }\n this._prepared = !0;\n }\n /**\n * Get the number of discovered images\n * @throws Error if called before prepare()\n */\n imagesLength() {\n if (!this._prepared)\n throw new Error(\"GoogleDriveLoader.imagesLength() called before prepare()\");\n return this._discoveredUrls.length;\n }\n /**\n * Get the ordered list of image URLs\n * @throws Error if called before prepare()\n */\n imageURLs() {\n if (!this._prepared)\n throw new Error(\"GoogleDriveLoader.imageURLs() called before prepare()\");\n return [...this._discoveredUrls];\n }\n /**\n * Check if the loader has been prepared\n */\n isPrepared() {\n return this._prepared;\n }\n /**\n * Extract folder ID from various Google Drive URL formats\n * @param folderUrl - Google Drive folder URL\n * @returns Folder ID or null if invalid\n */\n extractFolderId(e) {\n const s = [\n /\\/folders\\/([a-zA-Z0-9_-]+)/,\n // Standard format\n /id=([a-zA-Z0-9_-]+)/\n // Alternative format\n ];\n for (const o of s) {\n const t = e.match(o);\n if (t && t[1])\n return t[1];\n }\n return null;\n }\n /**\n * Load images from a Google Drive folder\n * @param folderUrl - Google Drive folder URL\n * @param filter - Filter to apply to discovered images\n * @param recursive - Whether to include images from subfolders\n * @returns Promise resolving to array of image URLs\n */\n async loadFromFolder(e, s, o = !0) {\n const t = this.extractFolderId(e);\n if (!t)\n throw new Error(\"Invalid Google Drive folder URL. Please check the URL format.\");\n if (!this.apiKey || this.apiKey === \"YOUR_API_KEY_HERE\")\n return this.loadImagesDirectly(t, s);\n try {\n return o ? await this.loadImagesRecursively(t, s) : await this.loadImagesFromSingleFolder(t, s);\n } catch (r) {\n return console.error(\"Error loading from Google Drive API:\", r), this.loadImagesDirectly(t, s);\n }\n }\n /**\n * Load images from a single folder (non-recursive)\n * @param folderId - Google Drive folder ID\n * @param filter - Filter to apply to discovered images\n * @returns Promise resolving to array of image URLs\n */\n async loadImagesFromSingleFolder(e, s) {\n const o = [], t = `'${e}' in parents and trashed=false`, d = `${this.apiEndpoint}?q=${encodeURIComponent(t)}&fields=files(id,name,mimeType,thumbnailLink)&key=${this.apiKey}`, i = await fetch(d);\n if (!i.ok)\n throw new Error(`API request failed: ${i.status} ${i.statusText}`);\n const c = (await i.json()).files.filter(\n (l) => l.mimeType.startsWith(\"image/\") && s.isAllowed(l.name)\n );\n return this.log(`Found ${c.length} images in folder ${e} (non-recursive)`), c.forEach((l) => {\n o.push(`https://lh3.googleusercontent.com/d/${l.id}=s1600`), this.log(`Added file: ${l.name}`);\n }), o;\n }\n /**\n * Load specific files by their URLs or IDs\n * @param fileUrls - Array of Google Drive file URLs or IDs\n * @param filter - Filter to apply to discovered images\n * @returns Promise resolving to array of image URLs\n */\n async loadFiles(e, s) {\n const o = [];\n for (const t of e) {\n const r = this.extractFileId(t);\n if (!r) {\n this.log(`Skipping invalid file URL: ${t}`);\n continue;\n }\n if (this.apiKey && this.apiKey !== \"YOUR_API_KEY_HERE\")\n try {\n const d = `${this.apiEndpoint}/${r}?fields=name,mimeType&key=${this.apiKey}`, i = await fetch(d);\n if (i.ok) {\n const n = await i.json();\n n.mimeType.startsWith(\"image/\") && s.isAllowed(n.name) ? (o.push(`https://lh3.googleusercontent.com/d/${r}=s1600`), this.log(`Added file: ${n.name}`)) : this.log(`Skipping non-image file: ${n.name} (${n.mimeType})`);\n } else\n this.log(`Failed to fetch metadata for file ${r}: ${i.status}`);\n } catch (d) {\n this.log(`Error fetching metadata for file ${r}:`, d);\n }\n else\n o.push(`https://lh3.googleusercontent.com/d/${r}=s1600`);\n }\n return o;\n }\n /**\n * Extract file ID from Google Drive file URL\n * @param fileUrl - Google Drive file URL or file ID\n * @returns File ID or null if invalid\n */\n extractFileId(e) {\n if (!/[/:.]/.test(e))\n return e;\n const s = [\n /\\/file\\/d\\/([a-zA-Z0-9_-]+)/,\n // Standard file format\n /\\/open\\?id=([a-zA-Z0-9_-]+)/,\n // Alternative format\n /id=([a-zA-Z0-9_-]+)/\n // Generic id parameter\n ];\n for (const o of s) {\n const t = e.match(o);\n if (t && t[1])\n return t[1];\n }\n return null;\n }\n /**\n * Recursively load images from a folder and all its subfolders\n * @param folderId - Google Drive folder ID\n * @param filter - Filter to apply to discovered images\n * @returns Promise resolving to array of image URLs\n */\n async loadImagesRecursively(e, s) {\n const o = [], t = `'${e}' in parents and trashed=false`, d = `${this.apiEndpoint}?q=${encodeURIComponent(t)}&fields=files(id,name,mimeType,thumbnailLink)&key=${this.apiKey}`, i = await fetch(d);\n if (!i.ok)\n throw new Error(`API request failed: ${i.status} ${i.statusText}`);\n const n = await i.json(), c = n.files.filter(\n (a) => a.mimeType.startsWith(\"image/\") && s.isAllowed(a.name)\n ), l = n.files.filter(\n (a) => a.mimeType === \"application/vnd.google-apps.folder\"\n );\n this.log(`Found ${n.files.length} total items in folder ${e}`), n.files.forEach((a) => this.log(` - File: ${a.name} (${a.mimeType})`)), this.log(`- ${c.length} valid files (images only)`), this.log(`- ${l.length} subfolders`), c.forEach((a) => {\n o.push(`https://lh3.googleusercontent.com/d/${a.id}=s1600`), this.log(`Added file: ${a.name}`);\n });\n for (const a of l) {\n this.log(`Loading images from subfolder: ${a.name}`);\n const h = await this.loadImagesRecursively(a.id, s);\n o.push(...h);\n }\n return o;\n }\n /**\n * Direct loading method (no API key required, but less reliable)\n * Uses embedded folder view to scrape image IDs\n * @param folderId - Google Drive folder ID\n * @param filter - Filter to apply (not used in fallback mode)\n * @returns Promise resolving to array of image URLs\n */\n async loadImagesDirectly(e, s) {\n try {\n const o = `https://drive.google.com/embeddedfolderview?id=${e}`, t = await fetch(o, { mode: \"cors\" });\n if (!t.ok)\n throw new Error(\"Cannot access folder directly (CORS or permissions issue)\");\n const r = await t.text(), d = /\\/file\\/d\\/([a-zA-Z0-9_-]+)/g, i = [...r.matchAll(d)];\n return [...new Set(i.map((l) => l[1]))].map(\n (l) => `https://drive.google.com/uc?export=view&id=${l}`\n );\n } catch (o) {\n throw console.error(\"Direct loading failed:\", o), new Error(\n `Unable to load images. Please ensure:\n1. The folder is shared publicly (Anyone with the link can view)\n2. The folder contains image files\n3. Consider adding a Google Drive API key in config.js for better reliability`\n );\n }\n }\n /**\n * Manually add image URLs (for testing or when auto-loading fails)\n * @param imageIds - Array of Google Drive file IDs\n * @returns Array of direct image URLs\n */\n manualImageUrls(e) {\n return e.map((s) => `https://drive.google.com/uc?export=view&id=${s}`);\n }\n /**\n * Debug logging helper\n * @param args - Arguments to log\n */\n log(...e) {\n this.debugLogging && typeof console < \"u\" && console.log(...e);\n }\n}\ng.registerLoader(\"google-drive\", m);\nexport {\n m as GoogleDriveLoader\n};\n//# sourceMappingURL=google-drive.js.map\n"],"names":["m","s","d","i","c","l","n","a","g"],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ const s = class t {
2
+ /**
3
+ * Register a loader implementation with the registry
4
+ * @param name - Loader identifier (e.g., 'static', 'google-drive', 'composite')
5
+ * @param Loader - Loader class constructor to register
6
+ */
7
+ static registerLoader(e, r) {
8
+ t.registry.set(e, r);
9
+ }
10
+ /**
11
+ * Get a registered loader implementation
12
+ * @param name - Loader identifier
13
+ * @returns Loader class constructor
14
+ * @throws Error if loader is not registered
15
+ */
16
+ static getLoader(e) {
17
+ const r = t.registry.get(e);
18
+ if (!r)
19
+ throw new Error(
20
+ `Loader "${e}" is not registered. Import "@frybynite/image-cloud/loaders/${e}" or "@frybynite/image-cloud/loaders/all".`
21
+ );
22
+ return r;
23
+ }
24
+ /**
25
+ * Check if a loader is registered
26
+ * @param name - Loader identifier
27
+ * @returns True if the loader is registered, false otherwise
28
+ */
29
+ static isRegistered(e) {
30
+ return t.registry.has(e);
31
+ }
32
+ };
33
+ s.registry = /* @__PURE__ */ new Map();
34
+ let i = s;
35
+ export {
36
+ i as e
37
+ };
38
+ //# sourceMappingURL=image-cloud-CO9PMUGK.js.map