@ogify/core 0.1.4 → 0.1.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.
- package/README.md +165 -86
- package/dist/index.d.mts +77 -72
- package/dist/index.d.ts +77 -72
- package/dist/index.js +318 -51
- package/dist/index.mjs +295 -51
- package/package.json +14 -26
- package/LICENSE +0 -21
package/dist/index.js
CHANGED
|
@@ -3,10 +3,37 @@
|
|
|
3
3
|
var satori = require('satori');
|
|
4
4
|
var satoriHtml = require('satori-html');
|
|
5
5
|
var resvgJs = require('@resvg/resvg-js');
|
|
6
|
+
var lruCache = require('lru-cache');
|
|
7
|
+
var fs = require('fs');
|
|
8
|
+
var path = require('path');
|
|
9
|
+
var crypto = require('crypto');
|
|
10
|
+
var rtlCSSJS = require('rtl-css-js');
|
|
6
11
|
|
|
7
12
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
13
|
|
|
14
|
+
function _interopNamespace(e) {
|
|
15
|
+
if (e && e.__esModule) return e;
|
|
16
|
+
var n = Object.create(null);
|
|
17
|
+
if (e) {
|
|
18
|
+
Object.keys(e).forEach(function (k) {
|
|
19
|
+
if (k !== 'default') {
|
|
20
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
21
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
22
|
+
enumerable: true,
|
|
23
|
+
get: function () { return e[k]; }
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
n.default = e;
|
|
29
|
+
return Object.freeze(n);
|
|
30
|
+
}
|
|
31
|
+
|
|
9
32
|
var satori__default = /*#__PURE__*/_interopDefault(satori);
|
|
33
|
+
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
34
|
+
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
35
|
+
var crypto__namespace = /*#__PURE__*/_interopNamespace(crypto);
|
|
36
|
+
var rtlCSSJS__default = /*#__PURE__*/_interopDefault(rtlCSSJS);
|
|
10
37
|
|
|
11
38
|
// src/template.ts
|
|
12
39
|
|
|
@@ -175,6 +202,216 @@ var GoogleFontDetector = class {
|
|
|
175
202
|
}
|
|
176
203
|
}
|
|
177
204
|
};
|
|
205
|
+
var DEFAULT_TTL = 1e3 * 60 * 60 * 24 * 7;
|
|
206
|
+
var DEFAULT_MAX = 100;
|
|
207
|
+
var DEFAULT_CACHE_DIR = ".ogify-cache";
|
|
208
|
+
var CacheManager = class {
|
|
209
|
+
cache;
|
|
210
|
+
config;
|
|
211
|
+
cacheDir = DEFAULT_CACHE_DIR;
|
|
212
|
+
/**
|
|
213
|
+
* Creates a new CacheManager instance.
|
|
214
|
+
*
|
|
215
|
+
* @param config - Cache configuration (memory or filesystem)
|
|
216
|
+
*/
|
|
217
|
+
constructor(config) {
|
|
218
|
+
this.config = config;
|
|
219
|
+
if (config.type === "memory") {
|
|
220
|
+
this.cache = new lruCache.LRUCache({
|
|
221
|
+
max: config.max || DEFAULT_MAX,
|
|
222
|
+
ttl: config.ttl || DEFAULT_TTL
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
if (config.type === "filesystem") {
|
|
226
|
+
this.cacheDir = config.dir || DEFAULT_CACHE_DIR;
|
|
227
|
+
this.ensureCacheDirectory();
|
|
228
|
+
this.cleanExpiredFiles().catch((err) => {
|
|
229
|
+
console.warn("Failed to clean expired cache files:", err);
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// eslint-disable-next-line
|
|
234
|
+
generateKey(object) {
|
|
235
|
+
const sorted = Object.keys(object).sort().map((key) => `${key}=${object[key]}`);
|
|
236
|
+
return crypto__namespace.createHash("md5").update(sorted.join("|")).digest("hex");
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Retrieves a value from the cache.
|
|
240
|
+
*
|
|
241
|
+
* For filesystem cache, attempts to load from disk if not in memory.
|
|
242
|
+
*
|
|
243
|
+
* @param key - Cache key
|
|
244
|
+
* @returns Cached buffer or undefined if not found
|
|
245
|
+
*/
|
|
246
|
+
async get(key) {
|
|
247
|
+
if (this.config.type === "memory") {
|
|
248
|
+
return this.cache?.get(key);
|
|
249
|
+
}
|
|
250
|
+
if (this.config.type === "filesystem") {
|
|
251
|
+
return this.loadFromDisk(key);
|
|
252
|
+
}
|
|
253
|
+
return void 0;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Stores a value in the cache.
|
|
257
|
+
*
|
|
258
|
+
* For filesystem cache, also persists to disk.
|
|
259
|
+
*
|
|
260
|
+
* @param key - Cache key
|
|
261
|
+
* @param value - Buffer to cache
|
|
262
|
+
*/
|
|
263
|
+
async set(key, value) {
|
|
264
|
+
if (this.config.type === "memory") {
|
|
265
|
+
this.cache?.set(key, value);
|
|
266
|
+
}
|
|
267
|
+
if (this.config.type === "filesystem") {
|
|
268
|
+
await this.saveToDisk(key, value);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Checks if a key exists in the cache.
|
|
273
|
+
*
|
|
274
|
+
* @param key - Cache key
|
|
275
|
+
* @returns true if the key exists and is not expired
|
|
276
|
+
*/
|
|
277
|
+
async has(key) {
|
|
278
|
+
if (this.config.type === "memory") {
|
|
279
|
+
return this.cache?.has(key) || false;
|
|
280
|
+
}
|
|
281
|
+
if (this.config.type === "filesystem") {
|
|
282
|
+
try {
|
|
283
|
+
await fs__namespace.promises.access(path__namespace.join(this.cacheDir, this.getFilename(key)));
|
|
284
|
+
return true;
|
|
285
|
+
} catch {
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Clears all cached items.
|
|
293
|
+
*
|
|
294
|
+
* For filesystem cache, also removes all files from disk.
|
|
295
|
+
*/
|
|
296
|
+
async clear() {
|
|
297
|
+
if (this.config.type === "memory") {
|
|
298
|
+
this.cache?.clear();
|
|
299
|
+
}
|
|
300
|
+
if (this.config.type === "filesystem") {
|
|
301
|
+
await this.clearFilesystem();
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Ensures the cache directory exists.
|
|
306
|
+
* Creates it if it doesn't exist.
|
|
307
|
+
*/
|
|
308
|
+
ensureCacheDirectory() {
|
|
309
|
+
if (!this.cacheDir) return;
|
|
310
|
+
if (!fs__namespace.existsSync(this.cacheDir)) {
|
|
311
|
+
fs__namespace.mkdirSync(this.cacheDir, { recursive: true });
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Generates a safe filename from a cache key.
|
|
316
|
+
*
|
|
317
|
+
* Uses SHA-256 hash to avoid filesystem issues with special characters.
|
|
318
|
+
*
|
|
319
|
+
* @param key - Cache key
|
|
320
|
+
* @returns Safe filename
|
|
321
|
+
*/
|
|
322
|
+
getFilename(key) {
|
|
323
|
+
const hash = crypto__namespace.createHash("sha256").update(key).digest("hex");
|
|
324
|
+
return `${hash}.cache`;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Loads a cached item from disk.
|
|
328
|
+
*
|
|
329
|
+
* @param key - Cache key
|
|
330
|
+
* @returns Cached buffer or undefined if not found or expired
|
|
331
|
+
*/
|
|
332
|
+
async loadFromDisk(key) {
|
|
333
|
+
if (this.config.type !== "filesystem") return void 0;
|
|
334
|
+
const filename = this.getFilename(key);
|
|
335
|
+
const filepath = path__namespace.join(this.cacheDir, filename);
|
|
336
|
+
try {
|
|
337
|
+
try {
|
|
338
|
+
await fs__namespace.promises.access(filepath);
|
|
339
|
+
} catch {
|
|
340
|
+
return void 0;
|
|
341
|
+
}
|
|
342
|
+
const stats = await fs__namespace.promises.stat(filepath);
|
|
343
|
+
const age = Date.now() - stats.mtimeMs;
|
|
344
|
+
const ttl = this.config.ttl || DEFAULT_TTL;
|
|
345
|
+
if (age > ttl) {
|
|
346
|
+
await fs__namespace.promises.unlink(filepath).catch(() => {
|
|
347
|
+
});
|
|
348
|
+
return void 0;
|
|
349
|
+
}
|
|
350
|
+
const data = await fs__namespace.promises.readFile(filepath);
|
|
351
|
+
this.cache?.set(key, data);
|
|
352
|
+
return data;
|
|
353
|
+
} catch (error) {
|
|
354
|
+
return void 0;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Saves a cached item to disk.
|
|
359
|
+
*
|
|
360
|
+
* @param key - Cache key
|
|
361
|
+
* @param value - Buffer to save
|
|
362
|
+
*/
|
|
363
|
+
async saveToDisk(key, value) {
|
|
364
|
+
if (this.config.type !== "filesystem") return;
|
|
365
|
+
const filename = this.getFilename(key);
|
|
366
|
+
const filepath = path__namespace.join(this.cacheDir, filename);
|
|
367
|
+
try {
|
|
368
|
+
await fs__namespace.promises.writeFile(filepath, value);
|
|
369
|
+
} catch (error) {
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Loads all cached items from filesystem into memory on initialization.
|
|
374
|
+
*/
|
|
375
|
+
async cleanExpiredFiles() {
|
|
376
|
+
if (this.config.type !== "filesystem") return;
|
|
377
|
+
try {
|
|
378
|
+
const files = await fs__namespace.promises.readdir(this.cacheDir);
|
|
379
|
+
for (const file of files) {
|
|
380
|
+
if (!file.endsWith(".cache")) continue;
|
|
381
|
+
const filepath = path__namespace.join(this.cacheDir, file);
|
|
382
|
+
try {
|
|
383
|
+
const stats = await fs__namespace.promises.stat(filepath);
|
|
384
|
+
const age = Date.now() - stats.mtimeMs;
|
|
385
|
+
const ttl = this.config.ttl || DEFAULT_TTL;
|
|
386
|
+
if (age > ttl) {
|
|
387
|
+
await fs__namespace.promises.unlink(filepath).catch(() => {
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
} catch {
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
} catch (error) {
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Clears all files from the filesystem cache directory.
|
|
398
|
+
*/
|
|
399
|
+
async clearFilesystem() {
|
|
400
|
+
if (this.config.type !== "filesystem") return;
|
|
401
|
+
const cacheDir = this.cacheDir;
|
|
402
|
+
try {
|
|
403
|
+
const files = await fs__namespace.promises.readdir(cacheDir);
|
|
404
|
+
const unlinkPromises = files.map(async (file) => {
|
|
405
|
+
if (!file.endsWith(".cache")) return;
|
|
406
|
+
const filepath = path__namespace.join(cacheDir, file);
|
|
407
|
+
await fs__namespace.promises.unlink(filepath).catch(() => {
|
|
408
|
+
});
|
|
409
|
+
});
|
|
410
|
+
await Promise.all(unlinkPromises);
|
|
411
|
+
} catch (error) {
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
};
|
|
178
415
|
|
|
179
416
|
// src/utils/emoji-loader.ts
|
|
180
417
|
var ZERO_WIDTH_JOINER = String.fromCharCode(8205);
|
|
@@ -210,12 +447,15 @@ var apis = {
|
|
|
210
447
|
fluent: (code) => `https://cdn.jsdelivr.net/gh/shuding/fluentui-emoji-unicode/assets/${code.toLowerCase()}_color.svg`,
|
|
211
448
|
fluentFlat: (code) => `https://cdn.jsdelivr.net/gh/shuding/fluentui-emoji-unicode/assets/${code.toLowerCase()}_flat.svg`
|
|
212
449
|
};
|
|
213
|
-
var cache = {
|
|
450
|
+
var cache = new CacheManager({
|
|
451
|
+
type: "memory"
|
|
452
|
+
});
|
|
214
453
|
async function loadEmoji(type, text) {
|
|
215
454
|
const code = getIconCode(text);
|
|
216
455
|
const cacheKey = `${type}:${code}`;
|
|
217
|
-
|
|
218
|
-
|
|
456
|
+
const cached = await cache.get(cacheKey);
|
|
457
|
+
if (cached) {
|
|
458
|
+
return cached.toString();
|
|
219
459
|
}
|
|
220
460
|
if (!type || !apis[type]) {
|
|
221
461
|
type = "noto";
|
|
@@ -224,19 +464,22 @@ async function loadEmoji(type, text) {
|
|
|
224
464
|
const baseUrl = typeof api === "function" ? api(code) : api;
|
|
225
465
|
const fullUrl = typeof api === "function" ? baseUrl : `${baseUrl}${code.toUpperCase()}.svg`;
|
|
226
466
|
const emojiPromise = fetch(fullUrl).then((response) => response.text()).then((svgContent) => `data:image/svg+xml;base64,${btoa(svgContent)}`);
|
|
227
|
-
cache
|
|
467
|
+
await cache.set(cacheKey, Buffer.from(await emojiPromise));
|
|
228
468
|
return emojiPromise;
|
|
229
469
|
}
|
|
230
470
|
|
|
231
|
-
// src/utils/fetcher.ts
|
|
232
|
-
var cache2 = {
|
|
471
|
+
// src/utils/font-fetcher.ts
|
|
472
|
+
var cache2 = new CacheManager({
|
|
473
|
+
type: "memory"
|
|
474
|
+
});
|
|
233
475
|
var loadFontFromUrl = async (url) => {
|
|
234
|
-
|
|
235
|
-
|
|
476
|
+
const cachedFont = await cache2.get(url);
|
|
477
|
+
if (cachedFont) {
|
|
478
|
+
return cachedFont;
|
|
236
479
|
}
|
|
237
|
-
const fontData = fetch(url).then((response) => response.arrayBuffer());
|
|
238
|
-
cache2
|
|
239
|
-
return fontData;
|
|
480
|
+
const fontData = await fetch(url).then((response) => response.arrayBuffer());
|
|
481
|
+
await cache2.set(url, Buffer.from(fontData));
|
|
482
|
+
return Buffer.from(fontData);
|
|
240
483
|
};
|
|
241
484
|
|
|
242
485
|
// src/utils/additional-asset-loader.ts
|
|
@@ -314,11 +557,12 @@ var DEFAULT_HEIGHT = 630;
|
|
|
314
557
|
async function renderTemplate(template, params, options) {
|
|
315
558
|
const width = options?.width || DEFAULT_WIDTH;
|
|
316
559
|
const height = options?.height || DEFAULT_HEIGHT;
|
|
317
|
-
const
|
|
560
|
+
const fonts = options?.fonts?.length ? options.fonts : template.fonts;
|
|
561
|
+
const emojiProvider = options?.emojiProvider || template.emojiProvider || "noto";
|
|
562
|
+
const satoriFonts = await loadFonts(fonts);
|
|
318
563
|
const htmlString = await template.renderer({
|
|
319
564
|
params: typeof params === "function" ? await params() : params,
|
|
320
|
-
|
|
321
|
-
height
|
|
565
|
+
...options
|
|
322
566
|
});
|
|
323
567
|
const element = satoriHtml.html(htmlString);
|
|
324
568
|
const svg = await satori__default.default(element, {
|
|
@@ -337,32 +581,25 @@ async function renderTemplate(template, params, options) {
|
|
|
337
581
|
// Asset type ('emoji' or other)
|
|
338
582
|
segment,
|
|
339
583
|
// The character(s) to load
|
|
340
|
-
fonts
|
|
584
|
+
fonts,
|
|
341
585
|
// Available fonts for fallback detection
|
|
342
|
-
emojiProvider
|
|
586
|
+
emojiProvider
|
|
343
587
|
// Emoji provider (default: noto)
|
|
344
588
|
});
|
|
345
589
|
}
|
|
346
590
|
});
|
|
347
|
-
const
|
|
591
|
+
const pngData = await resvgJs.renderAsync(svg, {
|
|
348
592
|
fitTo: {
|
|
349
593
|
mode: "width",
|
|
350
594
|
// Scale based on width, maintain aspect ratio
|
|
351
595
|
value: width
|
|
352
596
|
}
|
|
353
597
|
});
|
|
354
|
-
const pngData = resvg.render();
|
|
355
598
|
return Buffer.from(pngData.asPng());
|
|
356
599
|
}
|
|
357
600
|
|
|
358
601
|
// src/renderer.ts
|
|
359
602
|
function validateTemplate(config) {
|
|
360
|
-
if (!config.id) {
|
|
361
|
-
throw new Error("Template must have an id");
|
|
362
|
-
}
|
|
363
|
-
if (!config.name) {
|
|
364
|
-
throw new Error("Template must have a name");
|
|
365
|
-
}
|
|
366
603
|
if (typeof config.renderer !== "function") {
|
|
367
604
|
throw new Error("Template must have a renderer function");
|
|
368
605
|
}
|
|
@@ -372,9 +609,14 @@ function defineTemplate(config) {
|
|
|
372
609
|
validateTemplate(config);
|
|
373
610
|
return config;
|
|
374
611
|
}
|
|
612
|
+
var DEFAULT_CACHE = {
|
|
613
|
+
type: "memory"
|
|
614
|
+
};
|
|
375
615
|
var TemplateRenderer = class {
|
|
376
616
|
/** Configuration including global settings and lifecycle hooks */
|
|
377
617
|
config;
|
|
618
|
+
/** Cache manager for fonts and icons */
|
|
619
|
+
cacheManager;
|
|
378
620
|
/**
|
|
379
621
|
* Internal registry mapping template IDs to template definitions.
|
|
380
622
|
*
|
|
@@ -383,7 +625,7 @@ var TemplateRenderer = class {
|
|
|
383
625
|
* - Guaranteed insertion order
|
|
384
626
|
* - Better memory efficiency than objects
|
|
385
627
|
*/
|
|
386
|
-
templates =
|
|
628
|
+
templates = {};
|
|
387
629
|
/**
|
|
388
630
|
* Creates a new TemplateRenderer instance.
|
|
389
631
|
*
|
|
@@ -391,6 +633,7 @@ var TemplateRenderer = class {
|
|
|
391
633
|
*/
|
|
392
634
|
constructor(config) {
|
|
393
635
|
this.config = config;
|
|
636
|
+
this.cacheManager = new CacheManager(config.cache || DEFAULT_CACHE);
|
|
394
637
|
this.registerTemplates(config.templates);
|
|
395
638
|
}
|
|
396
639
|
/**
|
|
@@ -399,12 +642,13 @@ var TemplateRenderer = class {
|
|
|
399
642
|
* Templates are indexed by their ID for fast lookup.
|
|
400
643
|
* If a template with the same ID already exists, it will be overwritten.
|
|
401
644
|
*
|
|
402
|
-
* @param templates -
|
|
645
|
+
* @param templates - Map of template definitions to register
|
|
403
646
|
*/
|
|
404
647
|
registerTemplates(templates) {
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
648
|
+
const keys = Object.keys(templates);
|
|
649
|
+
keys.forEach((key) => {
|
|
650
|
+
this.templates[key] = templates[key];
|
|
651
|
+
});
|
|
408
652
|
}
|
|
409
653
|
/**
|
|
410
654
|
* Retrieves a template by its unique ID.
|
|
@@ -418,20 +662,7 @@ var TemplateRenderer = class {
|
|
|
418
662
|
* @returns The template definition, or undefined if not found
|
|
419
663
|
*/
|
|
420
664
|
getTemplate(id) {
|
|
421
|
-
return this.templates
|
|
422
|
-
}
|
|
423
|
-
/**
|
|
424
|
-
* Gets all registered template IDs.
|
|
425
|
-
*
|
|
426
|
-
* Useful for:
|
|
427
|
-
* - Building template selection dropdowns
|
|
428
|
-
* - Listing available templates in documentation
|
|
429
|
-
* - Debugging template registration
|
|
430
|
-
*
|
|
431
|
-
* @returns Array of template IDs
|
|
432
|
-
*/
|
|
433
|
-
getTemplateIds() {
|
|
434
|
-
return Array.from(this.templates.keys());
|
|
665
|
+
return this.templates[id];
|
|
435
666
|
}
|
|
436
667
|
/**
|
|
437
668
|
* Renders a template to a PNG image buffer.
|
|
@@ -454,7 +685,7 @@ var TemplateRenderer = class {
|
|
|
454
685
|
* - Throws if rendering fails (font loading, HTML generation, etc.)
|
|
455
686
|
*
|
|
456
687
|
* @param templateId - ID of the template to render
|
|
457
|
-
* @param params - Parameters to pass to the template
|
|
688
|
+
* @param params - Parameters (or function returning params) to pass to the template
|
|
458
689
|
* @param options - Optional rendering options
|
|
459
690
|
* @param options.width - Custom image width in pixels (default: 1200)
|
|
460
691
|
* @param options.height - Custom image height in pixels (default: 630)
|
|
@@ -462,33 +693,69 @@ var TemplateRenderer = class {
|
|
|
462
693
|
* @throws Error if template is not found or rendering fails
|
|
463
694
|
*/
|
|
464
695
|
async renderToImage(templateId, params, options) {
|
|
465
|
-
const {
|
|
696
|
+
const { sharedParams } = this.config;
|
|
466
697
|
const template = this.getTemplate(templateId);
|
|
467
698
|
if (!template) {
|
|
468
699
|
throw new Error(`Template '${templateId}' not found`);
|
|
469
700
|
}
|
|
470
701
|
const mergedParams = {
|
|
471
|
-
...typeof
|
|
472
|
-
...typeof params === "function" ? await params() : params
|
|
702
|
+
...typeof sharedParams === "function" ? await sharedParams() : sharedParams || {},
|
|
703
|
+
...typeof params === "function" ? await params() : params || {}
|
|
473
704
|
};
|
|
705
|
+
const cacheKey = this.cacheManager.generateKey({
|
|
706
|
+
templateId,
|
|
707
|
+
...mergedParams,
|
|
708
|
+
...options
|
|
709
|
+
});
|
|
710
|
+
const cached = await this.cacheManager.get(cacheKey);
|
|
711
|
+
if (cached) {
|
|
712
|
+
return cached;
|
|
713
|
+
}
|
|
474
714
|
if (this.config.beforeRender) {
|
|
475
715
|
await this.config.beforeRender(templateId, mergedParams);
|
|
476
716
|
}
|
|
477
717
|
const imageBuffer = await renderTemplate(template, mergedParams, options);
|
|
718
|
+
await this.cacheManager.set(cacheKey, imageBuffer);
|
|
478
719
|
if (this.config.afterRender) {
|
|
479
720
|
await this.config.afterRender(templateId, mergedParams, imageBuffer);
|
|
480
721
|
}
|
|
481
722
|
return imageBuffer;
|
|
482
723
|
}
|
|
483
724
|
};
|
|
484
|
-
function
|
|
725
|
+
function createRenderer(config) {
|
|
485
726
|
return new TemplateRenderer(config);
|
|
486
727
|
}
|
|
487
|
-
|
|
728
|
+
|
|
729
|
+
// src/utils/clsx.ts
|
|
730
|
+
function clsx(...inputs) {
|
|
731
|
+
var i = 0, tmp, str = "", len = inputs.length;
|
|
732
|
+
for (; i < len; i++) {
|
|
733
|
+
if (tmp = inputs[i]) {
|
|
734
|
+
if (typeof tmp === "string") {
|
|
735
|
+
str += (str && " ") + tmp;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
return str;
|
|
740
|
+
}
|
|
741
|
+
var objectToStyle = (style, options) => {
|
|
742
|
+
if (!style) {
|
|
743
|
+
return "";
|
|
744
|
+
}
|
|
745
|
+
const { isRTL = false } = options || {};
|
|
746
|
+
return Object.entries(isRTL ? rtlCSSJS__default.default(style) : style).filter(([_, value]) => value !== void 0 && value !== null && value !== "").map(([key, value]) => {
|
|
747
|
+
if (value || value === 0) {
|
|
748
|
+
const cssKey = key.startsWith("--") ? key : key.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
749
|
+
return `${cssKey}:${value}`;
|
|
750
|
+
}
|
|
751
|
+
return "";
|
|
752
|
+
}).filter(Boolean).join(";");
|
|
753
|
+
};
|
|
488
754
|
|
|
489
755
|
exports.TemplateRenderer = TemplateRenderer;
|
|
490
|
-
exports.
|
|
756
|
+
exports.clsx = clsx;
|
|
757
|
+
exports.createRenderer = createRenderer;
|
|
491
758
|
exports.defineTemplate = defineTemplate;
|
|
492
|
-
exports.
|
|
759
|
+
exports.objectToStyle = objectToStyle;
|
|
493
760
|
exports.renderTemplate = renderTemplate;
|
|
494
761
|
exports.validateTemplate = validateTemplate;
|