@adminforth/bulk-ai-flow 1.13.1 → 1.14.1

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/build.log CHANGED
@@ -13,5 +13,5 @@ custom/package-lock.json
13
13
  custom/package.json
14
14
  custom/tsconfig.json
15
15
 
16
- sent 74,067 bytes received 172 bytes 148,478.00 bytes/sec
17
- total size is 73,426 speedup is 0.99
16
+ sent 74,113 bytes received 172 bytes 148,570.00 bytes/sec
17
+ total size is 73,472 speedup is 0.99
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="flex items-end justify-start gap-2 cursor-pointer" @click="openDialog">
2
+ <div class="flex items-end justify-start gap-2 cursor-pointer">
3
3
  <div class="flex items-center justify-center text-white bg-gradient-to-r h-[18px] from-purple-500 via-purple-600 to-purple-700 hover:bg-gradient-to-br focus:ring-4 focus:outline-none focus:ring-purple-300 dark:focus:ring-purple-800 font-medium rounded-md text-sm px-1 text-center">
4
4
  AI
5
5
  </div>
@@ -78,6 +78,10 @@ const props = defineProps<{
78
78
  }
79
79
  }>();
80
80
 
81
+ defineExpose({
82
+ click
83
+ });
84
+
81
85
  const confirmDialog = ref(null);
82
86
  const records = ref<any[]>([]);
83
87
  const images = ref<any[]>([]);
@@ -745,4 +749,8 @@ async function findPreviewURLForImages() {
745
749
  }
746
750
  }
747
751
 
752
+ function click() {
753
+ openDialog();
754
+ }
755
+
748
756
  </script>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="flex items-end justify-start gap-2 cursor-pointer" @click="openDialog">
2
+ <div class="flex items-end justify-start gap-2 cursor-pointer">
3
3
  <div class="flex items-center justify-center text-white bg-gradient-to-r h-[18px] from-purple-500 via-purple-600 to-purple-700 hover:bg-gradient-to-br focus:ring-4 focus:outline-none focus:ring-purple-300 dark:focus:ring-purple-800 font-medium rounded-md text-sm px-1 text-center">
4
4
  AI
5
5
  </div>
@@ -78,6 +78,10 @@ const props = defineProps<{
78
78
  }
79
79
  }>();
80
80
 
81
+ defineExpose({
82
+ click
83
+ });
84
+
81
85
  const confirmDialog = ref(null);
82
86
  const records = ref<any[]>([]);
83
87
  const images = ref<any[]>([]);
@@ -745,4 +749,8 @@ async function findPreviewURLForImages() {
745
749
  }
746
750
  }
747
751
 
752
+ function click() {
753
+ openDialog();
754
+ }
755
+
748
756
  </script>
package/dist/index.js CHANGED
@@ -80,6 +80,15 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
80
80
  return {};
81
81
  }
82
82
  else if (attachmentFiles.length !== 0) {
83
+ try {
84
+ for (const fileUrl of attachmentFiles) {
85
+ new URL(fileUrl);
86
+ }
87
+ }
88
+ catch (e) {
89
+ jobs.set(jobId, { status: 'failed', error: 'One of the image URLs is not valid' });
90
+ return { ok: false, error: 'One of the image URLs is not valid' };
91
+ }
83
92
  //create prompt for OpenAI
84
93
  const compiledOutputFields = this.compileOutputFieldsTemplates(record);
85
94
  const prompt = `Analyze the following image(s) and return a single JSON in format like: {'param1': 'value1', 'param2': 'value2'}.
@@ -107,7 +116,14 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
107
116
  jobs.set(jobId, { status: 'failed', error: 'Unexpected AI response format' });
108
117
  }
109
118
  //parse response and update record
110
- const resData = JSON.parse(textOutput);
119
+ let resData;
120
+ try {
121
+ resData = JSON.parse(textOutput);
122
+ }
123
+ catch (e) {
124
+ jobs.set(jobId, { status: 'failed', error: 'AI response is not valid JSON. Probably attached invalid image URL' });
125
+ return { ok: false, error: 'AI response is not valid JSON. Probably attached invalid image URL' };
126
+ }
111
127
  const result = resData;
112
128
  jobs.set(jobId, { status: 'completed', result });
113
129
  return { ok: true };
@@ -174,6 +190,15 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
174
190
  }
175
191
  else {
176
192
  attachmentFiles = yield this.options.attachFiles({ record });
193
+ try {
194
+ for (const fileUrl of attachmentFiles) {
195
+ new URL(fileUrl);
196
+ }
197
+ }
198
+ catch (e) {
199
+ jobs.set(jobId, { status: 'failed', error: 'One of the image URLs is not valid' });
200
+ return { ok: false, error: 'One of the image URLs is not valid' };
201
+ }
177
202
  }
178
203
  const fieldTasks = Object.keys(((_b = this.options) === null || _b === void 0 ? void 0 : _b.generateImages) || {}).map((key) => __awaiter(this, void 0, void 0, function* () {
179
204
  const prompt = this.compileGenerationFieldTemplates(record)[key];
@@ -563,10 +588,10 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
563
588
  }
564
589
  catch (e) {
565
590
  // file might be e.g. already deleted, so we catch error
566
- console.error(`Error setting tag to true for object ${oldRecord[value]}. File will not be auto-cleaned up`, e);
591
+ console.error(`Error setting tag to true for object ${oldRecord[value]}. File will not be auto-cleaned up`);
567
592
  }
568
593
  }
569
- if (fieldsToUpdate[idx][key] && fieldsToUpdate[idx][key] !== null) {
594
+ if (fieldsToUpdate[idx][value] && fieldsToUpdate[idx][value] !== null) {
570
595
  // remove tag from new file
571
596
  // in this case we let it crash if it fails: this is a new file which just was uploaded.
572
597
  yield columnPlugin.pluginOptions.storageAdapter.markKeyForNotDeletation(fieldsToUpdate[idx][value]);
package/index.ts CHANGED
@@ -89,6 +89,14 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
89
89
  }
90
90
  return {};
91
91
  } else if (attachmentFiles.length !== 0) {
92
+ try {
93
+ for (const fileUrl of attachmentFiles) {
94
+ new URL(fileUrl);
95
+ }
96
+ } catch (e) {
97
+ jobs.set(jobId, { status: 'failed', error: 'One of the image URLs is not valid' });
98
+ return { ok: false, error: 'One of the image URLs is not valid' };
99
+ }
92
100
  //create prompt for OpenAI
93
101
  const compiledOutputFields = this.compileOutputFieldsTemplates(record);
94
102
  const prompt = `Analyze the following image(s) and return a single JSON in format like: {'param1': 'value1', 'param2': 'value2'}.
@@ -118,7 +126,13 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
118
126
  }
