@frybynite/image-cloud 0.6.4 → 0.7.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.
- package/README.md +1 -28
- package/dist/image-cloud-auto-init.js +759 -345
- package/dist/image-cloud-auto-init.js.map +1 -1
- package/dist/image-cloud.js +1040 -1084
- package/dist/image-cloud.js.map +1 -1
- package/dist/image-cloud.umd.js +5 -5
- package/dist/image-cloud.umd.js.map +1 -1
- package/dist/index.d.ts +0 -2
- package/dist/react.d.ts +0 -2
- package/dist/react.js +848 -434
- package/dist/react.js.map +1 -1
- package/dist/vue.d.ts +0 -2
- package/dist/vue.js +856 -442
- package/dist/vue.js.map +1 -1
- package/dist/web-component.d.ts +0 -2
- package/dist/web-component.js +843 -429
- package/dist/web-component.js.map +1 -1
- package/package.json +14 -27
- package/dist/composite-CtUxtN2l.js +0 -96
- package/dist/composite-CtUxtN2l.js.map +0 -1
- package/dist/google-drive-CC-qFSV1.js +0 -260
- package/dist/google-drive-CC-qFSV1.js.map +0 -1
- package/dist/loaders/all.d.ts +0 -1654
- package/dist/loaders/all.js +0 -496
- package/dist/loaders/all.js.map +0 -1
- package/dist/loaders/composite.d.ts +0 -1654
- package/dist/loaders/composite.js +0 -96
- package/dist/loaders/composite.js.map +0 -1
- package/dist/loaders/google-drive.d.ts +0 -1654
- package/dist/loaders/google-drive.js +0 -260
- package/dist/loaders/google-drive.js.map +0 -1
- package/dist/loaders/static.d.ts +0 -1654
- package/dist/loaders/static.js +0 -219
- package/dist/loaders/static.js.map +0 -1
- package/dist/static-ejylHtQ4.js +0 -219
- package/dist/static-ejylHtQ4.js.map +0 -1
package/dist/loaders/static.js
DELETED
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
const a = class a {
|
|
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
|
-
a.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 = a.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 a.registry.has(e);
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
a.registry = /* @__PURE__ */ new Map();
|
|
34
|
-
let n = a;
|
|
35
|
-
class l {
|
|
36
|
-
constructor(e) {
|
|
37
|
-
if (this._prepared = !1, this._discoveredUrls = [], this.validateUrls = e.validateUrls !== !1, this.validationTimeout = e.validationTimeout ?? 5e3, this.validationMethod = e.validationMethod ?? "head", this.debugLogging = e.debugLogging ?? !1, this.sources = e.sources ?? [], !this.sources || this.sources.length === 0)
|
|
38
|
-
throw new Error("StaticImageLoader requires at least one source to be configured");
|
|
39
|
-
this.log("StaticImageLoader initialized with config:", e);
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Prepare the loader by discovering all images from configured sources
|
|
43
|
-
* @param filter - Filter to apply to discovered images
|
|
44
|
-
*/
|
|
45
|
-
async prepare(e) {
|
|
46
|
-
this._discoveredUrls = [], this.log(`Processing ${this.sources.length} source(s)`);
|
|
47
|
-
for (const t of this.sources)
|
|
48
|
-
try {
|
|
49
|
-
const r = await this.processSource(t, e);
|
|
50
|
-
this._discoveredUrls.push(...r);
|
|
51
|
-
} catch (r) {
|
|
52
|
-
console.warn("Failed to process source:", t, r);
|
|
53
|
-
}
|
|
54
|
-
this._prepared = !0, this.log(`Successfully loaded ${this._discoveredUrls.length} image(s)`);
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Get the number of discovered images
|
|
58
|
-
* @throws Error if called before prepare()
|
|
59
|
-
*/
|
|
60
|
-
imagesLength() {
|
|
61
|
-
if (!this._prepared)
|
|
62
|
-
throw new Error("StaticImageLoader.imagesLength() called before prepare()");
|
|
63
|
-
return this._discoveredUrls.length;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Get the ordered list of image URLs
|
|
67
|
-
* @throws Error if called before prepare()
|
|
68
|
-
*/
|
|
69
|
-
imageURLs() {
|
|
70
|
-
if (!this._prepared)
|
|
71
|
-
throw new Error("StaticImageLoader.imageURLs() called before prepare()");
|
|
72
|
-
return [...this._discoveredUrls];
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Check if the loader has been prepared
|
|
76
|
-
*/
|
|
77
|
-
isPrepared() {
|
|
78
|
-
return this._prepared;
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Process a single source object using shape-based detection
|
|
82
|
-
* @param source - Source configuration detected by key presence
|
|
83
|
-
* @param filter - Filter to apply to discovered images
|
|
84
|
-
* @returns Promise resolving to array of valid URLs from this source
|
|
85
|
-
*/
|
|
86
|
-
async processSource(e, t) {
|
|
87
|
-
return e ? "urls" in e ? await this.processUrls(e.urls, t) : "path" in e ? await this.processPath(e.path, e.files, t) : "json" in e ? await this.processJson(e.json, t) : (console.warn("Unknown source shape:", e), []) : (console.warn("Invalid source object:", e), []);
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Process a list of direct URLs
|
|
91
|
-
* @param urls - Array of image URLs
|
|
92
|
-
* @param filter - Filter to apply to discovered images
|
|
93
|
-
* @returns Promise resolving to array of validated URLs
|
|
94
|
-
*/
|
|
95
|
-
async processUrls(e, t) {
|
|
96
|
-
if (!Array.isArray(e))
|
|
97
|
-
return console.warn("URLs must be an array:", e), [];
|
|
98
|
-
const r = [];
|
|
99
|
-
for (const i of e) {
|
|
100
|
-
const s = i.split("/").pop() || i;
|
|
101
|
-
if (!t.isAllowed(s)) {
|
|
102
|
-
this.log(`Skipping filtered URL: ${i}`);
|
|
103
|
-
continue;
|
|
104
|
-
}
|
|
105
|
-
this.validateUrls ? await this.validateUrl(i) ? r.push(i) : console.warn(`Skipping invalid/missing URL: ${i}`) : r.push(i);
|
|
106
|
-
}
|
|
107
|
-
return r;
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Process a path-based source
|
|
111
|
-
* @param basePath - Base path (relative or absolute)
|
|
112
|
-
* @param files - Array of filenames
|
|
113
|
-
* @param filter - Filter to apply to discovered images
|
|
114
|
-
* @returns Promise resolving to array of validated URLs
|
|
115
|
-
*/
|
|
116
|
-
async processPath(e, t, r) {
|
|
117
|
-
if (!Array.isArray(t))
|
|
118
|
-
return console.warn("files must be an array:", t), [];
|
|
119
|
-
const i = [];
|
|
120
|
-
for (const s of t) {
|
|
121
|
-
if (!r.isAllowed(s)) {
|
|
122
|
-
this.log(`Skipping filtered file: ${s}`);
|
|
123
|
-
continue;
|
|
124
|
-
}
|
|
125
|
-
const o = this.constructUrl(e, s);
|
|
126
|
-
this.validateUrls ? await this.validateUrl(o) ? i.push(o) : console.warn(`Skipping invalid/missing file: ${o}`) : i.push(o);
|
|
127
|
-
}
|
|
128
|
-
return i;
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Process a JSON endpoint source
|
|
132
|
-
* Fetches a JSON endpoint that returns { images: string[] }
|
|
133
|
-
* @param url - JSON endpoint URL
|
|
134
|
-
* @param filter - Filter to apply to discovered images
|
|
135
|
-
* @returns Promise resolving to array of validated URLs
|
|
136
|
-
*/
|
|
137
|
-
async processJson(e, t) {
|
|
138
|
-
this.log(`Fetching JSON endpoint: ${e}`);
|
|
139
|
-
const r = new AbortController(), i = setTimeout(() => r.abort(), 1e4);
|
|
140
|
-
try {
|
|
141
|
-
const s = await fetch(e, { signal: r.signal });
|
|
142
|
-
if (clearTimeout(i), !s.ok)
|
|
143
|
-
throw new Error(`HTTP ${s.status} fetching ${e}`);
|
|
144
|
-
const o = await s.json();
|
|
145
|
-
if (!o || !Array.isArray(o.images))
|
|
146
|
-
throw new Error('JSON source must return JSON with shape { "images": ["url1", "url2", ...] }');
|
|
147
|
-
return this.log(`JSON endpoint returned ${o.images.length} image(s)`), await this.processUrls(o.images, t);
|
|
148
|
-
} catch (s) {
|
|
149
|
-
throw clearTimeout(i), s instanceof Error && s.name === "AbortError" ? new Error(`Timeout fetching JSON endpoint: ${e}`) : s;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Validate a single URL using HEAD request
|
|
154
|
-
* @param url - URL to validate
|
|
155
|
-
* @returns Promise resolving to true if valid and accessible
|
|
156
|
-
*/
|
|
157
|
-
async validateUrl(e) {
|
|
158
|
-
if (this.validationMethod === "none")
|
|
159
|
-
return !0;
|
|
160
|
-
if (this.validationMethod === "simple")
|
|
161
|
-
try {
|
|
162
|
-
return typeof window < "u" ? new URL(e, window.location.origin) : new URL(e), !0;
|
|
163
|
-
} catch {
|
|
164
|
-
return !1;
|
|
165
|
-
}
|
|
166
|
-
if (typeof window > "u")
|
|
167
|
-
return !0;
|
|
168
|
-
if (!(e.startsWith(window.location.origin) || e.startsWith("/")))
|
|
169
|
-
return this.log(`Skipping validation for cross-origin URL: ${e}`), !0;
|
|
170
|
-
try {
|
|
171
|
-
const r = new AbortController(), i = setTimeout(() => r.abort(), this.validationTimeout), s = await fetch(e, {
|
|
172
|
-
method: "HEAD",
|
|
173
|
-
signal: r.signal
|
|
174
|
-
});
|
|
175
|
-
return clearTimeout(i), s.ok ? !0 : (this.log(`Validation failed for ${e}: HTTP ${s.status}`), !1);
|
|
176
|
-
} catch (r) {
|
|
177
|
-
return r instanceof Error && (r.name === "AbortError" ? this.log(`Validation timeout for ${e}`) : this.log(`Validation failed for ${e}:`, r.message)), !1;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Construct full URL from basePath and filename
|
|
182
|
-
* @param basePath - Base path (relative or absolute)
|
|
183
|
-
* @param filename - Filename to append
|
|
184
|
-
* @returns Complete URL
|
|
185
|
-
*/
|
|
186
|
-
constructUrl(e, t) {
|
|
187
|
-
const r = e.replace(/\/$/, "");
|
|
188
|
-
if (this.isAbsoluteUrl(e))
|
|
189
|
-
return `${r}/${t}`;
|
|
190
|
-
if (typeof window > "u")
|
|
191
|
-
return `${r}/${t}`;
|
|
192
|
-
const i = window.location.origin, o = (e.startsWith("/") ? e : "/" + e).replace(/\/$/, "");
|
|
193
|
-
return `${i}${o}/${t}`;
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Check if URL is absolute (contains protocol)
|
|
197
|
-
* @param url - URL to check
|
|
198
|
-
* @returns True if absolute URL
|
|
199
|
-
*/
|
|
200
|
-
isAbsoluteUrl(e) {
|
|
201
|
-
try {
|
|
202
|
-
return new URL(e), !0;
|
|
203
|
-
} catch {
|
|
204
|
-
return !1;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* Debug logging helper
|
|
209
|
-
* @param args - Arguments to log
|
|
210
|
-
*/
|
|
211
|
-
log(...e) {
|
|
212
|
-
this.debugLogging && typeof console < "u" && console.log(...e);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
n.registerLoader("static", l);
|
|
216
|
-
export {
|
|
217
|
-
l as StaticImageLoader
|
|
218
|
-
};
|
|
219
|
-
//# sourceMappingURL=static.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"static.js","sources":["../../src/engines/LoaderRegistry.ts","../../src/loaders/StaticImageLoader.ts","../../src/loaders/index-static.ts"],"sourcesContent":["/**\n * Loader Registry - Manages registration and lookup of image loader implementations\n *\n * This registry enables dynamic loading of loaders through separate bundles\n * while maintaining a central registry of available loaders. It mirrors the\n * LayoutEngine registry pattern for consistency.\n *\n * Public API:\n * - registerLoader(name, LoaderClass)\n * - getLoader(name)\n * - isRegistered(name)\n */\n\nimport type { ImageLoader, StaticLoaderInnerConfig, GoogleDriveLoaderInnerConfig } from '../config/types';\n\n/**\n * Constructor signature for loader classes\n * Supports both simple loaders and composite loaders with their respective config types\n */\nexport type LoaderConstructor =\n | (new (config: StaticLoaderInnerConfig) => ImageLoader)\n | (new (config: GoogleDriveLoaderInnerConfig) => ImageLoader)\n | (new (config: any) => ImageLoader);\n\nexport class LoaderRegistry {\n private static readonly registry = new Map<string, LoaderConstructor>();\n\n /**\n * Register a loader implementation with the registry\n * @param name - Loader identifier (e.g., 'static', 'google-drive', 'composite')\n * @param Loader - Loader class constructor to register\n */\n static registerLoader(name: string, Loader: LoaderConstructor): void {\n LoaderRegistry.registry.set(name, Loader);\n }\n\n /**\n * Get a registered loader implementation\n * @param name - Loader identifier\n * @returns Loader class constructor\n * @throws Error if loader is not registered\n */\n static getLoader(name: string): LoaderConstructor {\n const Loader = LoaderRegistry.registry.get(name);\n\n if (!Loader) {\n throw new Error(\n `Loader \"${name}\" is not registered. ` +\n `Import \"@frybynite/image-cloud/loaders/${name}\" or \"@frybynite/image-cloud/loaders/all\".`\n );\n }\n\n return Loader;\n }\n\n /**\n * Check if a loader is registered\n * @param name - Loader identifier\n * @returns True if the loader is registered, false otherwise\n */\n static isRegistered(name: string): boolean {\n return LoaderRegistry.registry.has(name);\n }\n}\n","/**\n * StaticImageLoader.ts\n * Loads images from predefined URL sources and local paths\n * Compatible with ImageCloud's loader interface\n *\n * Public API:\n * - prepare(filter) - Async discovery of images\n * - imagesLength() - Get count of discovered images\n * - imageURLs() - Get ordered list of image URLs\n * - isPrepared() - Check if loader has been prepared\n */\n\nimport type { ImageLoader, IImageFilter, StaticSource, StaticLoaderInnerConfig } from '../config/types';\n\nexport class StaticImageLoader implements ImageLoader {\n private validateUrls: boolean;\n private validationTimeout: number;\n private validationMethod: 'head' | 'simple' | 'none';\n private sources: StaticSource[];\n private debugLogging: boolean;\n\n // State for new interface\n private _prepared: boolean = false;\n private _discoveredUrls: string[] = [];\n\n constructor(config: StaticLoaderInnerConfig) {\n this.validateUrls = config.validateUrls !== false;\n this.validationTimeout = config.validationTimeout ?? 5000;\n this.validationMethod = config.validationMethod ?? 'head';\n this.debugLogging = config.debugLogging ?? false;\n this.sources = config.sources ?? [];\n\n // Validate that we have sources configured\n if (!this.sources || this.sources.length === 0) {\n throw new Error('StaticImageLoader requires at least one source to be configured');\n }\n\n this.log('StaticImageLoader initialized with config:', config);\n }\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(filter: IImageFilter): Promise<void> {\n this._discoveredUrls = [];\n\n this.log(`Processing ${this.sources.length} source(s)`);\n\n // Process sources sequentially to preserve order\n for (const source of this.sources) {\n try {\n const urls = await this.processSource(source, filter);\n this._discoveredUrls.push(...urls);\n } catch (error) {\n console.warn('Failed to process source:', source, error);\n // Continue processing other sources\n }\n }\n\n this._prepared = true;\n this.log(`Successfully loaded ${this._discoveredUrls.length} image(s)`);\n }\n\n /**\n * Get the number of discovered images\n * @throws Error if called before prepare()\n */\n imagesLength(): number {\n if (!this._prepared) {\n throw new Error('StaticImageLoader.imagesLength() called before prepare()');\n }\n return this._discoveredUrls.length;\n }\n\n /**\n * Get the ordered list of image URLs\n * @throws Error if called before prepare()\n */\n imageURLs(): string[] {\n if (!this._prepared) {\n throw new Error('StaticImageLoader.imageURLs() called before prepare()');\n }\n return [...this._discoveredUrls];\n }\n\n /**\n * Check if the loader has been prepared\n */\n isPrepared(): boolean {\n return this._prepared;\n }\n\n /**\n * Process a single source object using shape-based detection\n * @param source - Source configuration detected by key presence\n * @param filter - Filter to apply to discovered images\n * @returns Promise resolving to array of valid URLs from this source\n */\n private async processSource(source: StaticSource, filter: IImageFilter): Promise<string[]> {\n if (!source) {\n console.warn('Invalid source object:', source);\n return [];\n }\n\n if ('urls' in source) {\n return await this.processUrls(source.urls, filter);\n } else if ('path' in source) {\n return await this.processPath(source.path, source.files, filter);\n } else if ('json' in source) {\n return await this.processJson(source.json, filter);\n } else {\n console.warn('Unknown source shape:', source);\n return [];\n }\n }\n\n /**\n * Process a list of direct URLs\n * @param urls - Array of image URLs\n * @param filter - Filter to apply to discovered images\n * @returns Promise resolving to array of validated URLs\n */\n private async processUrls(urls: string[], filter: IImageFilter): Promise<string[]> {\n if (!Array.isArray(urls)) {\n console.warn('URLs must be an array:', urls);\n return [];\n }\n\n const validUrls: string[] = [];\n\n for (const url of urls) {\n // Apply filter based on URL filename\n const filename = url.split('/').pop() || url;\n if (!filter.isAllowed(filename)) {\n this.log(`Skipping filtered URL: ${url}`);\n continue;\n }\n\n if (this.validateUrls) {\n const isValid = await this.validateUrl(url);\n if (isValid) {\n validUrls.push(url);\n } else {\n console.warn(`Skipping invalid/missing URL: ${url}`);\n }\n } else {\n // No validation - add all URLs\n validUrls.push(url);\n }\n }\n\n return validUrls;\n }\n\n /**\n * Process a path-based source\n * @param basePath - Base path (relative or absolute)\n * @param files - Array of filenames\n * @param filter - Filter to apply to discovered images\n * @returns Promise resolving to array of validated URLs\n */\n private async processPath(basePath: string, files: string[], filter: IImageFilter): Promise<string[]> {\n\n if (!Array.isArray(files)) {\n console.warn('files must be an array:', files);\n return [];\n }\n\n const validUrls: string[] = [];\n\n for (const file of files) {\n // Apply filter based on filename\n if (!filter.isAllowed(file)) {\n this.log(`Skipping filtered file: ${file}`);\n continue;\n }\n\n const url = this.constructUrl(basePath, file);\n\n if (this.validateUrls) {\n const isValid = await this.validateUrl(url);\n if (isValid) {\n validUrls.push(url);\n } else {\n console.warn(`Skipping invalid/missing file: ${url}`);\n }\n } else {\n // No validation - add all URLs\n validUrls.push(url);\n }\n }\n\n return validUrls;\n }\n\n /**\n * Process a JSON endpoint source\n * Fetches a JSON endpoint that returns { images: string[] }\n * @param url - JSON endpoint URL\n * @param filter - Filter to apply to discovered images\n * @returns Promise resolving to array of validated URLs\n */\n private async processJson(url: string, filter: IImageFilter): Promise<string[]> {\n\n this.log(`Fetching JSON endpoint: ${url}`);\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 10000);\n\n try {\n const response = await fetch(url, { signal: controller.signal });\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status} fetching ${url}`);\n }\n\n const data = await response.json();\n\n if (!data || !Array.isArray(data.images)) {\n throw new Error(`JSON source must return JSON with shape { \"images\": [\"url1\", \"url2\", ...] }`);\n }\n\n this.log(`JSON endpoint returned ${data.images.length} image(s)`);\n\n // Process the URLs through the standard URL processing pipeline\n return await this.processUrls(data.images, filter);\n } catch (error) {\n clearTimeout(timeoutId);\n if (error instanceof Error && error.name === 'AbortError') {\n throw new Error(`Timeout fetching JSON endpoint: ${url}`);\n }\n throw error;\n }\n }\n\n /**\n * Validate a single URL using HEAD request\n * @param url - URL to validate\n * @returns Promise resolving to true if valid and accessible\n */\n private async validateUrl(url: string): Promise<boolean> {\n if (this.validationMethod === 'none') {\n return true;\n }\n\n if (this.validationMethod === 'simple') {\n // Basic URL format check\n try {\n if (typeof window !== 'undefined') {\n new URL(url, window.location.origin);\n } else {\n new URL(url);\n }\n return true;\n } catch {\n return false;\n }\n }\n\n // validationMethod === 'head' (default)\n // For cross-origin URLs, we can't validate due to CORS\n // So we only validate same-origin URLs\n if (typeof window === 'undefined') {\n return true; // In non-browser environment, assume valid\n }\n\n const isSameOrigin = url.startsWith(window.location.origin) ||\n url.startsWith('/');\n\n if (!isSameOrigin) {\n // Cross-origin URL - assume valid, can't validate due to CORS\n this.log(`Skipping validation for cross-origin URL: ${url}`);\n return true;\n }\n\n // Same-origin URL - validate with HEAD request\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.validationTimeout);\n\n const response = await fetch(url, {\n method: 'HEAD',\n signal: controller.signal\n });\n\n clearTimeout(timeoutId);\n\n if (response.ok) {\n return true;\n } else {\n this.log(`Validation failed for ${url}: HTTP ${response.status}`);\n return false;\n }\n\n } catch (error) {\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n this.log(`Validation timeout for ${url}`);\n } else {\n this.log(`Validation failed for ${url}:`, error.message);\n }\n }\n return false;\n }\n }\n\n /**\n * Construct full URL from basePath and filename\n * @param basePath - Base path (relative or absolute)\n * @param filename - Filename to append\n * @returns Complete URL\n */\n private constructUrl(basePath: string, filename: string): string {\n // Remove trailing slash from basePath\n const cleanBase = basePath.replace(/\\/$/, '');\n\n // Check if basePath is absolute URL\n if (this.isAbsoluteUrl(basePath)) {\n return `${cleanBase}/${filename}`;\n }\n\n // Relative path - prepend current origin\n if (typeof window === 'undefined') {\n return `${cleanBase}/${filename}`; // In non-browser environment, return as-is\n }\n\n const origin = window.location.origin;\n // Ensure basePath starts with /\n const normalizedPath = basePath.startsWith('/') ? basePath : '/' + basePath;\n const cleanPath = normalizedPath.replace(/\\/$/, '');\n\n return `${origin}${cleanPath}/${filename}`;\n }\n\n /**\n * Check if URL is absolute (contains protocol)\n * @param url - URL to check\n * @returns True if absolute URL\n */\n private isAbsoluteUrl(url: string): boolean {\n try {\n new URL(url);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Debug logging helper\n * @param args - Arguments to log\n */\n private log(...args: unknown[]): void {\n if (this.debugLogging && typeof console !== 'undefined') {\n console.log(...args);\n }\n }\n}\n","import { LoaderRegistry } from '../engines/LoaderRegistry';\nimport { StaticImageLoader } from './StaticImageLoader';\n\nLoaderRegistry.registerLoader('static', StaticImageLoader);\n\nexport { StaticImageLoader };\n"],"names":["_LoaderRegistry","name","Loader","LoaderRegistry","StaticImageLoader","config","filter","source","urls","error","validUrls","url","filename","basePath","files","file","controller","timeoutId","response","data","cleanBase","origin","cleanPath","args"],"mappings":"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"}
|
package/dist/static-ejylHtQ4.js
DELETED
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
const n = class a {
|
|
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(r, t) {
|
|
8
|
-
a.registry.set(r, 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(r) {
|
|
17
|
-
const t = a.registry.get(r);
|
|
18
|
-
if (!t)
|
|
19
|
-
throw new Error(
|
|
20
|
-
`Loader "${r}" is not registered. Import "@frybynite/image-cloud/loaders/${r}" 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(r) {
|
|
30
|
-
return a.registry.has(r);
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
n.registry = /* @__PURE__ */ new Map();
|
|
34
|
-
let l = n;
|
|
35
|
-
class c {
|
|
36
|
-
constructor(r) {
|
|
37
|
-
if (this._prepared = !1, this._discoveredUrls = [], this.validateUrls = r.validateUrls !== !1, this.validationTimeout = r.validationTimeout ?? 5e3, this.validationMethod = r.validationMethod ?? "head", this.debugLogging = r.debugLogging ?? !1, this.sources = r.sources ?? [], !this.sources || this.sources.length === 0)
|
|
38
|
-
throw new Error("StaticImageLoader requires at least one source to be configured");
|
|
39
|
-
this.log("StaticImageLoader initialized with config:", r);
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Prepare the loader by discovering all images from configured sources
|
|
43
|
-
* @param filter - Filter to apply to discovered images
|
|
44
|
-
*/
|
|
45
|
-
async prepare(r) {
|
|
46
|
-
this._discoveredUrls = [], this.log(`Processing ${this.sources.length} source(s)`);
|
|
47
|
-
for (const t of this.sources)
|
|
48
|
-
try {
|
|
49
|
-
const i = await this.processSource(t, r);
|
|
50
|
-
this._discoveredUrls.push(...i);
|
|
51
|
-
} catch (i) {
|
|
52
|
-
console.warn("Failed to process source:", t, i);
|
|
53
|
-
}
|
|
54
|
-
this._prepared = !0, this.log(`Successfully loaded ${this._discoveredUrls.length} image(s)`);
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Get the number of discovered images
|
|
58
|
-
* @throws Error if called before prepare()
|
|
59
|
-
*/
|
|
60
|
-
imagesLength() {
|
|
61
|
-
if (!this._prepared)
|
|
62
|
-
throw new Error("StaticImageLoader.imagesLength() called before prepare()");
|
|
63
|
-
return this._discoveredUrls.length;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Get the ordered list of image URLs
|
|
67
|
-
* @throws Error if called before prepare()
|
|
68
|
-
*/
|
|
69
|
-
imageURLs() {
|
|
70
|
-
if (!this._prepared)
|
|
71
|
-
throw new Error("StaticImageLoader.imageURLs() called before prepare()");
|
|
72
|
-
return [...this._discoveredUrls];
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Check if the loader has been prepared
|
|
76
|
-
*/
|
|
77
|
-
isPrepared() {
|
|
78
|
-
return this._prepared;
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Process a single source object using shape-based detection
|
|
82
|
-
* @param source - Source configuration detected by key presence
|
|
83
|
-
* @param filter - Filter to apply to discovered images
|
|
84
|
-
* @returns Promise resolving to array of valid URLs from this source
|
|
85
|
-
*/
|
|
86
|
-
async processSource(r, t) {
|
|
87
|
-
return r ? "urls" in r ? await this.processUrls(r.urls, t) : "path" in r ? await this.processPath(r.path, r.files, t) : "json" in r ? await this.processJson(r.json, t) : (console.warn("Unknown source shape:", r), []) : (console.warn("Invalid source object:", r), []);
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Process a list of direct URLs
|
|
91
|
-
* @param urls - Array of image URLs
|
|
92
|
-
* @param filter - Filter to apply to discovered images
|
|
93
|
-
* @returns Promise resolving to array of validated URLs
|
|
94
|
-
*/
|
|
95
|
-
async processUrls(r, t) {
|
|
96
|
-
if (!Array.isArray(r))
|
|
97
|
-
return console.warn("URLs must be an array:", r), [];
|
|
98
|
-
const i = [];
|
|
99
|
-
for (const s of r) {
|
|
100
|
-
const e = s.split("/").pop() || s;
|
|
101
|
-
if (!t.isAllowed(e)) {
|
|
102
|
-
this.log(`Skipping filtered URL: ${s}`);
|
|
103
|
-
continue;
|
|
104
|
-
}
|
|
105
|
-
this.validateUrls ? await this.validateUrl(s) ? i.push(s) : console.warn(`Skipping invalid/missing URL: ${s}`) : i.push(s);
|
|
106
|
-
}
|
|
107
|
-
return i;
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Process a path-based source
|
|
111
|
-
* @param basePath - Base path (relative or absolute)
|
|
112
|
-
* @param files - Array of filenames
|
|
113
|
-
* @param filter - Filter to apply to discovered images
|
|
114
|
-
* @returns Promise resolving to array of validated URLs
|
|
115
|
-
*/
|
|
116
|
-
async processPath(r, t, i) {
|
|
117
|
-
if (!Array.isArray(t))
|
|
118
|
-
return console.warn("files must be an array:", t), [];
|
|
119
|
-
const s = [];
|
|
120
|
-
for (const e of t) {
|
|
121
|
-
if (!i.isAllowed(e)) {
|
|
122
|
-
this.log(`Skipping filtered file: ${e}`);
|
|
123
|
-
continue;
|
|
124
|
-
}
|
|
125
|
-
const o = this.constructUrl(r, e);
|
|
126
|
-
this.validateUrls ? await this.validateUrl(o) ? s.push(o) : console.warn(`Skipping invalid/missing file: ${o}`) : s.push(o);
|
|
127
|
-
}
|
|
128
|
-
return s;
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Process a JSON endpoint source
|
|
132
|
-
* Fetches a JSON endpoint that returns { images: string[] }
|
|
133
|
-
* @param url - JSON endpoint URL
|
|
134
|
-
* @param filter - Filter to apply to discovered images
|
|
135
|
-
* @returns Promise resolving to array of validated URLs
|
|
136
|
-
*/
|
|
137
|
-
async processJson(r, t) {
|
|
138
|
-
this.log(`Fetching JSON endpoint: ${r}`);
|
|
139
|
-
const i = new AbortController(), s = setTimeout(() => i.abort(), 1e4);
|
|
140
|
-
try {
|
|
141
|
-
const e = await fetch(r, { signal: i.signal });
|
|
142
|
-
if (clearTimeout(s), !e.ok)
|
|
143
|
-
throw new Error(`HTTP ${e.status} fetching ${r}`);
|
|
144
|
-
const o = await e.json();
|
|
145
|
-
if (!o || !Array.isArray(o.images))
|
|
146
|
-
throw new Error('JSON source must return JSON with shape { "images": ["url1", "url2", ...] }');
|
|
147
|
-
return this.log(`JSON endpoint returned ${o.images.length} image(s)`), await this.processUrls(o.images, t);
|
|
148
|
-
} catch (e) {
|
|
149
|
-
throw clearTimeout(s), e instanceof Error && e.name === "AbortError" ? new Error(`Timeout fetching JSON endpoint: ${r}`) : e;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Validate a single URL using HEAD request
|
|
154
|
-
* @param url - URL to validate
|
|
155
|
-
* @returns Promise resolving to true if valid and accessible
|
|
156
|
-
*/
|
|
157
|
-
async validateUrl(r) {
|
|
158
|
-
if (this.validationMethod === "none")
|
|
159
|
-
return !0;
|
|
160
|
-
if (this.validationMethod === "simple")
|
|
161
|
-
try {
|
|
162
|
-
return typeof window < "u" ? new URL(r, window.location.origin) : new URL(r), !0;
|
|
163
|
-
} catch {
|
|
164
|
-
return !1;
|
|
165
|
-
}
|
|
166
|
-
if (typeof window > "u")
|
|
167
|
-
return !0;
|
|
168
|
-
if (!(r.startsWith(window.location.origin) || r.startsWith("/")))
|
|
169
|
-
return this.log(`Skipping validation for cross-origin URL: ${r}`), !0;
|
|
170
|
-
try {
|
|
171
|
-
const t = new AbortController(), i = setTimeout(() => t.abort(), this.validationTimeout), s = await fetch(r, {
|
|
172
|
-
method: "HEAD",
|
|
173
|
-
signal: t.signal
|
|
174
|
-
});
|
|
175
|
-
return clearTimeout(i), s.ok ? !0 : (this.log(`Validation failed for ${r}: HTTP ${s.status}`), !1);
|
|
176
|
-
} catch (t) {
|
|
177
|
-
return t instanceof Error && (t.name === "AbortError" ? this.log(`Validation timeout for ${r}`) : this.log(`Validation failed for ${r}:`, t.message)), !1;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Construct full URL from basePath and filename
|
|
182
|
-
* @param basePath - Base path (relative or absolute)
|
|
183
|
-
* @param filename - Filename to append
|
|
184
|
-
* @returns Complete URL
|
|
185
|
-
*/
|
|
186
|
-
constructUrl(r, t) {
|
|
187
|
-
const i = r.replace(/\/$/, "");
|
|
188
|
-
if (this.isAbsoluteUrl(r))
|
|
189
|
-
return `${i}/${t}`;
|
|
190
|
-
if (typeof window > "u")
|
|
191
|
-
return `${i}/${t}`;
|
|
192
|
-
const s = window.location.origin, e = (r.startsWith("/") ? r : "/" + r).replace(/\/$/, "");
|
|
193
|
-
return `${s}${e}/${t}`;
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Check if URL is absolute (contains protocol)
|
|
197
|
-
* @param url - URL to check
|
|
198
|
-
* @returns True if absolute URL
|
|
199
|
-
*/
|
|
200
|
-
isAbsoluteUrl(r) {
|
|
201
|
-
try {
|
|
202
|
-
return new URL(r), !0;
|
|
203
|
-
} catch {
|
|
204
|
-
return !1;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* Debug logging helper
|
|
209
|
-
* @param args - Arguments to log
|
|
210
|
-
*/
|
|
211
|
-
log(...r) {
|
|
212
|
-
this.debugLogging && typeof console < "u" && console.log(...r);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
l.registerLoader("static", c);
|
|
216
|
-
export {
|
|
217
|
-
c as StaticImageLoader
|
|
218
|
-
};
|
|
219
|
-
//# sourceMappingURL=static-ejylHtQ4.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"static-ejylHtQ4.js","sources":["loaders/static.js"],"sourcesContent":["const a = class a {\n /**\n * Register a loader implementation with the registry\n * @param name - Loader identifier (e.g., 'static', 'google-drive', 'composite')\n * @param Loader - Loader class constructor to register\n */\n static registerLoader(e, t) {\n a.registry.set(e, t);\n }\n /**\n * Get a registered loader implementation\n * @param name - Loader identifier\n * @returns Loader class constructor\n * @throws Error if loader is not registered\n */\n static getLoader(e) {\n const t = a.registry.get(e);\n if (!t)\n throw new Error(\n `Loader \"${e}\" is not registered. Import \"@frybynite/image-cloud/loaders/${e}\" or \"@frybynite/image-cloud/loaders/all\".`\n );\n return t;\n }\n /**\n * Check if a loader is registered\n * @param name - Loader identifier\n * @returns True if the loader is registered, false otherwise\n */\n static isRegistered(e) {\n return a.registry.has(e);\n }\n};\na.registry = /* @__PURE__ */ new Map();\nlet n = a;\nclass l {\n constructor(e) {\n if (this._prepared = !1, this._discoveredUrls = [], this.validateUrls = e.validateUrls !== !1, this.validationTimeout = e.validationTimeout ?? 5e3, this.validationMethod = e.validationMethod ?? \"head\", this.debugLogging = e.debugLogging ?? !1, this.sources = e.sources ?? [], !this.sources || this.sources.length === 0)\n throw new Error(\"StaticImageLoader requires at least one source to be configured\");\n this.log(\"StaticImageLoader initialized with config:\", e);\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 = [], this.log(`Processing ${this.sources.length} source(s)`);\n for (const t of this.sources)\n try {\n const r = await this.processSource(t, e);\n this._discoveredUrls.push(...r);\n } catch (r) {\n console.warn(\"Failed to process source:\", t, r);\n }\n this._prepared = !0, this.log(`Successfully loaded ${this._discoveredUrls.length} image(s)`);\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(\"StaticImageLoader.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(\"StaticImageLoader.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 * Process a single source object using shape-based detection\n * @param source - Source configuration detected by key presence\n * @param filter - Filter to apply to discovered images\n * @returns Promise resolving to array of valid URLs from this source\n */\n async processSource(e, t) {\n return e ? \"urls\" in e ? await this.processUrls(e.urls, t) : \"path\" in e ? await this.processPath(e.path, e.files, t) : \"json\" in e ? await this.processJson(e.json, t) : (console.warn(\"Unknown source shape:\", e), []) : (console.warn(\"Invalid source object:\", e), []);\n }\n /**\n * Process a list of direct URLs\n * @param urls - Array of image URLs\n * @param filter - Filter to apply to discovered images\n * @returns Promise resolving to array of validated URLs\n */\n async processUrls(e, t) {\n if (!Array.isArray(e))\n return console.warn(\"URLs must be an array:\", e), [];\n const r = [];\n for (const i of e) {\n const s = i.split(\"/\").pop() || i;\n if (!t.isAllowed(s)) {\n this.log(`Skipping filtered URL: ${i}`);\n continue;\n }\n this.validateUrls ? await this.validateUrl(i) ? r.push(i) : console.warn(`Skipping invalid/missing URL: ${i}`) : r.push(i);\n }\n return r;\n }\n /**\n * Process a path-based source\n * @param basePath - Base path (relative or absolute)\n * @param files - Array of filenames\n * @param filter - Filter to apply to discovered images\n * @returns Promise resolving to array of validated URLs\n */\n async processPath(e, t, r) {\n if (!Array.isArray(t))\n return console.warn(\"files must be an array:\", t), [];\n const i = [];\n for (const s of t) {\n if (!r.isAllowed(s)) {\n this.log(`Skipping filtered file: ${s}`);\n continue;\n }\n const o = this.constructUrl(e, s);\n this.validateUrls ? await this.validateUrl(o) ? i.push(o) : console.warn(`Skipping invalid/missing file: ${o}`) : i.push(o);\n }\n return i;\n }\n /**\n * Process a JSON endpoint source\n * Fetches a JSON endpoint that returns { images: string[] }\n * @param url - JSON endpoint URL\n * @param filter - Filter to apply to discovered images\n * @returns Promise resolving to array of validated URLs\n */\n async processJson(e, t) {\n this.log(`Fetching JSON endpoint: ${e}`);\n const r = new AbortController(), i = setTimeout(() => r.abort(), 1e4);\n try {\n const s = await fetch(e, { signal: r.signal });\n if (clearTimeout(i), !s.ok)\n throw new Error(`HTTP ${s.status} fetching ${e}`);\n const o = await s.json();\n if (!o || !Array.isArray(o.images))\n throw new Error('JSON source must return JSON with shape { \"images\": [\"url1\", \"url2\", ...] }');\n return this.log(`JSON endpoint returned ${o.images.length} image(s)`), await this.processUrls(o.images, t);\n } catch (s) {\n throw clearTimeout(i), s instanceof Error && s.name === \"AbortError\" ? new Error(`Timeout fetching JSON endpoint: ${e}`) : s;\n }\n }\n /**\n * Validate a single URL using HEAD request\n * @param url - URL to validate\n * @returns Promise resolving to true if valid and accessible\n */\n async validateUrl(e) {\n if (this.validationMethod === \"none\")\n return !0;\n if (this.validationMethod === \"simple\")\n try {\n return typeof window < \"u\" ? new URL(e, window.location.origin) : new URL(e), !0;\n } catch {\n return !1;\n }\n if (typeof window > \"u\")\n return !0;\n if (!(e.startsWith(window.location.origin) || e.startsWith(\"/\")))\n return this.log(`Skipping validation for cross-origin URL: ${e}`), !0;\n try {\n const r = new AbortController(), i = setTimeout(() => r.abort(), this.validationTimeout), s = await fetch(e, {\n method: \"HEAD\",\n signal: r.signal\n });\n return clearTimeout(i), s.ok ? !0 : (this.log(`Validation failed for ${e}: HTTP ${s.status}`), !1);\n } catch (r) {\n return r instanceof Error && (r.name === \"AbortError\" ? this.log(`Validation timeout for ${e}`) : this.log(`Validation failed for ${e}:`, r.message)), !1;\n }\n }\n /**\n * Construct full URL from basePath and filename\n * @param basePath - Base path (relative or absolute)\n * @param filename - Filename to append\n * @returns Complete URL\n */\n constructUrl(e, t) {\n const r = e.replace(/\\/$/, \"\");\n if (this.isAbsoluteUrl(e))\n return `${r}/${t}`;\n if (typeof window > \"u\")\n return `${r}/${t}`;\n const i = window.location.origin, o = (e.startsWith(\"/\") ? e : \"/\" + e).replace(/\\/$/, \"\");\n return `${i}${o}/${t}`;\n }\n /**\n * Check if URL is absolute (contains protocol)\n * @param url - URL to check\n * @returns True if absolute URL\n */\n isAbsoluteUrl(e) {\n try {\n return new URL(e), !0;\n } catch {\n return !1;\n }\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}\nn.registerLoader(\"static\", l);\nexport {\n l as StaticImageLoader\n};\n//# sourceMappingURL=static.js.map\n"],"names":["a","e","n","l","r","i","s","o"],"mappings":"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"}
|