@azuro-org/images-generator 1.3.15 → 2.0.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 +179 -98
- package/dist/generator.d.ts +31 -0
- package/dist/{index-82868da9.js → index-6ec143bc.js} +2047 -1394
- package/dist/index.d.ts +1 -1
- package/dist/index.es.js +238 -128
- package/dist/templates/bet-nft/index.js +1 -1
- package/dist/templates/bet-og/index.js +1 -1
- package/dist/templates/combo-bet-og/index.js +1 -1
- package/dist/templates/freebet/index.js +1 -1
- package/dist/templates/trendle-leaderboard/index.js +1 -1
- package/dist/templates/trendle-social/index.js +1 -1
- package/dist/templates/trendle-trading/index.js +1 -1
- package/lib/generator.d.ts +31 -0
- package/lib/{index-de0b52f4.js → index-efa024cc.js} +2047 -1394
- package/lib/index.d.ts +1 -1
- package/lib/index.js +238 -128
- package/lib/templates/bet-nft/index.js +1 -1
- package/lib/templates/bet-og/index.js +1 -1
- package/lib/templates/combo-bet-og/index.js +1 -1
- package/lib/templates/freebet/index.js +1 -1
- package/lib/templates/trendle-leaderboard/index.js +1 -1
- package/lib/templates/trendle-social/index.js +1 -1
- package/lib/templates/trendle-trading/index.js +1 -1
- package/package.json +1 -1
- package/dist/utils/generateImage.d.ts +0 -17
- package/lib/utils/generateImage.d.ts +0 -17
package/README.md
CHANGED
|
@@ -1,80 +1,152 @@
|
|
|
1
1
|
# @azuro-org/images-generator
|
|
2
2
|
|
|
3
|
+
Puppeteer-based image generator: render HTML templates to PNG/JPEG. Uses a shared browser instance; relaunches automatically if the browser disconnects.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @azuro-org/images-generator
|
|
9
|
+
```
|
|
10
|
+
|
|
3
11
|
## Usage
|
|
4
12
|
|
|
13
|
+
Create a `Generator` instance, call `run()` to start the browser, then use `generate()` for each image. Call `shutdown()` when done to close the browser.
|
|
14
|
+
|
|
5
15
|
```typescript
|
|
6
|
-
import {
|
|
7
|
-
import template
|
|
16
|
+
import { Generator } from '@azuro-org/images-generator';
|
|
17
|
+
import template from '@azuro-org/images-generator/lib/templates/bet-nft';
|
|
8
18
|
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
19
|
+
const generator = new Generator();
|
|
20
|
+
|
|
21
|
+
await generator.run();
|
|
12
22
|
|
|
13
|
-
//
|
|
14
|
-
const buffer =
|
|
23
|
+
// Single image – returns Uint8Array
|
|
24
|
+
const buffer = await generator.generate({
|
|
15
25
|
template,
|
|
16
|
-
props,
|
|
17
|
-
})
|
|
26
|
+
props: { /* ... */ },
|
|
27
|
+
});
|
|
18
28
|
|
|
19
|
-
//
|
|
20
|
-
|
|
29
|
+
// Save to file
|
|
30
|
+
await generator.generate({
|
|
21
31
|
template,
|
|
22
|
-
props,
|
|
32
|
+
props: { /* ... */ },
|
|
23
33
|
output: './dist',
|
|
24
|
-
|
|
34
|
+
filename: 'my-image',
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
await generator.shutdown();
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Batch generation with shutdown
|
|
41
|
+
|
|
42
|
+
Run multiple generations in parallel and close the browser when finished:
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
await generator.run();
|
|
46
|
+
|
|
47
|
+
await Promise.all([
|
|
48
|
+
generator.generate({ template, props: props1, output: './dist', filename: 'image-1' }),
|
|
49
|
+
generator.generate({ template, props: props2, output: './dist', filename: 'image-2' }),
|
|
50
|
+
]).finally(() => {
|
|
51
|
+
generator.shutdown();
|
|
52
|
+
});
|
|
25
53
|
```
|
|
26
54
|
|
|
27
|
-
|
|
55
|
+
### Auto-recovery
|
|
56
|
+
|
|
57
|
+
If the browser process exits or crashes, the next `generate()` call will launch a new browser automatically. You can also call `run()` again after a disconnect.
|
|
58
|
+
|
|
59
|
+
## API
|
|
60
|
+
|
|
61
|
+
### `Generator`
|
|
62
|
+
|
|
63
|
+
**Constructor**
|
|
28
64
|
|
|
29
65
|
```typescript
|
|
30
|
-
|
|
66
|
+
const generator = new Generator(options?: GeneratorOptions);
|
|
67
|
+
|
|
68
|
+
interface GeneratorOptions {
|
|
69
|
+
headless?: boolean; // default: true
|
|
70
|
+
timeout?: number; // default: 30000 (ms)
|
|
71
|
+
args?: string[]; // extra Chromium args
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Methods**
|
|
76
|
+
|
|
77
|
+
- **`run(): Promise<void>`** — Launches the browser. Idempotent if already running.
|
|
78
|
+
- **`generate<P>(props: GenerateProps<P>): Promise<Uint8Array>`** — Renders the template with the given props. Ensures the browser is running (calls `run()` if needed).
|
|
79
|
+
- **`shutdown(): Promise<void>`** — Closes the browser and cleans up.
|
|
80
|
+
|
|
81
|
+
### `generate()` options
|
|
31
82
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
83
|
+
```typescript
|
|
84
|
+
interface GenerateProps<P> {
|
|
85
|
+
template: Template<P>;
|
|
86
|
+
props: P;
|
|
87
|
+
output?: string; // folder path for the output file
|
|
88
|
+
filename?: string; // file name without extension (used with output)
|
|
89
|
+
options?: GenerateOptions;
|
|
36
90
|
}
|
|
37
91
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
92
|
+
interface GenerateOptions {
|
|
93
|
+
quality?: number; // JPEG quality, default 85
|
|
94
|
+
fullPage?: boolean; // default false
|
|
95
|
+
waitForFonts?: boolean; // default true
|
|
96
|
+
waitTimeout?: number; // ms, default 2000
|
|
97
|
+
waitUntil?: 'load' | 'domcontentloaded' | 'networkidle0' | 'networkidle2'; // default 'domcontentloaded'
|
|
98
|
+
skipAnimations?: boolean; // default true
|
|
99
|
+
}
|
|
44
100
|
```
|
|
45
101
|
|
|
102
|
+
## Templates
|
|
103
|
+
|
|
104
|
+
Templates are in `lib/templates/<name>` (or `dist/templates/<name>` for ESM). Each template exports a default `Template` and a `Props` type.
|
|
105
|
+
|
|
106
|
+
| Template | Import path |
|
|
107
|
+
|--------------------|----------------------------------------------------------|
|
|
108
|
+
| Bet NFT | `@azuro-org/images-generator/lib/templates/bet-nft` |
|
|
109
|
+
| Bet OG | `@azuro-org/images-generator/lib/templates/bet-og` |
|
|
110
|
+
| Combo Bet OG | `@azuro-org/images-generator/lib/templates/combo-bet-og` |
|
|
111
|
+
| Freebet | `@azuro-org/images-generator/lib/templates/freebet` |
|
|
112
|
+
| Trendle Leaderboard| `@azuro-org/images-generator/lib/templates/trendle-leaderboard` |
|
|
113
|
+
| Trendle Social | `@azuro-org/images-generator/lib/templates/trendle-social` |
|
|
114
|
+
| Trendle Trading | `@azuro-org/images-generator/lib/templates/trendle-trading` |
|
|
46
115
|
|
|
47
|
-
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Examples
|
|
48
119
|
|
|
49
120
|
<details>
|
|
50
121
|
<summary><b>Bet Opengraph</b></summary>
|
|
51
122
|
<p>
|
|
52
123
|
|
|
53
124
|
```typescript
|
|
54
|
-
import {
|
|
125
|
+
import { Generator } from '@azuro-org/images-generator';
|
|
55
126
|
import template from '@azuro-org/images-generator/lib/templates/bet-og';
|
|
56
127
|
|
|
57
|
-
|
|
128
|
+
const generator = new Generator();
|
|
129
|
+
await generator.run();
|
|
130
|
+
|
|
131
|
+
await generator.generate({
|
|
58
132
|
template,
|
|
133
|
+
output: './dist',
|
|
134
|
+
filename: 'bet-og',
|
|
59
135
|
props: {
|
|
60
136
|
title: 'Decentralized betting is awesome!',
|
|
61
137
|
game: {
|
|
62
138
|
country: 'International Tournaments',
|
|
63
139
|
league: 'ESL Challenger League North America',
|
|
64
140
|
participants: [
|
|
65
|
-
{
|
|
66
|
-
|
|
67
|
-
image: 'https://content.bookmaker.xyz/avatars/provider-3/4757.png',
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
name: 'Los Grandes Academy',
|
|
71
|
-
image: 'https://content.bookmaker.xyz/avatars/provider-3/4739.png',
|
|
72
|
-
},
|
|
141
|
+
{ name: 'WINDINGO', image: 'https://content.bookmaker.xyz/avatars/provider-3/4757.png' },
|
|
142
|
+
{ name: 'Los Grandes Academy', image: 'https://content.bookmaker.xyz/avatars/provider-3/4739.png' },
|
|
73
143
|
],
|
|
74
144
|
startsAt: Date.now(),
|
|
75
|
-
}
|
|
145
|
+
},
|
|
76
146
|
},
|
|
77
|
-
})
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
await generator.shutdown();
|
|
78
150
|
```
|
|
79
151
|
|
|
80
152
|
### Result
|
|
@@ -88,34 +160,27 @@ generateImage({
|
|
|
88
160
|
<p>
|
|
89
161
|
|
|
90
162
|
```typescript
|
|
91
|
-
import {
|
|
163
|
+
import { Generator } from '@azuro-org/images-generator';
|
|
92
164
|
import template from '@azuro-org/images-generator/lib/templates/combo-bet-og';
|
|
93
165
|
|
|
94
|
-
|
|
166
|
+
const generator = new Generator();
|
|
167
|
+
await generator.run();
|
|
168
|
+
|
|
169
|
+
await generator.generate({
|
|
95
170
|
template,
|
|
171
|
+
output: './dist',
|
|
172
|
+
filename: 'combo-bet-og',
|
|
96
173
|
props: {
|
|
97
174
|
title: 'Decentralized betting is awesome!',
|
|
98
175
|
data: {
|
|
99
176
|
totalOdds: 1.57,
|
|
100
177
|
possiblePayout: 1017.17,
|
|
101
178
|
asset: 'USDT',
|
|
102
|
-
}
|
|
179
|
+
},
|
|
103
180
|
},
|
|
104
|
-
})
|
|
181
|
+
});
|
|
105
182
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
generateImage({
|
|
109
|
-
template,
|
|
110
|
-
props: {
|
|
111
|
-
title: 'Decentralized betting is awesome!',
|
|
112
|
-
data: {
|
|
113
|
-
totalOdds: 1.57,
|
|
114
|
-
payout: 500,
|
|
115
|
-
asset: 'USDT',
|
|
116
|
-
}
|
|
117
|
-
},
|
|
118
|
-
})
|
|
183
|
+
await generator.shutdown();
|
|
119
184
|
```
|
|
120
185
|
|
|
121
186
|
### Result
|
|
@@ -129,30 +194,31 @@ generateImage({
|
|
|
129
194
|
<p>
|
|
130
195
|
|
|
131
196
|
```typescript
|
|
132
|
-
import {
|
|
197
|
+
import { Generator } from '@azuro-org/images-generator';
|
|
133
198
|
import template from '@azuro-org/images-generator/lib/templates/bet-nft';
|
|
134
199
|
|
|
135
|
-
|
|
200
|
+
const generator = new Generator();
|
|
201
|
+
await generator.run();
|
|
202
|
+
|
|
203
|
+
await generator.generate({
|
|
136
204
|
template,
|
|
205
|
+
output: './dist',
|
|
206
|
+
filename: 'bet-nft',
|
|
137
207
|
props: {
|
|
138
208
|
type: 'match',
|
|
139
209
|
sport: 'Football',
|
|
140
210
|
league: 'International Tournaments · FIFA - World Cup',
|
|
141
|
-
team1: {
|
|
142
|
-
|
|
143
|
-
name: 'Ecuador',
|
|
144
|
-
},
|
|
145
|
-
team2: {
|
|
146
|
-
img: 'https://content.bookmaker.xyz/avatars/provider-3/4739.png',
|
|
147
|
-
name: 'Senegal',
|
|
148
|
-
},
|
|
211
|
+
team1: { img: 'https://content.bookmaker.xyz/avatars/provider-3/4757.png', name: 'Ecuador' },
|
|
212
|
+
team2: { img: 'https://content.bookmaker.xyz/avatars/provider-3/4739.png', name: 'Senegal' },
|
|
149
213
|
date: 'Dec 24, 2020',
|
|
150
214
|
betAmount: '100 xDAI',
|
|
151
215
|
outcome: 'Senegal',
|
|
152
216
|
betOdds: '1.7',
|
|
153
217
|
currentOdds: '1.2',
|
|
154
218
|
},
|
|
155
|
-
})
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
await generator.shutdown();
|
|
156
222
|
```
|
|
157
223
|
|
|
158
224
|
### Result
|
|
@@ -162,20 +228,27 @@ generateImage({
|
|
|
162
228
|
</details>
|
|
163
229
|
|
|
164
230
|
<details>
|
|
165
|
-
<summary><b>
|
|
231
|
+
<summary><b>Freebet</b></summary>
|
|
166
232
|
<p>
|
|
167
233
|
|
|
168
234
|
```typescript
|
|
169
|
-
import {
|
|
235
|
+
import { Generator } from '@azuro-org/images-generator';
|
|
170
236
|
import template from '@azuro-org/images-generator/lib/templates/freebet';
|
|
171
237
|
|
|
172
|
-
|
|
238
|
+
const generator = new Generator();
|
|
239
|
+
await generator.run();
|
|
240
|
+
|
|
241
|
+
await generator.generate({
|
|
173
242
|
template,
|
|
243
|
+
output: './dist',
|
|
244
|
+
filename: 'freebet',
|
|
174
245
|
props: {
|
|
175
246
|
amount: '5 xDAI',
|
|
176
247
|
date: '12.01.2022',
|
|
177
248
|
},
|
|
178
|
-
})
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
await generator.shutdown();
|
|
179
252
|
```
|
|
180
253
|
|
|
181
254
|
### Result
|
|
@@ -184,53 +257,61 @@ generateImage({
|
|
|
184
257
|
</p>
|
|
185
258
|
</details>
|
|
186
259
|
|
|
260
|
+
---
|
|
187
261
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
## Add new template
|
|
262
|
+
## Contributing
|
|
191
263
|
|
|
192
|
-
|
|
193
|
-
3. Use `index.html` for HTML. Write CSS in `index.html` file.
|
|
194
|
-
4. Create `templates/{your_template_name}/images` folder for images if required.
|
|
264
|
+
### Add a new template
|
|
195
265
|
|
|
266
|
+
1. Copy `src/templates/_template` to `src/templates/{your_template_name}`.
|
|
267
|
+
2. Put layout and styles in `index.html`.
|
|
268
|
+
3. Add a `images` folder for static assets if needed.
|
|
196
269
|
|
|
197
|
-
|
|
270
|
+
### Template definition
|
|
198
271
|
|
|
199
|
-
|
|
272
|
+
Use `Template<Props>`, `getBase64Image`, and `downloadImage` from `../../utils`:
|
|
200
273
|
|
|
201
274
|
```typescript
|
|
202
|
-
import
|
|
203
|
-
|
|
204
|
-
import { type Template, getFile, downloadImage, createGenerator } from '../../utils'
|
|
275
|
+
import { type Template, downloadImage } from '../../utils';
|
|
276
|
+
import html from './index.html';
|
|
205
277
|
|
|
206
278
|
export type Props = {
|
|
207
|
-
team1ImageSrc: string
|
|
208
|
-
team2ImageSrc: string
|
|
209
|
-
date: string
|
|
210
|
-
}
|
|
279
|
+
team1ImageSrc: string;
|
|
280
|
+
team2ImageSrc: string;
|
|
281
|
+
date: string;
|
|
282
|
+
};
|
|
211
283
|
|
|
212
|
-
const template = {
|
|
284
|
+
const template: Template<Props> = {
|
|
213
285
|
width: 800,
|
|
214
286
|
height: 400,
|
|
215
287
|
type: 'jpeg',
|
|
216
288
|
html: async (props: Props) => {
|
|
217
|
-
const { team1ImageSrc, team2ImageSrc, date } = props
|
|
218
|
-
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
const team1Img = await downloadImage(team1ImageSrc)
|
|
222
|
-
const team2Img = await downloadImage(team2ImageSrc)
|
|
223
|
-
|
|
289
|
+
const { team1ImageSrc, team2ImageSrc, date } = props;
|
|
290
|
+
const team1Img = await downloadImage(team1ImageSrc);
|
|
291
|
+
const team2Img = await downloadImage(team2ImageSrc);
|
|
224
292
|
return html
|
|
225
293
|
.replace('{image1}', team1Img)
|
|
226
294
|
.replace('{image2}', team2Img)
|
|
227
|
-
.replace('{date}', date)
|
|
295
|
+
.replace('{date}', date);
|
|
228
296
|
},
|
|
229
|
-
}
|
|
297
|
+
};
|
|
230
298
|
|
|
231
|
-
export default template
|
|
299
|
+
export default template;
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
**Template shape**
|
|
303
|
+
|
|
304
|
+
```typescript
|
|
305
|
+
type Template<Props> = {
|
|
306
|
+
width: number;
|
|
307
|
+
height: number;
|
|
308
|
+
type: 'png' | 'jpeg';
|
|
309
|
+
html: (props: Props) => string | Promise<string>;
|
|
310
|
+
headless?: boolean;
|
|
311
|
+
scaleFactor?: 1 | 2;
|
|
312
|
+
};
|
|
232
313
|
```
|
|
233
314
|
|
|
234
|
-
|
|
315
|
+
### Publish
|
|
235
316
|
|
|
236
|
-
Publish
|
|
317
|
+
Publish with `npm publish`. For access to the `@azuro-org` scope, contact the maintainers.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type Template } from './utils';
|
|
2
|
+
interface GeneratorOptions {
|
|
3
|
+
headless?: boolean;
|
|
4
|
+
timeout?: number;
|
|
5
|
+
args?: string[];
|
|
6
|
+
}
|
|
7
|
+
interface GenerateOptions {
|
|
8
|
+
quality?: number;
|
|
9
|
+
fullPage?: boolean;
|
|
10
|
+
waitForFonts?: boolean;
|
|
11
|
+
waitTimeout?: number;
|
|
12
|
+
waitUntil?: 'load' | 'domcontentloaded' | 'networkidle0' | 'networkidle2';
|
|
13
|
+
skipAnimations?: boolean;
|
|
14
|
+
}
|
|
15
|
+
type GenerateProps<P> = {
|
|
16
|
+
template: Template<P>;
|
|
17
|
+
props: P;
|
|
18
|
+
output?: string;
|
|
19
|
+
filename?: string;
|
|
20
|
+
options?: GenerateOptions;
|
|
21
|
+
};
|
|
22
|
+
declare class Generator {
|
|
23
|
+
private browser;
|
|
24
|
+
private readonly options;
|
|
25
|
+
constructor(options?: GeneratorOptions);
|
|
26
|
+
run(): Promise<void>;
|
|
27
|
+
generate<P>(props: GenerateProps<P>): Promise<Uint8Array>;
|
|
28
|
+
shutdown(): Promise<void>;
|
|
29
|
+
private cleanup;
|
|
30
|
+
}
|
|
31
|
+
export default Generator;
|