119
127
 
120
128
  //parse response and update record
121
- const resData = JSON.parse(textOutput);
129
+ let resData;
130
+ try {
131
+ resData = JSON.parse(textOutput);
132
+ } catch (e) {
133
+ jobs.set(jobId, { status: 'failed', error: 'AI response is not valid JSON. Probably attached invalid image URL' });
134
+ return { ok: false, error: 'AI response is not valid JSON. Probably attached invalid image URL' };
135
+ }
122
136
  const result = resData;
123
137
  jobs.set(jobId, { status: 'completed', result });
124
138
  return { ok: true };
@@ -180,6 +194,14 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
180
194
  attachmentFiles = [];
181
195
  } else {
182
196
  attachmentFiles = await this.options.attachFiles({ record });
197
+ try {
198
+ for (const fileUrl of attachmentFiles) {
199
+ new URL(fileUrl);
200
+ }
201
+ } catch (e) {
202
+ jobs.set(jobId, { status: 'failed', error: 'One of the image URLs is not valid' });
203
+ return { ok: false, error: 'One of the image URLs is not valid' };
204
+ }
183
205
  }
184
206
  const fieldTasks = Object.keys(this.options?.generateImages || {}).map(async (key) => {
185
207
  const prompt = this.compileGenerationFieldTemplates(record)[key];
@@ -591,10 +613,10 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
591
613
  await columnPlugin.pluginOptions.storageAdapter.markKeyForDeletation(oldRecord[value]);
592
614
  } catch (e) {
593
615
  // file might be e.g. already deleted, so we catch error
594
- console.error(`Error setting tag to true for object ${oldRecord[value]}. File will not be auto-cleaned up`, e);
616
+ console.error(`Error setting tag to true for object ${oldRecord[value]}. File will not be auto-cleaned up`);
595
617
  }
596
618
  }
597
- if (fieldsToUpdate[idx][key] && fieldsToUpdate[idx][key] !== null) {
619
+ if (fieldsToUpdate[idx][value] && fieldsToUpdate[idx][value] !== null) {
598
620
  // remove tag from new file
599
621
  // in this case we let it crash if it fails: this is a new file which just was uploaded.
600
622
  await columnPlugin.pluginOptions.storageAdapter.markKeyForNotDeletation(fieldsToUpdate[idx][value]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adminforth/bulk-ai-flow",
3
- "version": "1.13.1",
3
+ "version": "1.14.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -10,17 +10,48 @@
10
10
  "scripts": {
11
11
  "build": "tsc && rsync -av --exclude 'node_modules' custom dist/"
12
12
  },
13
- "keywords": [],
13
+ "keywords": [
14
+ "adminforth",
15
+ "bulk",
16
+ "ai",
17
+ "flow"
18
+ ],
14
19
  "author": "",
15
20
  "license": "ISC",
16
21
  "description": "",
17
22
  "devDependencies": {
18
23
  "@types/node": "latest",
24
+ "semantic-release": "^24.2.1",
25
+ "semantic-release-slack-bot": "^4.0.2",
19
26
  "typescript": "^5.7.3"
20
27
  },
21
28
  "dependencies": {
22
29
  "@types/handlebars": "^4.0.40",
23
- "adminforth": "^2.4.0-next.112",
30
+ "adminforth": "^2.4.0-next.127",
24
31
  "handlebars": "^4.7.8"
32
+ },
33
+ "release": {
34
+ "plugins": [
35
+ "@semantic-release/commit-analyzer",
36
+ "@semantic-release/release-notes-generator",
37
+ "@semantic-release/npm",
38
+ "@semantic-release/github",
39
+ [
40
+ "semantic-release-slack-bot",
41
+ {
42
+ "notifyOnSuccess": true,
43
+ "notifyOnFail": true,
44
+ "slackIcon": ":package:",
45
+ "markdownReleaseNotes": true
46
+ }
47
+ ]
48
+ ],
49
+ "branches": [
50
+ "main",
51
+ {
52
+ "name": "next",
53
+ "prerelease": true
54
+ }
55
+ ]
25
56
  }
26
57
  }