@adminforth/upload 1.0.18 → 1.0.20
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/custom/imageGenerator.vue +4 -3
- package/dist/custom/imageGenerator.vue +4 -3
- package/dist/index.js +11 -2
- package/index.ts +14 -1
- package/package.json +1 -1
- package/types.ts +19 -0
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
|
|
104
104
|
<script setup lang="ts">
|
|
105
105
|
|
|
106
|
-
import { ref, onMounted } from 'vue'
|
|
106
|
+
import { ref, onMounted, nextTick } from 'vue'
|
|
107
107
|
import { Carousel } from 'flowbite';
|
|
108
108
|
import { callAdminForthApi } from '@/utils';
|
|
109
109
|
|
|
@@ -184,6 +184,7 @@ async function generateImages() {
|
|
|
184
184
|
variant: 'danger',
|
|
185
185
|
timeout: 15,
|
|
186
186
|
});
|
|
187
|
+
loading.value = false;
|
|
187
188
|
return;
|
|
188
189
|
}
|
|
189
190
|
|
|
@@ -196,7 +197,7 @@ async function generateImages() {
|
|
|
196
197
|
// 'https://via.placeholder.com/600x400?text=Image+1',
|
|
197
198
|
// 'https://via.placeholder.com/600x400?text=Image+2',
|
|
198
199
|
// ];
|
|
199
|
-
await
|
|
200
|
+
await nextTick();
|
|
200
201
|
|
|
201
202
|
caurosel.value = new Carousel(
|
|
202
203
|
document.getElementById('gallery'),
|
|
@@ -212,7 +213,7 @@ async function generateImages() {
|
|
|
212
213
|
override: true,
|
|
213
214
|
}
|
|
214
215
|
);
|
|
215
|
-
await
|
|
216
|
+
await nextTick();
|
|
216
217
|
loading.value = false;
|
|
217
218
|
}
|
|
218
219
|
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
|
|
104
104
|
<script setup lang="ts">
|
|
105
105
|
|
|
106
|
-
import { ref, onMounted } from 'vue'
|
|
106
|
+
import { ref, onMounted, nextTick } from 'vue'
|
|
107
107
|
import { Carousel } from 'flowbite';
|
|
108
108
|
import { callAdminForthApi } from '@/utils';
|
|
109
109
|
|
|
@@ -184,6 +184,7 @@ async function generateImages() {
|
|
|
184
184
|
variant: 'danger',
|
|
185
185
|
timeout: 15,
|
|
186
186
|
});
|
|
187
|
+
loading.value = false;
|
|
187
188
|
return;
|
|
188
189
|
}
|
|
189
190
|
|
|
@@ -196,7 +197,7 @@ async function generateImages() {
|
|
|
196
197
|
// 'https://via.placeholder.com/600x400?text=Image+1',
|
|
197
198
|
// 'https://via.placeholder.com/600x400?text=Image+2',
|
|
198
199
|
// ];
|
|
199
|
-
await
|
|
200
|
+
await nextTick();
|
|
200
201
|
|
|
201
202
|
caurosel.value = new Carousel(
|
|
202
203
|
document.getElementById('gallery'),
|
|
@@ -212,7 +213,7 @@ async function generateImages() {
|
|
|
212
213
|
override: true,
|
|
213
214
|
}
|
|
214
215
|
);
|
|
215
|
-
await
|
|
216
|
+
await nextTick();
|
|
216
217
|
loading.value = false;
|
|
217
218
|
}
|
|
218
219
|
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,7 @@ import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
|
|
11
11
|
import { ExpirationStatus, GetObjectCommand, PutObjectCommand, S3 } from '@aws-sdk/client-s3';
|
|
12
12
|
import { AdminForthPlugin, suggestIfTypo } from "adminforth";
|
|
13
13
|
import { Readable } from "stream";
|
|
14
|
+
import { RateLimiter, getClientIp } from "adminforth";
|
|
14
15
|
const ADMINFORTH_NOT_YET_USED_TAG = 'adminforth-candidate-for-cleanup';
|
|
15
16
|
export default class UploadPlugin extends AdminForthPlugin {
|
|
16
17
|
constructor(options) {
|
|
@@ -409,11 +410,19 @@ export default class UploadPlugin extends AdminForthPlugin {
|
|
|
409
410
|
server.endpoint({
|
|
410
411
|
method: 'POST',
|
|
411
412
|
path: `/plugin/${this.pluginInstanceId}/generate_images`,
|
|
412
|
-
handler: (_c) => __awaiter(this, [_c], void 0, function* ({ body }) {
|
|
413
|
+
handler: (_c) => __awaiter(this, [_c], void 0, function* ({ body, headers }) {
|
|
414
|
+
var _d, _e;
|
|
413
415
|
const { prompt } = body;
|
|
414
416
|
if (this.options.generation.provider !== 'openai-dall-e') {
|
|
415
417
|
throw new Error(`Provider ${this.options.generation.provider} is not supported`);
|
|
416
418
|
}
|
|
419
|
+
if ((_d = this.options.generation.rateLimit) === null || _d === void 0 ? void 0 : _d.limit) {
|
|
420
|
+
// rate limit
|
|
421
|
+
const { error } = RateLimiter.checkRateLimit(this.pluginInstanceId, (_e = this.options.generation.rateLimit) === null || _e === void 0 ? void 0 : _e.limit, getClientIp(headers));
|
|
422
|
+
if (error) {
|
|
423
|
+
return { error: this.options.generation.rateLimit.errorMessage };
|
|
424
|
+
}
|
|
425
|
+
}
|
|
417
426
|
const { model, size, apiKey } = this.options.generation.openAiOptions;
|
|
418
427
|
const url = 'https://api.openai.com/v1/images/generations';
|
|
419
428
|
let error = null;
|
|
@@ -445,7 +454,7 @@ export default class UploadPlugin extends AdminForthPlugin {
|
|
|
445
454
|
server.endpoint({
|
|
446
455
|
method: 'GET',
|
|
447
456
|
path: `/plugin/${this.pluginInstanceId}/cors-proxy`,
|
|
448
|
-
handler: (
|
|
457
|
+
handler: (_f) => __awaiter(this, [_f], void 0, function* ({ query, response }) {
|
|
449
458
|
const { url } = query;
|
|
450
459
|
const resp = yield fetch(url);
|
|
451
460
|
response.setHeader('Content-Type', resp.headers.get('Content-Type'));
|
package/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
|
|
4
4
|
import { ExpirationStatus, GetObjectCommand, ObjectCannedACL, PutObjectCommand, S3 } from '@aws-sdk/client-s3';
|
|
5
5
|
import { AdminForthPlugin, AdminForthResourceColumn, AdminForthResourcePages, IAdminForth, IHttpServer, suggestIfTypo } from "adminforth";
|
|
6
6
|
import { Readable } from "stream";
|
|
7
|
+
import { RateLimiter, getClientIp } from "adminforth";
|
|
7
8
|
|
|
8
9
|
const ADMINFORTH_NOT_YET_USED_TAG = 'adminforth-candidate-for-cleanup';
|
|
9
10
|
|
|
@@ -451,13 +452,25 @@ export default class UploadPlugin extends AdminForthPlugin {
|
|
|
451
452
|
server.endpoint({
|
|
452
453
|
method: 'POST',
|
|
453
454
|
path: `/plugin/${this.pluginInstanceId}/generate_images`,
|
|
454
|
-
handler: async ({ body }) => {
|
|
455
|
+
handler: async ({ body, headers }) => {
|
|
455
456
|
const { prompt } = body;
|
|
456
457
|
|
|
457
458
|
if (this.options.generation.provider !== 'openai-dall-e') {
|
|
458
459
|
throw new Error(`Provider ${this.options.generation.provider} is not supported`);
|
|
459
460
|
}
|
|
460
461
|
|
|
462
|
+
if (this.options.generation.rateLimit?.limit) {
|
|
463
|
+
// rate limit
|
|
464
|
+
const { error } = RateLimiter.checkRateLimit(
|
|
465
|
+
this.pluginInstanceId,
|
|
466
|
+
this.options.generation.rateLimit?.limit,
|
|
467
|
+
getClientIp(headers),
|
|
468
|
+
);
|
|
469
|
+
if (error) {
|
|
470
|
+
return { error: this.options.generation.rateLimit.errorMessage };
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
461
474
|
const { model, size, apiKey } = this.options.generation.openAiOptions;
|
|
462
475
|
const url = 'https://api.openai.com/v1/images/generations';
|
|
463
476
|
|
package/package.json
CHANGED
package/types.ts
CHANGED
|
@@ -128,6 +128,25 @@ export type PluginOptions = {
|
|
|
128
128
|
* where plugin is used.
|
|
129
129
|
*/
|
|
130
130
|
fieldsForContext? : string[],
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Since AI generation can be expensive, we can limit the number of requests per IP.
|
|
135
|
+
*/
|
|
136
|
+
rateLimit?: {
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* E.g. 5/1d - 5 requests per day
|
|
140
|
+
* 3/1h - 3 requests per hour
|
|
141
|
+
*/
|
|
142
|
+
limit: string,
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* !Not used now
|
|
146
|
+
* Message shown to user when rate limit is reached
|
|
147
|
+
*/
|
|
148
|
+
errorMessage: string,
|
|
149
|
+
},
|
|
131
150
|
}
|
|
132
151
|
|
|
133
152
|
}
|