notes-to-strapi-export-article-ai 1.0.118 → 3.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/.eslintrc +30 -22
- package/README.md +98 -143
- package/images/img.png +0 -0
- package/images/img_1.png +0 -0
- package/images/img_10.png +0 -0
- package/images/img_11.png +0 -0
- package/images/img_12.png +0 -0
- package/images/img_13.png +0 -0
- package/images/img_2.png +0 -0
- package/images/img_3.png +0 -0
- package/images/img_4.png +0 -0
- package/images/img_5.png +0 -0
- package/images/img_6.png +0 -0
- package/images/img_7.png +0 -0
- package/images/img_8.png +0 -0
- package/images/img_9.png +0 -0
- package/manifest.json +2 -2
- package/package.json +29 -26
- package/src/components/APIKeys.ts +219 -0
- package/src/components/Configuration.ts +663 -0
- package/src/components/Dashboard.ts +184 -0
- package/src/components/ImageSelectionModal.ts +58 -0
- package/src/components/Routes.ts +279 -0
- package/src/constants.ts +22 -61
- package/src/main.ts +177 -34
- package/src/services/configuration-generator.ts +172 -0
- package/src/services/field-analyzer.ts +84 -0
- package/src/services/frontmatter.ts +329 -0
- package/src/services/strapi-export.ts +436 -0
- package/src/settings/UnifiedSettingsTab.ts +206 -0
- package/src/types/image.ts +27 -16
- package/src/types/index.ts +3 -0
- package/src/types/route.ts +51 -0
- package/src/types/settings.ts +22 -23
- package/src/utils/analyse-file.ts +94 -0
- package/src/utils/debounce.ts +34 -0
- package/src/utils/image-processor.ts +124 -400
- package/src/utils/preview-modal.ts +265 -0
- package/src/utils/process-file.ts +122 -0
- package/src/utils/strapi-uploader.ts +120 -119
- package/src/settings.ts +0 -404
- package/src/types/article.ts +0 -8
- package/src/utils/openai-generator.ts +0 -139
- package/src/utils/validators.ts +0 -8
- package/version-bump.mjs +0 -14
- package/versions.json +0 -118
package/src/settings.ts
DELETED
|
@@ -1,404 +0,0 @@
|
|
|
1
|
-
import { App, PluginSettingTab, Setting } from 'obsidian'
|
|
2
|
-
import StrapiExporterPlugin from './main'
|
|
3
|
-
import { validateJsonTemplate } from './utils/validators'
|
|
4
|
-
|
|
5
|
-
export class StrapiExporterSettingTab extends PluginSettingTab {
|
|
6
|
-
plugin: StrapiExporterPlugin
|
|
7
|
-
|
|
8
|
-
constructor(app: App, plugin: StrapiExporterPlugin) {
|
|
9
|
-
super(app, plugin)
|
|
10
|
-
this.plugin = plugin
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
display(): void {
|
|
14
|
-
const { containerEl } = this
|
|
15
|
-
containerEl.empty()
|
|
16
|
-
|
|
17
|
-
new Setting(containerEl)
|
|
18
|
-
.setName('Strapi URL')
|
|
19
|
-
.setDesc('Enter your Strapi instance URL')
|
|
20
|
-
.addText(text =>
|
|
21
|
-
text
|
|
22
|
-
.setPlaceholder('https://your-strapi-url')
|
|
23
|
-
.setValue(this.plugin.settings.strapiUrl)
|
|
24
|
-
.onChange(async value => {
|
|
25
|
-
this.plugin.settings.strapiUrl = value
|
|
26
|
-
await this.plugin.saveSettings()
|
|
27
|
-
})
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
new Setting(containerEl)
|
|
31
|
-
.setName('Strapi API token')
|
|
32
|
-
.setDesc('Enter your Strapi API token')
|
|
33
|
-
.addText(text =>
|
|
34
|
-
text
|
|
35
|
-
.setPlaceholder('Enter your token')
|
|
36
|
-
.setValue(this.plugin.settings.strapiApiToken)
|
|
37
|
-
.onChange(async value => {
|
|
38
|
-
this.plugin.settings.strapiApiToken = value
|
|
39
|
-
await this.plugin.saveSettings()
|
|
40
|
-
})
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
new Setting(containerEl)
|
|
44
|
-
.setName('OpenAI API key')
|
|
45
|
-
.setDesc('Enter your OpenAI API key for GPT-3')
|
|
46
|
-
.addText(text =>
|
|
47
|
-
text
|
|
48
|
-
.setPlaceholder('Enter your OpenAI API key')
|
|
49
|
-
.setValue(this.plugin.settings.openaiApiKey)
|
|
50
|
-
.onChange(async value => {
|
|
51
|
-
this.plugin.settings.openaiApiKey = value
|
|
52
|
-
await this.plugin.saveSettings()
|
|
53
|
-
})
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
new Setting(containerEl)
|
|
57
|
-
.setName('Additional prompt')
|
|
58
|
-
.setDesc(
|
|
59
|
-
'Enter an optional additional prompt to customize the article content generation'
|
|
60
|
-
)
|
|
61
|
-
.addTextArea(text =>
|
|
62
|
-
text
|
|
63
|
-
.setPlaceholder('Enter your additional prompt here...')
|
|
64
|
-
.setValue(this.plugin.settings.additionalPrompt)
|
|
65
|
-
.onChange(async value => {
|
|
66
|
-
this.plugin.settings.additionalPrompt = value
|
|
67
|
-
await this.plugin.saveSettings()
|
|
68
|
-
})
|
|
69
|
-
)
|
|
70
|
-
|
|
71
|
-
new Setting(containerEl).setName('Strapi settings - Call 1').setHeading()
|
|
72
|
-
|
|
73
|
-
new Setting(containerEl)
|
|
74
|
-
.setName('Strapi article create URL')
|
|
75
|
-
.setDesc('Enter the URL to create articles in Strapi')
|
|
76
|
-
.addText(text =>
|
|
77
|
-
text
|
|
78
|
-
.setPlaceholder('https://your-strapi-url/api/articles')
|
|
79
|
-
.setValue(this.plugin.settings.strapiArticleCreateUrl)
|
|
80
|
-
.onChange(async value => {
|
|
81
|
-
this.plugin.settings.strapiArticleCreateUrl = value
|
|
82
|
-
await this.plugin.saveSettings()
|
|
83
|
-
})
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
new Setting(containerEl)
|
|
87
|
-
.setName('JSON template')
|
|
88
|
-
.setDesc('Enter the JSON template for the fields needed')
|
|
89
|
-
.addTextArea(text =>
|
|
90
|
-
text
|
|
91
|
-
.setPlaceholder('Enter your JSON template')
|
|
92
|
-
.setValue(this.plugin.settings.jsonTemplate)
|
|
93
|
-
.onChange(async value => {
|
|
94
|
-
if (validateJsonTemplate(value)) {
|
|
95
|
-
this.plugin.settings.jsonTemplate = value
|
|
96
|
-
await this.plugin.saveSettings()
|
|
97
|
-
}
|
|
98
|
-
})
|
|
99
|
-
)
|
|
100
|
-
|
|
101
|
-
new Setting(containerEl)
|
|
102
|
-
.setName('JSON template description')
|
|
103
|
-
.setDesc('Enter the description for each field in the JSON template')
|
|
104
|
-
.addTextArea(text =>
|
|
105
|
-
text
|
|
106
|
-
.setPlaceholder('Enter the field descriptions')
|
|
107
|
-
.setValue(this.plugin.settings.jsonTemplateDescription)
|
|
108
|
-
.onChange(async value => {
|
|
109
|
-
this.plugin.settings.jsonTemplateDescription = value
|
|
110
|
-
await this.plugin.saveSettings()
|
|
111
|
-
})
|
|
112
|
-
)
|
|
113
|
-
|
|
114
|
-
new Setting(containerEl)
|
|
115
|
-
.setName('Strapi content attribute name')
|
|
116
|
-
.setDesc('Enter the attribute name for the content field in Strapi')
|
|
117
|
-
.addText(text =>
|
|
118
|
-
text
|
|
119
|
-
.setPlaceholder('content')
|
|
120
|
-
.setValue(this.plugin.settings.strapiContentAttributeName)
|
|
121
|
-
.onChange(async value => {
|
|
122
|
-
this.plugin.settings.strapiContentAttributeName = value
|
|
123
|
-
await this.plugin.saveSettings()
|
|
124
|
-
})
|
|
125
|
-
)
|
|
126
|
-
|
|
127
|
-
new Setting(containerEl).setName('Main image settings').setHeading()
|
|
128
|
-
|
|
129
|
-
new Setting(containerEl)
|
|
130
|
-
.setName('Enable main image')
|
|
131
|
-
.setDesc('Toggle the main image')
|
|
132
|
-
.addToggle(toggle =>
|
|
133
|
-
toggle
|
|
134
|
-
.setValue(this.plugin.settings.mainButtonImageEnabled)
|
|
135
|
-
.onChange(async value => {
|
|
136
|
-
this.plugin.settings.mainButtonImageEnabled = value
|
|
137
|
-
await this.plugin.saveSettings()
|
|
138
|
-
this.display()
|
|
139
|
-
})
|
|
140
|
-
)
|
|
141
|
-
|
|
142
|
-
if (this.plugin.settings.mainButtonImageEnabled) {
|
|
143
|
-
containerEl.createEl('p', {
|
|
144
|
-
text: 'For the plugin to detect images and galleries, ensure the following folder structure:',
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
containerEl.createEl('ul', {
|
|
148
|
-
text: '- Article file (e.g., article.md)',
|
|
149
|
-
})
|
|
150
|
-
containerEl.createEl('ul', {
|
|
151
|
-
text: '- Main image folder (name: image)',
|
|
152
|
-
})
|
|
153
|
-
|
|
154
|
-
containerEl.createEl('p', {
|
|
155
|
-
text: 'The plugin will detect images in the main image (for this api call)',
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
new Setting(containerEl)
|
|
159
|
-
.setName('Main image full path property')
|
|
160
|
-
.setDesc(
|
|
161
|
-
'Enter the full path property for the main image in the final call'
|
|
162
|
-
)
|
|
163
|
-
.addText(text =>
|
|
164
|
-
text
|
|
165
|
-
.setPlaceholder('data.attributes.image')
|
|
166
|
-
.setValue(this.plugin.settings.mainImageFullPathProperty)
|
|
167
|
-
.onChange(async value => {
|
|
168
|
-
this.plugin.settings.mainImageFullPathProperty = value
|
|
169
|
-
await this.plugin.saveSettings()
|
|
170
|
-
})
|
|
171
|
-
)
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
new Setting(containerEl).setName('Main gallery settings').setHeading()
|
|
175
|
-
|
|
176
|
-
new Setting(containerEl)
|
|
177
|
-
.setName('Enable main gallery')
|
|
178
|
-
.setDesc('Toggle the main gallery')
|
|
179
|
-
.addToggle(toggle =>
|
|
180
|
-
toggle
|
|
181
|
-
.setValue(this.plugin.settings.mainButtonGalleryEnabled)
|
|
182
|
-
.onChange(async value => {
|
|
183
|
-
this.plugin.settings.mainButtonGalleryEnabled = value
|
|
184
|
-
await this.plugin.saveSettings()
|
|
185
|
-
this.display()
|
|
186
|
-
})
|
|
187
|
-
)
|
|
188
|
-
|
|
189
|
-
if (this.plugin.settings.mainButtonGalleryEnabled) {
|
|
190
|
-
containerEl.createEl('p', {
|
|
191
|
-
text: 'For the plugin to detect galleries, ensure the following folder structure:',
|
|
192
|
-
})
|
|
193
|
-
|
|
194
|
-
containerEl.createEl('ul', {
|
|
195
|
-
text: '- Article file (e.g., article.md)',
|
|
196
|
-
})
|
|
197
|
-
containerEl.createEl('ul', {
|
|
198
|
-
text: '- Main gallery folder (name: gallery)',
|
|
199
|
-
})
|
|
200
|
-
|
|
201
|
-
containerEl.createEl('p', {
|
|
202
|
-
text: 'The plugin will detect images in the main gallery folders. (for this api call)',
|
|
203
|
-
})
|
|
204
|
-
|
|
205
|
-
new Setting(containerEl)
|
|
206
|
-
.setName('Main gallery full path property')
|
|
207
|
-
.setDesc(
|
|
208
|
-
'Enter the full path property for the main gallery in the final call'
|
|
209
|
-
)
|
|
210
|
-
.addText(text =>
|
|
211
|
-
text
|
|
212
|
-
.setPlaceholder('data.attributes.gallery')
|
|
213
|
-
.setValue(this.plugin.settings.mainGalleryFullPathProperty)
|
|
214
|
-
.onChange(async value => {
|
|
215
|
-
this.plugin.settings.mainGalleryFullPathProperty = value
|
|
216
|
-
await this.plugin.saveSettings()
|
|
217
|
-
})
|
|
218
|
-
)
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
new Setting(containerEl)
|
|
222
|
-
.setName('Strapi settings - Call 2 - Additional call')
|
|
223
|
-
.setHeading()
|
|
224
|
-
|
|
225
|
-
containerEl.createEl('p', {
|
|
226
|
-
text: `(Be careful, when enabling this feature, you'll need to restart Obsidian to see the additional button in the ribbon menu.)`,
|
|
227
|
-
})
|
|
228
|
-
|
|
229
|
-
new Setting(containerEl)
|
|
230
|
-
.setName('Enable additional call API')
|
|
231
|
-
.setDesc(
|
|
232
|
-
'Toggle the additional Call API, and display a new icon in the ribbon menu'
|
|
233
|
-
)
|
|
234
|
-
.addToggle(toggle =>
|
|
235
|
-
toggle
|
|
236
|
-
.setValue(this.plugin.settings.enableAdditionalApiCall)
|
|
237
|
-
.onChange(async value => {
|
|
238
|
-
this.plugin.settings.enableAdditionalApiCall = value
|
|
239
|
-
await this.plugin.saveSettings()
|
|
240
|
-
this.display()
|
|
241
|
-
})
|
|
242
|
-
)
|
|
243
|
-
|
|
244
|
-
if (this.plugin.settings.enableAdditionalApiCall) {
|
|
245
|
-
new Setting(containerEl)
|
|
246
|
-
.setName('Additional API URL')
|
|
247
|
-
.setDesc('Enter the URL to create content for the additional API')
|
|
248
|
-
.addText(text =>
|
|
249
|
-
text
|
|
250
|
-
.setPlaceholder('https://your-strapi-url/api/additional-content')
|
|
251
|
-
.setValue(this.plugin.settings.additionalUrl)
|
|
252
|
-
.onChange(async value => {
|
|
253
|
-
this.plugin.settings.additionalUrl = value
|
|
254
|
-
await this.plugin.saveSettings()
|
|
255
|
-
})
|
|
256
|
-
)
|
|
257
|
-
|
|
258
|
-
new Setting(containerEl)
|
|
259
|
-
.setName('Additional JSON template')
|
|
260
|
-
.setDesc(
|
|
261
|
-
'Enter the JSON template for the fields needed for the additional api'
|
|
262
|
-
)
|
|
263
|
-
.addTextArea(text =>
|
|
264
|
-
text
|
|
265
|
-
.setPlaceholder('Enter your JSON template')
|
|
266
|
-
.setValue(this.plugin.settings.additionalJsonTemplate)
|
|
267
|
-
.onChange(async value => {
|
|
268
|
-
if (validateJsonTemplate(value)) {
|
|
269
|
-
this.plugin.settings.additionalJsonTemplate = value
|
|
270
|
-
await this.plugin.saveSettings()
|
|
271
|
-
}
|
|
272
|
-
})
|
|
273
|
-
)
|
|
274
|
-
|
|
275
|
-
new Setting(containerEl)
|
|
276
|
-
.setName('Additional API JSON template description')
|
|
277
|
-
.setDesc(
|
|
278
|
-
'Enter the description for each field in the additional API JSON template'
|
|
279
|
-
)
|
|
280
|
-
.addTextArea(text =>
|
|
281
|
-
text
|
|
282
|
-
.setPlaceholder('Enter the field descriptions')
|
|
283
|
-
.setValue(this.plugin.settings.additionalJsonTemplateDescription)
|
|
284
|
-
.onChange(async value => {
|
|
285
|
-
this.plugin.settings.additionalJsonTemplateDescription = value
|
|
286
|
-
await this.plugin.saveSettings()
|
|
287
|
-
})
|
|
288
|
-
)
|
|
289
|
-
|
|
290
|
-
new Setting(containerEl)
|
|
291
|
-
.setName('Additional API content attribute name')
|
|
292
|
-
.setDesc(
|
|
293
|
-
'Enter the attribute name for the content field for the additional API'
|
|
294
|
-
)
|
|
295
|
-
.addText(text =>
|
|
296
|
-
text
|
|
297
|
-
.setPlaceholder('content')
|
|
298
|
-
.setValue(this.plugin.settings.additionalContentAttributeName)
|
|
299
|
-
.onChange(async value => {
|
|
300
|
-
this.plugin.settings.additionalContentAttributeName = value
|
|
301
|
-
await this.plugin.saveSettings()
|
|
302
|
-
})
|
|
303
|
-
)
|
|
304
|
-
|
|
305
|
-
new Setting(containerEl)
|
|
306
|
-
.setName('Additional call API image settings')
|
|
307
|
-
.setHeading()
|
|
308
|
-
|
|
309
|
-
new Setting(containerEl)
|
|
310
|
-
.setName('Enable additional call API image')
|
|
311
|
-
.setDesc('Toggle the additional Call API image')
|
|
312
|
-
.addToggle(toggle =>
|
|
313
|
-
toggle
|
|
314
|
-
.setValue(this.plugin.settings.additionalButtonImageEnabled)
|
|
315
|
-
.onChange(async value => {
|
|
316
|
-
this.plugin.settings.additionalButtonImageEnabled = value
|
|
317
|
-
await this.plugin.saveSettings()
|
|
318
|
-
this.display()
|
|
319
|
-
})
|
|
320
|
-
)
|
|
321
|
-
|
|
322
|
-
if (this.plugin.settings.additionalButtonImageEnabled) {
|
|
323
|
-
containerEl.createEl('p', {
|
|
324
|
-
text: 'For the plugin to detect images and galleries, ensure the following folder structure:',
|
|
325
|
-
})
|
|
326
|
-
|
|
327
|
-
containerEl.createEl('ul', {
|
|
328
|
-
text: '- Article file (e.g., article.md)',
|
|
329
|
-
})
|
|
330
|
-
containerEl.createEl('ul', {
|
|
331
|
-
text: '- Main image folder (name: image)',
|
|
332
|
-
})
|
|
333
|
-
|
|
334
|
-
containerEl.createEl('p', {
|
|
335
|
-
text: 'The plugin will detect images in the main image (for this api call)',
|
|
336
|
-
})
|
|
337
|
-
|
|
338
|
-
new Setting(containerEl)
|
|
339
|
-
.setName('Additional call API image full path property')
|
|
340
|
-
.setDesc(
|
|
341
|
-
'Enter the full path property for the additional Call API image in the final call'
|
|
342
|
-
)
|
|
343
|
-
.addText(text =>
|
|
344
|
-
text
|
|
345
|
-
.setPlaceholder('image_presentation')
|
|
346
|
-
.setValue(this.plugin.settings.additionalImageFullPathProperty)
|
|
347
|
-
.onChange(async value => {
|
|
348
|
-
this.plugin.settings.additionalImageFullPathProperty = value
|
|
349
|
-
await this.plugin.saveSettings()
|
|
350
|
-
})
|
|
351
|
-
)
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
new Setting(containerEl)
|
|
355
|
-
.setName('Additional call API gallery settings')
|
|
356
|
-
.setHeading()
|
|
357
|
-
|
|
358
|
-
new Setting(containerEl)
|
|
359
|
-
.setName('Enable additional call API gallery')
|
|
360
|
-
.setDesc('Toggle the additional Call API gallery')
|
|
361
|
-
.addToggle(toggle =>
|
|
362
|
-
toggle
|
|
363
|
-
.setValue(this.plugin.settings.additionalButtonGalleryEnabled)
|
|
364
|
-
.onChange(async value => {
|
|
365
|
-
this.plugin.settings.additionalButtonGalleryEnabled = value
|
|
366
|
-
await this.plugin.saveSettings()
|
|
367
|
-
this.display()
|
|
368
|
-
})
|
|
369
|
-
)
|
|
370
|
-
|
|
371
|
-
if (this.plugin.settings.additionalButtonGalleryEnabled) {
|
|
372
|
-
containerEl.createEl('p', {
|
|
373
|
-
text: 'For the plugin to detect galleries, ensure the following folder structure:',
|
|
374
|
-
})
|
|
375
|
-
|
|
376
|
-
containerEl.createEl('ul', {
|
|
377
|
-
text: '- Article file (e.g., article.md)',
|
|
378
|
-
})
|
|
379
|
-
containerEl.createEl('ul', {
|
|
380
|
-
text: '- Main gallery folder (name: gallery)',
|
|
381
|
-
})
|
|
382
|
-
|
|
383
|
-
containerEl.createEl('p', {
|
|
384
|
-
text: 'The plugin will detect images in the main gallery folders. (for this api call)',
|
|
385
|
-
})
|
|
386
|
-
|
|
387
|
-
new Setting(containerEl)
|
|
388
|
-
.setName('Additional call API gallery full path property')
|
|
389
|
-
.setDesc(
|
|
390
|
-
'Enter the full path property for the additional Call API gallery in the final call'
|
|
391
|
-
)
|
|
392
|
-
.addText(text =>
|
|
393
|
-
text
|
|
394
|
-
.setPlaceholder('galery')
|
|
395
|
-
.setValue(this.plugin.settings.additionalGalleryFullPathProperty)
|
|
396
|
-
.onChange(async value => {
|
|
397
|
-
this.plugin.settings.additionalGalleryFullPathProperty = value
|
|
398
|
-
await this.plugin.saveSettings()
|
|
399
|
-
})
|
|
400
|
-
)
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
}
|
package/src/types/article.ts
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import { OpenAI } from 'openai'
|
|
2
|
-
import { StrapiExporterSettings } from '../types/settings'
|
|
3
|
-
import { ArticleContent } from '../types/article'
|
|
4
|
-
import { Notice } from 'obsidian'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Generate article content using OpenAI
|
|
8
|
-
* @param content
|
|
9
|
-
* @param openai
|
|
10
|
-
* @param settings
|
|
11
|
-
* @param useAdditionalCallAPI
|
|
12
|
-
*/
|
|
13
|
-
export async function generateArticleContent(
|
|
14
|
-
content: string,
|
|
15
|
-
openai: OpenAI,
|
|
16
|
-
settings: StrapiExporterSettings,
|
|
17
|
-
useAdditionalCallAPI = false
|
|
18
|
-
): Promise<ArticleContent> {
|
|
19
|
-
let jsonTemplate: any
|
|
20
|
-
let jsonTemplateDescription: any
|
|
21
|
-
let contentAttributeName: string
|
|
22
|
-
|
|
23
|
-
if (useAdditionalCallAPI) {
|
|
24
|
-
jsonTemplate = JSON.parse(settings.additionalJsonTemplate)
|
|
25
|
-
jsonTemplateDescription = JSON.parse(
|
|
26
|
-
settings.additionalJsonTemplateDescription
|
|
27
|
-
)
|
|
28
|
-
contentAttributeName = settings.additionalContentAttributeName
|
|
29
|
-
} else {
|
|
30
|
-
jsonTemplate = JSON.parse(settings.jsonTemplate)
|
|
31
|
-
jsonTemplateDescription = JSON.parse(settings.jsonTemplateDescription)
|
|
32
|
-
contentAttributeName = settings.strapiContentAttributeName
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const articlePrompt = `You are an SEO expert. Generate an article based on the following template and field descriptions:
|
|
36
|
-
|
|
37
|
-
Template:
|
|
38
|
-
${JSON.stringify(jsonTemplate, null, 2)}
|
|
39
|
-
|
|
40
|
-
Field Descriptions:
|
|
41
|
-
${JSON.stringify(jsonTemplateDescription, null, 2)}
|
|
42
|
-
|
|
43
|
-
The main content of the article should be based on the following text and all the keywords around the domain of the text:
|
|
44
|
-
----- CONTENT -----
|
|
45
|
-
${content.substring(0, 500)}
|
|
46
|
-
----- END CONTENT -----
|
|
47
|
-
|
|
48
|
-
Please provide the generated article content as a JSON object following the given template structure.
|
|
49
|
-
|
|
50
|
-
${settings.additionalPrompt ? `Additional Prompt: ${settings.additionalPrompt}` : ''}`
|
|
51
|
-
|
|
52
|
-
const completion = await openai.chat.completions.create({
|
|
53
|
-
model: 'gpt-3.5-turbo-0125',
|
|
54
|
-
messages: [
|
|
55
|
-
{
|
|
56
|
-
role: 'user',
|
|
57
|
-
content: articlePrompt,
|
|
58
|
-
},
|
|
59
|
-
],
|
|
60
|
-
max_tokens: 2000,
|
|
61
|
-
n: 1,
|
|
62
|
-
stop: null,
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
let articleContent = JSON.parse(completion.choices[0].message.content ?? '{}')
|
|
66
|
-
articleContent = {
|
|
67
|
-
data: {
|
|
68
|
-
...articleContent.data,
|
|
69
|
-
[contentAttributeName]: content,
|
|
70
|
-
},
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return articleContent
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Get the description of the image using OpenAI
|
|
78
|
-
* @param imageBlob
|
|
79
|
-
* @param openai
|
|
80
|
-
*/
|
|
81
|
-
export const getImageDescription = async (imageBlob: Blob, openai: OpenAI) => {
|
|
82
|
-
// Get the image description using the OpenAI API (using gpt 4 vision preview model)
|
|
83
|
-
// @ts-ignore
|
|
84
|
-
const response = await openai.chat.completions.create({
|
|
85
|
-
model: 'gpt-4-vision-preview',
|
|
86
|
-
messages: [
|
|
87
|
-
{
|
|
88
|
-
role: 'user',
|
|
89
|
-
content: [
|
|
90
|
-
{
|
|
91
|
-
type: 'text',
|
|
92
|
-
text: `What's in this image? make it simple, i just want the context and an idea(think about alt text)`,
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
type: 'image_url',
|
|
96
|
-
// Encode imageBlob as base64
|
|
97
|
-
// @ts-ignore
|
|
98
|
-
image_url: `data:image/png;base64,${btoa(
|
|
99
|
-
new Uint8Array(await imageBlob.arrayBuffer()).reduce(
|
|
100
|
-
(data, byte) => data + String.fromCharCode(byte),
|
|
101
|
-
''
|
|
102
|
-
)
|
|
103
|
-
)}`,
|
|
104
|
-
},
|
|
105
|
-
],
|
|
106
|
-
},
|
|
107
|
-
],
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
new Notice(response.choices[0].message.content ?? 'no response content...')
|
|
111
|
-
new Notice(
|
|
112
|
-
`prompt_tokens: ${response.usage?.prompt_tokens} // completion_tokens: ${response.usage?.completion_tokens} // total_tokens: ${response.usage?.total_tokens}`
|
|
113
|
-
)
|
|
114
|
-
|
|
115
|
-
// gpt-3.5-turbo-0125
|
|
116
|
-
// Generate alt text, caption, and title for the image, based on the description of the image
|
|
117
|
-
const completion = await openai.chat.completions.create({
|
|
118
|
-
model: 'gpt-3.5-turbo-0125',
|
|
119
|
-
messages: [
|
|
120
|
-
{
|
|
121
|
-
role: 'user',
|
|
122
|
-
content: `You are an SEO expert and you are writing alt text, caption, and title for this image. The description of the image is: ${response.choices[0].message.content}.
|
|
123
|
-
Give me a title (name) for this image, an SEO-friendly alternative text, and a caption for this image.
|
|
124
|
-
Generate this information and respond with a JSON object using the following fields: name, alternativeText, caption.
|
|
125
|
-
Use this JSON template: {"name": "string", "alternativeText": "string", "caption": "string"}.`,
|
|
126
|
-
},
|
|
127
|
-
],
|
|
128
|
-
max_tokens: 750,
|
|
129
|
-
n: 1,
|
|
130
|
-
stop: null,
|
|
131
|
-
})
|
|
132
|
-
|
|
133
|
-
new Notice(completion.choices[0].message.content ?? 'no response content...')
|
|
134
|
-
new Notice(
|
|
135
|
-
`prompt_tokens: ${completion.usage?.prompt_tokens} // completion_tokens: ${completion.usage?.completion_tokens} // total_tokens: ${completion.usage?.total_tokens}`
|
|
136
|
-
)
|
|
137
|
-
|
|
138
|
-
return JSON.parse(completion.choices[0].message.content?.trim() || '{}')
|
|
139
|
-
}
|
package/src/utils/validators.ts
DELETED
package/version-bump.mjs
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { readFileSync, writeFileSync } from "fs";
|
|
2
|
-
|
|
3
|
-
const targetVersion = process.env.npm_package_version;
|
|
4
|
-
|
|
5
|
-
// read minAppVersion from manifest.json and bump version to target version
|
|
6
|
-
let manifest = JSON.parse(readFileSync("manifest.json", "utf8"));
|
|
7
|
-
const { minAppVersion } = manifest;
|
|
8
|
-
manifest.version = targetVersion;
|
|
9
|
-
writeFileSync("manifest.json", JSON.stringify(manifest, null, "\t"));
|
|
10
|
-
|
|
11
|
-
// update versions.json with target version and minAppVersion from manifest.json
|
|
12
|
-
let versions = JSON.parse(readFileSync("versions.json", "utf8"));
|
|
13
|
-
versions[targetVersion] = minAppVersion;
|
|
14
|
-
writeFileSync("versions.json", JSON.stringify(versions, null, "\t"));
|
package/versions.json
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"1.0.2": "1.0.2",
|
|
3
|
-
"1.0.4": "1.5.0",
|
|
4
|
-
"1.0.5": "1.5.0",
|
|
5
|
-
"1.0.6": "1.5.0",
|
|
6
|
-
"1.0.7": "1.5.0",
|
|
7
|
-
"1.0.8": "1.5.0",
|
|
8
|
-
"1.0.9": "1.5.0",
|
|
9
|
-
"1.0.10": "1.5.0",
|
|
10
|
-
"1.0.11": "1.5.0",
|
|
11
|
-
"1.0.12": "1.5.0",
|
|
12
|
-
"1.0.13": "1.5.0",
|
|
13
|
-
"1.0.14": "1.5.0",
|
|
14
|
-
"1.0.15": "1.5.0",
|
|
15
|
-
"1.0.16": "1.5.0",
|
|
16
|
-
"1.0.17": "1.5.0",
|
|
17
|
-
"1.0.18": "1.5.0",
|
|
18
|
-
"1.0.19": "1.5.0",
|
|
19
|
-
"1.0.20": "1.5.0",
|
|
20
|
-
"1.0.21": "1.5.0",
|
|
21
|
-
"1.0.22": "1.5.0",
|
|
22
|
-
"1.0.23": "1.5.0",
|
|
23
|
-
"1.0.24": "1.5.0",
|
|
24
|
-
"1.0.25": "1.5.0",
|
|
25
|
-
"1.0.26": "1.5.0",
|
|
26
|
-
"1.0.27": "1.5.0",
|
|
27
|
-
"1.0.28": "1.5.0",
|
|
28
|
-
"1.0.29": "1.5.0",
|
|
29
|
-
"1.0.30": "1.5.0",
|
|
30
|
-
"1.0.31": "1.5.0",
|
|
31
|
-
"1.0.32": "1.5.0",
|
|
32
|
-
"1.0.33": "1.5.0",
|
|
33
|
-
"1.0.34": "1.5.0",
|
|
34
|
-
"1.0.35": "1.5.0",
|
|
35
|
-
"1.0.36": "1.5.0",
|
|
36
|
-
"1.0.37": "1.5.0",
|
|
37
|
-
"1.0.38": "1.5.0",
|
|
38
|
-
"1.0.39": "1.5.0",
|
|
39
|
-
"1.0.40": "1.5.0",
|
|
40
|
-
"1.0.41": "1.5.0",
|
|
41
|
-
"1.0.42": "1.5.0",
|
|
42
|
-
"1.0.43": "1.5.0",
|
|
43
|
-
"1.0.44": "1.5.0",
|
|
44
|
-
"1.0.45": "1.5.0",
|
|
45
|
-
"1.0.46": "1.5.0",
|
|
46
|
-
"1.0.47": "1.5.0",
|
|
47
|
-
"1.0.48": "1.5.0",
|
|
48
|
-
"1.0.49": "1.5.0",
|
|
49
|
-
"1.0.50": "1.5.0",
|
|
50
|
-
"1.0.51": "1.5.0",
|
|
51
|
-
"1.0.52": "1.5.0",
|
|
52
|
-
"1.0.53": "1.5.0",
|
|
53
|
-
"1.0.54": "1.5.0",
|
|
54
|
-
"1.0.55": "1.5.0",
|
|
55
|
-
"1.0.56": "1.5.0",
|
|
56
|
-
"1.0.57": "1.5.0",
|
|
57
|
-
"1.0.58": "1.5.0",
|
|
58
|
-
"1.0.59": "1.5.0",
|
|
59
|
-
"1.0.60": "1.5.0",
|
|
60
|
-
"1.0.61": "1.5.0",
|
|
61
|
-
"1.0.62": "1.5.0",
|
|
62
|
-
"1.0.63": "1.5.0",
|
|
63
|
-
"1.0.64": "1.5.0",
|
|
64
|
-
"1.0.65": "1.5.0",
|
|
65
|
-
"1.0.66": "1.5.0",
|
|
66
|
-
"1.0.67": "1.5.0",
|
|
67
|
-
"1.0.68": "1.5.0",
|
|
68
|
-
"1.0.69": "1.5.0",
|
|
69
|
-
"1.0.70": "1.5.0",
|
|
70
|
-
"1.0.71": "1.5.0",
|
|
71
|
-
"1.0.72": "1.5.0",
|
|
72
|
-
"1.0.73": "1.5.0",
|
|
73
|
-
"1.0.74": "1.5.0",
|
|
74
|
-
"1.0.75": "1.5.0",
|
|
75
|
-
"1.0.76": "1.5.0",
|
|
76
|
-
"1.0.77": "1.5.0",
|
|
77
|
-
"1.0.78": "1.5.0",
|
|
78
|
-
"1.0.79": "1.5.0",
|
|
79
|
-
"1.0.80": "1.5.0",
|
|
80
|
-
"1.0.81": "1.5.0",
|
|
81
|
-
"1.0.82": "1.5.0",
|
|
82
|
-
"1.0.83": "1.5.0",
|
|
83
|
-
"1.0.84": "1.5.0",
|
|
84
|
-
"1.0.85": "1.5.0",
|
|
85
|
-
"1.0.86": "1.5.0",
|
|
86
|
-
"1.0.87": "1.5.0",
|
|
87
|
-
"1.0.88": "1.5.0",
|
|
88
|
-
"1.0.89": "1.5.0",
|
|
89
|
-
"1.0.90": "1.5.0",
|
|
90
|
-
"1.0.91": "1.5.0",
|
|
91
|
-
"1.0.92": "1.5.0",
|
|
92
|
-
"1.0.93": "1.5.0",
|
|
93
|
-
"1.0.94": "1.5.0",
|
|
94
|
-
"1.0.95": "1.5.0",
|
|
95
|
-
"1.0.96": "1.5.0",
|
|
96
|
-
"1.0.97": "1.5.0",
|
|
97
|
-
"1.0.98": "1.5.0",
|
|
98
|
-
"1.0.99": "1.5.0",
|
|
99
|
-
"1.0.100": "1.5.0",
|
|
100
|
-
"1.0.101": "1.5.0",
|
|
101
|
-
"1.0.102": "1.5.0",
|
|
102
|
-
"1.0.103": "1.5.0",
|
|
103
|
-
"1.0.104": "1.5.0",
|
|
104
|
-
"1.0.105": "1.5.0",
|
|
105
|
-
"1.0.106": "1.5.0",
|
|
106
|
-
"1.0.107": "1.5.0",
|
|
107
|
-
"1.0.108": "1.5.0",
|
|
108
|
-
"1.0.109": "1.5.0",
|
|
109
|
-
"1.0.110": "1.5.0",
|
|
110
|
-
"1.0.111": "1.5.0",
|
|
111
|
-
"1.0.112": "1.5.0",
|
|
112
|
-
"1.0.113": "1.5.0",
|
|
113
|
-
"1.0.114": "1.5.0",
|
|
114
|
-
"1.0.115": "1.5.0",
|
|
115
|
-
"1.0.116": "1.5.0",
|
|
116
|
-
"1.0.117": "1.5.0",
|
|
117
|
-
"1.0.118": "1.5.0"
|
|
118
|
-
}
|