@rmdes/indiekit-endpoint-rss 1.0.11 → 1.0.12

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 ADDED
@@ -0,0 +1,291 @@
1
+ # @rmdes/indiekit-endpoint-rss
2
+
3
+ RSS feed reader endpoint for Indiekit. Aggregates multiple feeds, caches in MongoDB, displays on frontend.
4
+
5
+ ## Features
6
+
7
+ - **Multi-Feed Aggregation** - Subscribe to unlimited RSS/Atom/JSON feeds
8
+ - **Background Sync** - Automatic updates every 15 minutes (configurable)
9
+ - **MongoDB Caching** - Fast access to cached feed items
10
+ - **Admin Dashboard** - Add/remove feeds, view recent items, trigger manual sync
11
+ - **Public JSON API** - Read-only endpoints for frontend display
12
+ - **Feed Management** - Enable/disable feeds, view sync status and errors
13
+ - **Automatic Cleanup** - Prunes items older than 30 days (configurable)
14
+ - **Format Support** - RSS 2.0, Atom, JSON Feed, Google Reader API (FreshRSS)
15
+ - **Concurrency Control** - Fetches 3 feeds in parallel to avoid overwhelming servers
16
+ - **HTML Sanitization** - Strips dangerous tags, keeps basic formatting
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install @rmdes/indiekit-endpoint-rss
22
+ ```
23
+
24
+ ## Configuration
25
+
26
+ Add to your `indiekit.config.js`:
27
+
28
+ ```javascript
29
+ import RssEndpoint from "@rmdes/indiekit-endpoint-rss";
30
+
31
+ export default {
32
+ plugins: [
33
+ new RssEndpoint({
34
+ mountPath: "/rssapi", // Default: /rssapi
35
+ syncInterval: 900_000, // 15 minutes (in milliseconds)
36
+ maxItemsPerFeed: 50, // Max items per feed to cache
37
+ fetchTimeout: 10_000, // 10 second timeout per feed
38
+ maxConcurrentFetches: 3, // Parallel feed fetches
39
+ retentionDays: 30 // Days to keep items
40
+ })
41
+ ],
42
+ // MongoDB database is REQUIRED
43
+ mongodbUrl: process.env.MONGODB_URL
44
+ };
45
+ ```
46
+
47
+ ## Usage
48
+
49
+ ### Admin Dashboard
50
+
51
+ Navigate to `/rssapi` (or your configured `mountPath`) to access the admin dashboard.
52
+
53
+ **Features:**
54
+ - View all subscribed feeds
55
+ - Add new feeds by URL
56
+ - Enable/disable feeds
57
+ - Remove feeds
58
+ - View recent items
59
+ - Manual sync trigger
60
+ - Clear cache and re-sync
61
+
62
+ ### Adding Feeds
63
+
64
+ **Via Admin UI:**
65
+ 1. Go to `/rssapi`
66
+ 2. Enter feed URL in the "Add Feed" form
67
+ 3. Click "Add Feed"
68
+
69
+ **Via API:**
70
+ ```bash
71
+ curl -X POST https://yoursite.com/rssapi/api/feeds \
72
+ -H "Content-Type: application/json" \
73
+ -H "Authorization: Bearer YOUR_TOKEN" \
74
+ -d '{"url": "https://example.com/feed.xml"}'
75
+ ```
76
+
77
+ ### Public API Endpoints
78
+
79
+ **List All Feeds:**
80
+ ```bash
81
+ GET /rssapi/api/feeds
82
+ ```
83
+
84
+ **List Feed Items (Paginated):**
85
+ ```bash
86
+ GET /rssapi/api/items?page=1&limit=20&feedId=FEED_ID&includeContent=true
87
+ ```
88
+
89
+ **Get Single Item:**
90
+ ```bash
91
+ GET /rssapi/api/items/:id
92
+ ```
93
+
94
+ **Sync Status:**
95
+ ```bash
96
+ GET /rssapi/api/status
97
+ ```
98
+
99
+ ### Example: Display Items in Eleventy
100
+
101
+ ```javascript
102
+ // _data/rssItems.js
103
+ export default async function () {
104
+ const response = await fetch("https://yoursite.com/rssapi/api/items?limit=10");
105
+ const data = await response.json();
106
+ return data.items;
107
+ }
108
+ ```
109
+
110
+ ```nunjucks
111
+ <!-- index.njk -->
112
+ <h2>Latest News</h2>
113
+ {% for item in rssItems %}
114
+ <article>
115
+ <h3><a href="{{ item.link }}">{{ item.title }}</a></h3>
116
+ <p class="meta">{{ item.feedTitle }} - {{ item.pubDate | date("PPp") }}</p>
117
+ <p>{{ item.description }}</p>
118
+ {% if item.imageUrl %}
119
+ <img src="{{ item.imageUrl }}" alt="">
120
+ {% endif %}
121
+ </article>
122
+ {% endfor %}
123
+ ```
124
+
125
+ ## Supported Feed Formats
126
+
127
+ - **RSS 2.0** - Standard blog feeds
128
+ - **Atom** - GitHub releases, podcasts, etc.
129
+ - **JSON Feed** - jsonfeed.org spec (v1.0, v1.1)
130
+ - **Google Reader API** - FreshRSS, NewsBlur, Miniflux (use `?f=json` or `?f=greader`)
131
+
132
+ ## FreshRSS Integration
133
+
134
+ This plugin has special support for FreshRSS (and other Google Reader API compatible aggregators):
135
+
136
+ 1. Get your FreshRSS API feed URL (Settings → Authentication → API feed URL)
137
+ 2. Add `?f=json` or `?f=greader` to the URL
138
+ 3. Add the URL to Indiekit RSS endpoint
139
+
140
+ **Example:**
141
+ ```
142
+ https://freshrss.example.com/api/greader.php/reader/api/0/stream/contents/reading-list?f=json&n=50&user=admin&apiKey=YOUR_API_KEY
143
+ ```
144
+
145
+ **Features:**
146
+ - Preserves original feed source (via `origin` object)
147
+ - Filters out internal FreshRSS categories
148
+ - Extracts images from media content
149
+ - Handles FreshRSS timestamps (Unix seconds, microseconds)
150
+
151
+ ## API Reference
152
+
153
+ ### GET /api/feeds
154
+
155
+ List all feeds.
156
+
157
+ **Response:**
158
+ ```json
159
+ {
160
+ "feeds": [
161
+ {
162
+ "id": "507f1f77bcf86cd799439011",
163
+ "url": "https://example.com/feed.xml",
164
+ "title": "Example Blog",
165
+ "siteUrl": "https://example.com",
166
+ "description": "A blog about things",
167
+ "imageUrl": "https://example.com/icon.png",
168
+ "enabled": true,
169
+ "addedAt": "2025-02-01T12:00:00.000Z",
170
+ "lastFetchedAt": "2025-02-13T14:30:00.000Z",
171
+ "lastError": null,
172
+ "itemCount": 42
173
+ }
174
+ ],
175
+ "total": 1
176
+ }
177
+ ```
178
+
179
+ ### GET /api/items
180
+
181
+ List feed items with pagination.
182
+
183
+ **Query Parameters:**
184
+ - `page` (number, default: 1) - Page number
185
+ - `limit` (number, default: 20, max: 100) - Items per page
186
+ - `feedId` (string, optional) - Filter by feed ID
187
+ - `includeContent` (boolean, default: false) - Include full HTML content
188
+
189
+ **Response:**
190
+ ```json
191
+ {
192
+ "items": [
193
+ {
194
+ "id": "507f1f77bcf86cd799439012",
195
+ "feedId": "507f1f77bcf86cd799439011",
196
+ "feedTitle": "Example Blog",
197
+ "guid": "https://example.com/post-1",
198
+ "title": "Hello World",
199
+ "link": "https://example.com/post-1",
200
+ "description": "A short summary...",
201
+ "author": "John Doe",
202
+ "pubDate": "2025-02-13T12:00:00.000Z",
203
+ "imageUrl": "https://example.com/image.jpg",
204
+ "categories": ["tech", "web"],
205
+ "fetchedAt": "2025-02-13T14:30:00.000Z",
206
+ "sourceTitle": "Original Feed Title",
207
+ "sourceUrl": "https://original-source.com"
208
+ }
209
+ ],
210
+ "pagination": {
211
+ "page": 1,
212
+ "limit": 20,
213
+ "total": 100,
214
+ "totalPages": 5,
215
+ "hasNext": true,
216
+ "hasPrev": false
217
+ }
218
+ }
219
+ ```
220
+
221
+ ### GET /api/items/:id
222
+
223
+ Get a single item by ID.
224
+
225
+ **Response:**
226
+ ```json
227
+ {
228
+ "item": {
229
+ "id": "507f1f77bcf86cd799439012",
230
+ "feedId": "507f1f77bcf86cd799439011",
231
+ "feedTitle": "Example Blog",
232
+ "title": "Hello World",
233
+ "link": "https://example.com/post-1",
234
+ "description": "A short summary...",
235
+ "content": "<p>Full sanitized HTML content...</p>",
236
+ "author": "John Doe",
237
+ "pubDate": "2025-02-13T12:00:00.000Z",
238
+ "imageUrl": "https://example.com/image.jpg",
239
+ "categories": ["tech", "web"],
240
+ "enclosure": {
241
+ "url": "https://example.com/podcast.mp3",
242
+ "type": "audio/mpeg",
243
+ "length": 12345678
244
+ },
245
+ "fetchedAt": "2025-02-13T14:30:00.000Z"
246
+ }
247
+ }
248
+ ```
249
+
250
+ ### GET /api/status
251
+
252
+ Get sync status and statistics.
253
+
254
+ **Response:**
255
+ ```json
256
+ {
257
+ "status": "idle",
258
+ "lastSync": "2025-02-13T14:30:00.000Z",
259
+ "nextSync": "2025-02-13T14:45:00.000Z",
260
+ "lastError": null,
261
+ "stats": {
262
+ "feedsCount": 5,
263
+ "enabledFeedsCount": 4,
264
+ "itemsCount": 200,
265
+ "lastFeedsProcessed": 4,
266
+ "lastItemsAdded": 12
267
+ },
268
+ "config": {
269
+ "syncInterval": 900000,
270
+ "maxItemsPerFeed": 50
271
+ }
272
+ }
273
+ ```
274
+
275
+ ## Requirements
276
+
277
+ - **Indiekit** >= 1.0.0-beta.25
278
+ - **MongoDB** database
279
+ - **Node.js** >= 20
280
+
281
+ ## License
282
+
283
+ MIT
284
+
285
+ ## Author
286
+
287
+ Ricardo Mendes - https://rmendes.net
288
+
289
+ ## Repository
290
+
291
+ https://github.com/rmdes/indiekit-endpoint-rss
@@ -0,0 +1,52 @@
1
+ {
2
+ "rss": {
3
+ "title": "RSS-Reader",
4
+ "feeds": "Feeds",
5
+ "items": "Feed-Einträge",
6
+ "addFeed": "Feed hinzufügen",
7
+ "removeFeed": "Feed entfernen",
8
+ "enableFeed": "Aktivieren",
9
+ "disableFeed": "Deaktivieren",
10
+ "syncNow": "Jetzt synchronisieren",
11
+ "clearResync": "Löschen & neu synchronisieren",
12
+ "syncing": "Synchronisiere...",
13
+ "lastSynced": "Zuletzt synchronisiert",
14
+ "noFeeds": "Keine Feeds konfiguriert. Fügen Sie eine Feed-URL hinzu, um zu beginnen.",
15
+ "noItems": "Keine Einträge gefunden.",
16
+ "feedUrl": "Feed-URL",
17
+ "feedUrlPlaceholder": "https://example.com/feed.xml",
18
+ "recentItems": "Aktuelle Einträge",
19
+ "viewAll": "Alle anzeigen",
20
+ "enabled": "Aktiviert",
21
+ "disabled": "Deaktiviert",
22
+ "itemCount": "Einträge",
23
+ "actions": "Aktionen",
24
+ "status": "Status",
25
+ "syncStatus": "Synchronisierungsstatus",
26
+ "feedsCount": "Feeds insgesamt",
27
+ "itemsCount": "Einträge insgesamt",
28
+ "lastSync": "Letzte Synchronisierung",
29
+ "nextSync": "Nächste Synchronisierung",
30
+ "never": "Nie",
31
+ "error": {
32
+ "invalidUrl": "Bitte geben Sie eine gültige Feed-URL ein",
33
+ "feedExists": "Dieser Feed wurde bereits hinzugefügt",
34
+ "feedNotFound": "Feed nicht gefunden",
35
+ "fetchFailed": "Feed konnte nicht abgerufen werden",
36
+ "noConfig": "RSS-Endpunkt nicht korrekt konfiguriert",
37
+ "noDatabase": "Datenbank nicht verfügbar"
38
+ },
39
+ "success": {
40
+ "feedAdded": "Feed erfolgreich hinzugefügt",
41
+ "feedRemoved": "Feed entfernt",
42
+ "feedEnabled": "Feed aktiviert",
43
+ "feedDisabled": "Feed deaktiviert",
44
+ "syncComplete": "Synchronisierung abgeschlossen",
45
+ "clearResync": "Einträge gelöscht und neu synchronisiert"
46
+ },
47
+ "widget": {
48
+ "description": "Aggregierte RSS-Feeds auf der öffentlichen Seite anzeigen",
49
+ "view": "Nachrichtenseite anzeigen"
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "rss": {
3
+ "title": "Lector RSS",
4
+ "feeds": "Fuentes",
5
+ "items": "Elementos de fuentes",
6
+ "addFeed": "Agregar fuente",
7
+ "removeFeed": "Quitar fuente",
8
+ "enableFeed": "Habilitar",
9
+ "disableFeed": "Deshabilitar",
10
+ "syncNow": "Sincronizar ahora",
11
+ "clearResync": "Limpiar y resincronizar",
12
+ "syncing": "Sincronizando...",
13
+ "lastSynced": "Última sincronización",
14
+ "noFeeds": "No hay fuentes configuradas. Agregá una URL de fuente para comenzar.",
15
+ "noItems": "No se encontraron elementos.",
16
+ "feedUrl": "URL de la fuente",
17
+ "feedUrlPlaceholder": "https://ejemplo.com/feed.xml",
18
+ "recentItems": "Elementos recientes",
19
+ "viewAll": "Ver todos",
20
+ "enabled": "Habilitado",
21
+ "disabled": "Deshabilitado",
22
+ "itemCount": "elementos",
23
+ "actions": "Acciones",
24
+ "status": "Estado",
25
+ "syncStatus": "Estado de sincronización",
26
+ "feedsCount": "Total de fuentes",
27
+ "itemsCount": "Total de elementos",
28
+ "lastSync": "Última sincronización",
29
+ "nextSync": "Próxima sincronización",
30
+ "never": "Nunca",
31
+ "error": {
32
+ "invalidUrl": "Por favor ingresá una URL de fuente válida",
33
+ "feedExists": "Esta fuente ya fue agregada",
34
+ "feedNotFound": "Fuente no encontrada",
35
+ "fetchFailed": "Error al obtener la fuente",
36
+ "noConfig": "El endpoint RSS no está configurado correctamente",
37
+ "noDatabase": "Base de datos no disponible"
38
+ },
39
+ "success": {
40
+ "feedAdded": "Fuente agregada exitosamente",
41
+ "feedRemoved": "Fuente quitada",
42
+ "feedEnabled": "Fuente habilitada",
43
+ "feedDisabled": "Fuente deshabilitada",
44
+ "syncComplete": "Sincronización completa",
45
+ "clearResync": "Elementos limpiados y resincronizados"
46
+ },
47
+ "widget": {
48
+ "description": "Ver fuentes RSS agregadas en la página pública",
49
+ "view": "Ver página de noticias"
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "rss": {
3
+ "title": "Lector RSS",
4
+ "feeds": "Fuentes",
5
+ "items": "Entradas de fuentes",
6
+ "addFeed": "Añadir fuente",
7
+ "removeFeed": "Eliminar fuente",
8
+ "enableFeed": "Activar",
9
+ "disableFeed": "Desactivar",
10
+ "syncNow": "Sincronizar ahora",
11
+ "clearResync": "Borrar y resincronizar",
12
+ "syncing": "Sincronizando...",
13
+ "lastSynced": "Última sincronización",
14
+ "noFeeds": "No hay fuentes configuradas. Añade una URL de fuente para empezar.",
15
+ "noItems": "No se encontraron entradas.",
16
+ "feedUrl": "URL de la fuente",
17
+ "feedUrlPlaceholder": "https://ejemplo.com/feed.xml",
18
+ "recentItems": "Entradas recientes",
19
+ "viewAll": "Ver todo",
20
+ "enabled": "Activado",
21
+ "disabled": "Desactivado",
22
+ "itemCount": "entradas",
23
+ "actions": "Acciones",
24
+ "status": "Estado",
25
+ "syncStatus": "Estado de sincronización",
26
+ "feedsCount": "Total de fuentes",
27
+ "itemsCount": "Total de entradas",
28
+ "lastSync": "Última sincronización",
29
+ "nextSync": "Próxima sincronización",
30
+ "never": "Nunca",
31
+ "error": {
32
+ "invalidUrl": "Por favor, introduce una URL de fuente válida",
33
+ "feedExists": "Esta fuente ya ha sido añadida",
34
+ "feedNotFound": "Fuente no encontrada",
35
+ "fetchFailed": "Error al obtener la fuente",
36
+ "noConfig": "El endpoint RSS no está configurado correctamente",
37
+ "noDatabase": "Base de datos no disponible"
38
+ },
39
+ "success": {
40
+ "feedAdded": "Fuente añadida correctamente",
41
+ "feedRemoved": "Fuente eliminada",
42
+ "feedEnabled": "Fuente activada",
43
+ "feedDisabled": "Fuente desactivada",
44
+ "syncComplete": "Sincronización completa",
45
+ "clearResync": "Entradas borradas y resincronizadas"
46
+ },
47
+ "widget": {
48
+ "description": "Ver fuentes RSS agregadas en la página pública",
49
+ "view": "Ver página de noticias"
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "rss": {
3
+ "title": "Lecteur RSS",
4
+ "feeds": "Flux",
5
+ "items": "Articles de flux",
6
+ "addFeed": "Ajouter un flux",
7
+ "removeFeed": "Supprimer le flux",
8
+ "enableFeed": "Activer",
9
+ "disableFeed": "Désactiver",
10
+ "syncNow": "Synchroniser maintenant",
11
+ "clearResync": "Effacer et resynchroniser",
12
+ "syncing": "Synchronisation...",
13
+ "lastSynced": "Dernière synchronisation",
14
+ "noFeeds": "Aucun flux configuré. Ajoutez une URL de flux pour commencer.",
15
+ "noItems": "Aucun article trouvé.",
16
+ "feedUrl": "URL du flux",
17
+ "feedUrlPlaceholder": "https://exemple.com/feed.xml",
18
+ "recentItems": "Articles récents",
19
+ "viewAll": "Voir tout",
20
+ "enabled": "Activé",
21
+ "disabled": "Désactivé",
22
+ "itemCount": "articles",
23
+ "actions": "Actions",
24
+ "status": "Statut",
25
+ "syncStatus": "État de synchronisation",
26
+ "feedsCount": "Total des flux",
27
+ "itemsCount": "Total des articles",
28
+ "lastSync": "Dernière synchronisation",
29
+ "nextSync": "Prochaine synchronisation",
30
+ "never": "Jamais",
31
+ "error": {
32
+ "invalidUrl": "Veuillez saisir une URL de flux valide",
33
+ "feedExists": "Ce flux a déjà été ajouté",
34
+ "feedNotFound": "Flux introuvable",
35
+ "fetchFailed": "Échec de récupération du flux",
36
+ "noConfig": "Le point de terminaison RSS n'est pas configuré correctement",
37
+ "noDatabase": "Base de données non disponible"
38
+ },
39
+ "success": {
40
+ "feedAdded": "Flux ajouté avec succès",
41
+ "feedRemoved": "Flux supprimé",
42
+ "feedEnabled": "Flux activé",
43
+ "feedDisabled": "Flux désactivé",
44
+ "syncComplete": "Synchronisation terminée",
45
+ "clearResync": "Articles effacés et resynchronisés"
46
+ },
47
+ "widget": {
48
+ "description": "Voir les flux RSS agrégés sur la page publique",
49
+ "view": "Voir la page d'actualités"
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "rss": {
3
+ "title": "RSS रीडर",
4
+ "feeds": "फ़ीड",
5
+ "items": "फ़ीड आइटम",
6
+ "addFeed": "फ़ीड जोड़ें",
7
+ "removeFeed": "फ़ीड हटाएं",
8
+ "enableFeed": "सक्षम करें",
9
+ "disableFeed": "अक्षम करें",
10
+ "syncNow": "अभी सिंक करें",
11
+ "clearResync": "साफ़ करें और फिर से सिंक करें",
12
+ "syncing": "सिंक हो रहा है...",
13
+ "lastSynced": "अंतिम सिंक",
14
+ "noFeeds": "कोई फ़ीड कॉन्फ़िगर नहीं है। शुरू करने के लिए एक फ़ीड URL जोड़ें।",
15
+ "noItems": "कोई आइटम नहीं मिला।",
16
+ "feedUrl": "फ़ीड URL",
17
+ "feedUrlPlaceholder": "https://example.com/feed.xml",
18
+ "recentItems": "हाल के आइटम",
19
+ "viewAll": "सभी देखें",
20
+ "enabled": "सक्षम",
21
+ "disabled": "अक्षम",
22
+ "itemCount": "आइटम",
23
+ "actions": "क्रियाएं",
24
+ "status": "स्थिति",
25
+ "syncStatus": "सिंक स्थिति",
26
+ "feedsCount": "कुल फ़ीड",
27
+ "itemsCount": "कुल आइटम",
28
+ "lastSync": "अंतिम सिंक",
29
+ "nextSync": "अगला सिंक",
30
+ "never": "कभी नहीं",
31
+ "error": {
32
+ "invalidUrl": "कृपया एक मान्य फ़ीड URL दर्ज करें",
33
+ "feedExists": "यह फ़ीड पहले से जोड़ा गया है",
34
+ "feedNotFound": "फ़ीड नहीं मिला",
35
+ "fetchFailed": "फ़ीड लाने में विफल",
36
+ "noConfig": "RSS एंडपॉइंट सही तरीके से कॉन्फ़िगर नहीं है",
37
+ "noDatabase": "डेटाबेस उपलब्ध नहीं है"
38
+ },
39
+ "success": {
40
+ "feedAdded": "फ़ीड सफलतापूर्वक जोड़ा गया",
41
+ "feedRemoved": "फ़ीड हटाया गया",
42
+ "feedEnabled": "फ़ीड सक्षम किया गया",
43
+ "feedDisabled": "फ़ीड अक्षम किया गया",
44
+ "syncComplete": "सिंक पूर्ण",
45
+ "clearResync": "आइटम साफ़ किए गए और फिर से सिंक किए गए"
46
+ },
47
+ "widget": {
48
+ "description": "सार्वजनिक पृष्ठ पर समेकित RSS फ़ीड देखें",
49
+ "view": "समाचार पृष्ठ देखें"
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "rss": {
3
+ "title": "Pembaca RSS",
4
+ "feeds": "Umpan",
5
+ "items": "Item Umpan",
6
+ "addFeed": "Tambah Umpan",
7
+ "removeFeed": "Hapus Umpan",
8
+ "enableFeed": "Aktifkan",
9
+ "disableFeed": "Nonaktifkan",
10
+ "syncNow": "Sinkronkan Sekarang",
11
+ "clearResync": "Hapus & Sinkronkan Ulang",
12
+ "syncing": "Menyinkronkan...",
13
+ "lastSynced": "Terakhir disinkronkan",
14
+ "noFeeds": "Tidak ada umpan yang dikonfigurasi. Tambahkan URL umpan untuk memulai.",
15
+ "noItems": "Tidak ada item ditemukan.",
16
+ "feedUrl": "URL Umpan",
17
+ "feedUrlPlaceholder": "https://contoh.com/feed.xml",
18
+ "recentItems": "Item Terbaru",
19
+ "viewAll": "Lihat Semua",
20
+ "enabled": "Aktif",
21
+ "disabled": "Nonaktif",
22
+ "itemCount": "item",
23
+ "actions": "Tindakan",
24
+ "status": "Status",
25
+ "syncStatus": "Status Sinkronisasi",
26
+ "feedsCount": "Total Umpan",
27
+ "itemsCount": "Total Item",
28
+ "lastSync": "Sinkronisasi Terakhir",
29
+ "nextSync": "Sinkronisasi Berikutnya",
30
+ "never": "Tidak Pernah",
31
+ "error": {
32
+ "invalidUrl": "Masukkan URL umpan yang valid",
33
+ "feedExists": "Umpan ini sudah ditambahkan",
34
+ "feedNotFound": "Umpan tidak ditemukan",
35
+ "fetchFailed": "Gagal mengambil umpan",
36
+ "noConfig": "Endpoint RSS tidak dikonfigurasi dengan benar",
37
+ "noDatabase": "Basis data tidak tersedia"
38
+ },
39
+ "success": {
40
+ "feedAdded": "Umpan berhasil ditambahkan",
41
+ "feedRemoved": "Umpan dihapus",
42
+ "feedEnabled": "Umpan diaktifkan",
43
+ "feedDisabled": "Umpan dinonaktifkan",
44
+ "syncComplete": "Sinkronisasi selesai",
45
+ "clearResync": "Item dihapus dan disinkronkan ulang"
46
+ },
47
+ "widget": {
48
+ "description": "Lihat umpan RSS terkumpul di halaman publik",
49
+ "view": "Lihat Halaman Berita"
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "rss": {
3
+ "title": "Lettore RSS",
4
+ "feeds": "Feed",
5
+ "items": "Elementi del feed",
6
+ "addFeed": "Aggiungi feed",
7
+ "removeFeed": "Rimuovi feed",
8
+ "enableFeed": "Abilita",
9
+ "disableFeed": "Disabilita",
10
+ "syncNow": "Sincronizza ora",
11
+ "clearResync": "Cancella e risincronizza",
12
+ "syncing": "Sincronizzazione...",
13
+ "lastSynced": "Ultima sincronizzazione",
14
+ "noFeeds": "Nessun feed configurato. Aggiungi un URL feed per iniziare.",
15
+ "noItems": "Nessun elemento trovato.",
16
+ "feedUrl": "URL del feed",
17
+ "feedUrlPlaceholder": "https://esempio.com/feed.xml",
18
+ "recentItems": "Elementi recenti",
19
+ "viewAll": "Visualizza tutto",
20
+ "enabled": "Abilitato",
21
+ "disabled": "Disabilitato",
22
+ "itemCount": "elementi",
23
+ "actions": "Azioni",
24
+ "status": "Stato",
25
+ "syncStatus": "Stato sincronizzazione",
26
+ "feedsCount": "Totale feed",
27
+ "itemsCount": "Totale elementi",
28
+ "lastSync": "Ultima sincronizzazione",
29
+ "nextSync": "Prossima sincronizzazione",
30
+ "never": "Mai",
31
+ "error": {
32
+ "invalidUrl": "Inserisci un URL feed valido",
33
+ "feedExists": "Questo feed è già stato aggiunto",
34
+ "feedNotFound": "Feed non trovato",
35
+ "fetchFailed": "Recupero del feed non riuscito",
36
+ "noConfig": "Endpoint RSS non configurato correttamente",
37
+ "noDatabase": "Database non disponibile"
38
+ },
39
+ "success": {
40
+ "feedAdded": "Feed aggiunto con successo",
41
+ "feedRemoved": "Feed rimosso",
42
+ "feedEnabled": "Feed abilitato",
43
+ "feedDisabled": "Feed disabilitato",
44
+ "syncComplete": "Sincronizzazione completata",
45
+ "clearResync": "Elementi cancellati e risincronizzati"
46
+ },
47
+ "widget": {
48
+ "description": "Visualizza i feed RSS aggregati sulla pagina pubblica",
49
+ "view": "Visualizza pagina notizie"
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "rss": {
3
+ "title": "RSS-lezer",
4
+ "feeds": "Feeds",
5
+ "items": "Feed-items",
6
+ "addFeed": "Feed toevoegen",
7
+ "removeFeed": "Feed verwijderen",
8
+ "enableFeed": "Inschakelen",
9
+ "disableFeed": "Uitschakelen",
10
+ "syncNow": "Nu synchroniseren",
11
+ "clearResync": "Wissen en opnieuw synchroniseren",
12
+ "syncing": "Synchroniseren...",
13
+ "lastSynced": "Laatst gesynchroniseerd",
14
+ "noFeeds": "Geen feeds geconfigureerd. Voeg een feed-URL toe om te beginnen.",
15
+ "noItems": "Geen items gevonden.",
16
+ "feedUrl": "Feed-URL",
17
+ "feedUrlPlaceholder": "https://voorbeeld.nl/feed.xml",
18
+ "recentItems": "Recente items",
19
+ "viewAll": "Alles bekijken",
20
+ "enabled": "Ingeschakeld",
21
+ "disabled": "Uitgeschakeld",
22
+ "itemCount": "items",
23
+ "actions": "Acties",
24
+ "status": "Status",
25
+ "syncStatus": "Synchronisatiestatus",
26
+ "feedsCount": "Totaal aantal feeds",
27
+ "itemsCount": "Totaal aantal items",
28
+ "lastSync": "Laatste synchronisatie",
29
+ "nextSync": "Volgende synchronisatie",
30
+ "never": "Nooit",
31
+ "error": {
32
+ "invalidUrl": "Voer een geldige feed-URL in",
33
+ "feedExists": "Deze feed is al toegevoegd",
34
+ "feedNotFound": "Feed niet gevonden",
35
+ "fetchFailed": "Ophalen van feed mislukt",
36
+ "noConfig": "RSS-endpoint niet correct geconfigureerd",
37
+ "noDatabase": "Database niet beschikbaar"
38
+ },
39
+ "success": {
40
+ "feedAdded": "Feed succesvol toegevoegd",
41
+ "feedRemoved": "Feed verwijderd",
42
+ "feedEnabled": "Feed ingeschakeld",
43
+ "feedDisabled": "Feed uitgeschakeld",
44
+ "syncComplete": "Synchronisatie voltooid",
45
+ "clearResync": "Items gewist en opnieuw gesynchroniseerd"
46
+ },
47
+ "widget": {
48
+ "description": "Bekijk geaggregeerde RSS-feeds op de openbare pagina",
49
+ "view": "Bekijk nieuwspagina"
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "rss": {
3
+ "title": "Czytnik RSS",
4
+ "feeds": "Kanały",
5
+ "items": "Elementy kanałów",
6
+ "addFeed": "Dodaj kanał",
7
+ "removeFeed": "Usuń kanał",
8
+ "enableFeed": "Włącz",
9
+ "disableFeed": "Wyłącz",
10
+ "syncNow": "Synchronizuj teraz",
11
+ "clearResync": "Wyczyść i zsynchronizuj ponownie",
12
+ "syncing": "Synchronizacja...",
13
+ "lastSynced": "Ostatnia synchronizacja",
14
+ "noFeeds": "Brak skonfigurowanych kanałów. Dodaj adres URL kanału, aby rozpocząć.",
15
+ "noItems": "Nie znaleziono elementów.",
16
+ "feedUrl": "Adres URL kanału",
17
+ "feedUrlPlaceholder": "https://przyklad.pl/feed.xml",
18
+ "recentItems": "Ostatnie elementy",
19
+ "viewAll": "Pokaż wszystkie",
20
+ "enabled": "Włączony",
21
+ "disabled": "Wyłączony",
22
+ "itemCount": "elementów",
23
+ "actions": "Działania",
24
+ "status": "Status",
25
+ "syncStatus": "Status synchronizacji",
26
+ "feedsCount": "Łącznie kanałów",
27
+ "itemsCount": "Łącznie elementów",
28
+ "lastSync": "Ostatnia synchronizacja",
29
+ "nextSync": "Następna synchronizacja",
30
+ "never": "Nigdy",
31
+ "error": {
32
+ "invalidUrl": "Wprowadź prawidłowy adres URL kanału",
33
+ "feedExists": "Ten kanał został już dodany",
34
+ "feedNotFound": "Nie znaleziono kanału",
35
+ "fetchFailed": "Nie udało się pobrać kanału",
36
+ "noConfig": "Endpoint RSS nie jest poprawnie skonfigurowany",
37
+ "noDatabase": "Baza danych niedostępna"
38
+ },
39
+ "success": {
40
+ "feedAdded": "Kanał dodany pomyślnie",
41
+ "feedRemoved": "Kanał usunięty",
42
+ "feedEnabled": "Kanał włączony",
43
+ "feedDisabled": "Kanał wyłączony",
44
+ "syncComplete": "Synchronizacja zakończona",
45
+ "clearResync": "Elementy wyczyszczone i zsynchronizowane ponownie"
46
+ },
47
+ "widget": {
48
+ "description": "Wyświetl zagregowane kanały RSS na stronie publicznej",
49
+ "view": "Zobacz stronę aktualności"
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "rss": {
3
+ "title": "Leitor RSS",
4
+ "feeds": "Feeds",
5
+ "items": "Itens de feeds",
6
+ "addFeed": "Adicionar feed",
7
+ "removeFeed": "Remover feed",
8
+ "enableFeed": "Ativar",
9
+ "disableFeed": "Desativar",
10
+ "syncNow": "Sincronizar agora",
11
+ "clearResync": "Limpar e ressincronizar",
12
+ "syncing": "Sincronizando...",
13
+ "lastSynced": "Última sincronização",
14
+ "noFeeds": "Nenhum feed configurado. Adicione uma URL de feed para começar.",
15
+ "noItems": "Nenhum item encontrado.",
16
+ "feedUrl": "URL do feed",
17
+ "feedUrlPlaceholder": "https://exemplo.com/feed.xml",
18
+ "recentItems": "Itens recentes",
19
+ "viewAll": "Ver tudo",
20
+ "enabled": "Ativado",
21
+ "disabled": "Desativado",
22
+ "itemCount": "itens",
23
+ "actions": "Ações",
24
+ "status": "Status",
25
+ "syncStatus": "Status de sincronização",
26
+ "feedsCount": "Total de feeds",
27
+ "itemsCount": "Total de itens",
28
+ "lastSync": "Última sincronização",
29
+ "nextSync": "Próxima sincronização",
30
+ "never": "Nunca",
31
+ "error": {
32
+ "invalidUrl": "Por favor, insira uma URL de feed válida",
33
+ "feedExists": "Este feed já foi adicionado",
34
+ "feedNotFound": "Feed não encontrado",
35
+ "fetchFailed": "Falha ao buscar o feed",
36
+ "noConfig": "O endpoint RSS não está configurado corretamente",
37
+ "noDatabase": "Banco de dados não disponível"
38
+ },
39
+ "success": {
40
+ "feedAdded": "Feed adicionado com sucesso",
41
+ "feedRemoved": "Feed removido",
42
+ "feedEnabled": "Feed ativado",
43
+ "feedDisabled": "Feed desativado",
44
+ "syncComplete": "Sincronização concluída",
45
+ "clearResync": "Itens limpos e ressincronizados"
46
+ },
47
+ "widget": {
48
+ "description": "Ver feeds RSS agregados na página pública",
49
+ "view": "Ver página de notícias"
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "rss": {
3
+ "title": "Leitor RSS",
4
+ "feeds": "Feeds",
5
+ "items": "Itens de feeds",
6
+ "addFeed": "Adicionar feed",
7
+ "removeFeed": "Remover feed",
8
+ "enableFeed": "Activar",
9
+ "disableFeed": "Desactivar",
10
+ "syncNow": "Sincronizar agora",
11
+ "clearResync": "Limpar e ressincronizar",
12
+ "syncing": "A sincronizar...",
13
+ "lastSynced": "Última sincronização",
14
+ "noFeeds": "Nenhum feed configurado. Adicione um URL de feed para começar.",
15
+ "noItems": "Nenhum item encontrado.",
16
+ "feedUrl": "URL do feed",
17
+ "feedUrlPlaceholder": "https://exemplo.com/feed.xml",
18
+ "recentItems": "Itens recentes",
19
+ "viewAll": "Ver tudo",
20
+ "enabled": "Activado",
21
+ "disabled": "Desactivado",
22
+ "itemCount": "itens",
23
+ "actions": "Acções",
24
+ "status": "Estado",
25
+ "syncStatus": "Estado de sincronização",
26
+ "feedsCount": "Total de feeds",
27
+ "itemsCount": "Total de itens",
28
+ "lastSync": "Última sincronização",
29
+ "nextSync": "Próxima sincronização",
30
+ "never": "Nunca",
31
+ "error": {
32
+ "invalidUrl": "Por favor, introduza um URL de feed válido",
33
+ "feedExists": "Este feed já foi adicionado",
34
+ "feedNotFound": "Feed não encontrado",
35
+ "fetchFailed": "Falha ao obter o feed",
36
+ "noConfig": "O endpoint RSS não está configurado correctamente",
37
+ "noDatabase": "Base de dados não disponível"
38
+ },
39
+ "success": {
40
+ "feedAdded": "Feed adicionado com sucesso",
41
+ "feedRemoved": "Feed removido",
42
+ "feedEnabled": "Feed activado",
43
+ "feedDisabled": "Feed desactivado",
44
+ "syncComplete": "Sincronização concluída",
45
+ "clearResync": "Itens limpos e ressincronizados"
46
+ },
47
+ "widget": {
48
+ "description": "Ver feeds RSS agregados na página pública",
49
+ "view": "Ver página de notícias"
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "rss": {
3
+ "title": "RSS читач",
4
+ "feeds": "Довоји",
5
+ "items": "Ставке довода",
6
+ "addFeed": "Додај довод",
7
+ "removeFeed": "Уклони довод",
8
+ "enableFeed": "Омогући",
9
+ "disableFeed": "Онемогући",
10
+ "syncNow": "Синхронизуј сада",
11
+ "clearResync": "Обриши и поново синхронизуј",
12
+ "syncing": "Синхронизација...",
13
+ "lastSynced": "Последња синхронизација",
14
+ "noFeeds": "Нема конфигурисаних довода. Додајте URL довода да бисте почели.",
15
+ "noItems": "Нема пронађених ставки.",
16
+ "feedUrl": "URL довода",
17
+ "feedUrlPlaceholder": "https://primer.rs/feed.xml",
18
+ "recentItems": "Недавне ставке",
19
+ "viewAll": "Прикажи све",
20
+ "enabled": "Омогућено",
21
+ "disabled": "Онемогућено",
22
+ "itemCount": "ставки",
23
+ "actions": "Радње",
24
+ "status": "Статус",
25
+ "syncStatus": "Статус синхронизације",
26
+ "feedsCount": "Укупно довода",
27
+ "itemsCount": "Укупно ставки",
28
+ "lastSync": "Последња синхронизација",
29
+ "nextSync": "Следећа синхронизација",
30
+ "never": "Никада",
31
+ "error": {
32
+ "invalidUrl": "Молимо унесите важећи URL довода",
33
+ "feedExists": "Овај довод је већ додат",
34
+ "feedNotFound": "Довод није пронађен",
35
+ "fetchFailed": "Неуспешно преузимање довода",
36
+ "noConfig": "RSS крајња тачка није правилно конфигурисана",
37
+ "noDatabase": "База података није доступна"
38
+ },
39
+ "success": {
40
+ "feedAdded": "Довод је успешно додат",
41
+ "feedRemoved": "Довод уклоњен",
42
+ "feedEnabled": "Довод омогућен",
43
+ "feedDisabled": "Довод онемогућен",
44
+ "syncComplete": "Синхронизација завршена",
45
+ "clearResync": "Ставке обрисане и поново синхронизоване"
46
+ },
47
+ "widget": {
48
+ "description": "Погледајте обједињене RSS доводе на јавној страници",
49
+ "view": "Погледај страницу вести"
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "rss": {
3
+ "title": "RSS-läsare",
4
+ "feeds": "Flöden",
5
+ "items": "Flödesobjekt",
6
+ "addFeed": "Lägg till flöde",
7
+ "removeFeed": "Ta bort flöde",
8
+ "enableFeed": "Aktivera",
9
+ "disableFeed": "Inaktivera",
10
+ "syncNow": "Synkronisera nu",
11
+ "clearResync": "Rensa och synkronisera om",
12
+ "syncing": "Synkroniserar...",
13
+ "lastSynced": "Senast synkroniserad",
14
+ "noFeeds": "Inga flöden konfigurerade. Lägg till en flödes-URL för att komma igång.",
15
+ "noItems": "Inga objekt hittades.",
16
+ "feedUrl": "Flödes-URL",
17
+ "feedUrlPlaceholder": "https://exempel.se/feed.xml",
18
+ "recentItems": "Senaste objekten",
19
+ "viewAll": "Visa alla",
20
+ "enabled": "Aktiverad",
21
+ "disabled": "Inaktiverad",
22
+ "itemCount": "objekt",
23
+ "actions": "Åtgärder",
24
+ "status": "Status",
25
+ "syncStatus": "Synkroniseringsstatus",
26
+ "feedsCount": "Totalt antal flöden",
27
+ "itemsCount": "Totalt antal objekt",
28
+ "lastSync": "Senaste synkronisering",
29
+ "nextSync": "Nästa synkronisering",
30
+ "never": "Aldrig",
31
+ "error": {
32
+ "invalidUrl": "Ange en giltig flödes-URL",
33
+ "feedExists": "Detta flöde har redan lagts till",
34
+ "feedNotFound": "Flödet hittades inte",
35
+ "fetchFailed": "Misslyckades med att hämta flöde",
36
+ "noConfig": "RSS-ändpunkten är inte korrekt konfigurerad",
37
+ "noDatabase": "Databasen är inte tillgänglig"
38
+ },
39
+ "success": {
40
+ "feedAdded": "Flödet har lagts till",
41
+ "feedRemoved": "Flödet har tagits bort",
42
+ "feedEnabled": "Flödet aktiverat",
43
+ "feedDisabled": "Flödet inaktiverat",
44
+ "syncComplete": "Synkronisering klar",
45
+ "clearResync": "Objekt rensade och omsynkroniserade"
46
+ },
47
+ "widget": {
48
+ "description": "Visa aggregerade RSS-flöden på den publika sidan",
49
+ "view": "Visa nyhetssida"
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "rss": {
3
+ "title": "RSS 阅读器",
4
+ "feeds": "订阅源",
5
+ "items": "订阅项目",
6
+ "addFeed": "添加订阅源",
7
+ "removeFeed": "删除订阅源",
8
+ "enableFeed": "启用",
9
+ "disableFeed": "禁用",
10
+ "syncNow": "立即同步",
11
+ "clearResync": "清除并重新同步",
12
+ "syncing": "同步中...",
13
+ "lastSynced": "上次同步",
14
+ "noFeeds": "未配置订阅源。添加订阅源 URL 以开始使用。",
15
+ "noItems": "未找到任何项目。",
16
+ "feedUrl": "订阅源 URL",
17
+ "feedUrlPlaceholder": "https://example.com/feed.xml",
18
+ "recentItems": "最近项目",
19
+ "viewAll": "查看全部",
20
+ "enabled": "已启用",
21
+ "disabled": "已禁用",
22
+ "itemCount": "项",
23
+ "actions": "操作",
24
+ "status": "状态",
25
+ "syncStatus": "同步状态",
26
+ "feedsCount": "订阅源总数",
27
+ "itemsCount": "项目总数",
28
+ "lastSync": "上次同步",
29
+ "nextSync": "下次同步",
30
+ "never": "从未",
31
+ "error": {
32
+ "invalidUrl": "请输入有效的订阅源 URL",
33
+ "feedExists": "此订阅源已添加",
34
+ "feedNotFound": "未找到订阅源",
35
+ "fetchFailed": "获取订阅源失败",
36
+ "noConfig": "RSS 端点未正确配置",
37
+ "noDatabase": "数据库不可用"
38
+ },
39
+ "success": {
40
+ "feedAdded": "订阅源添加成功",
41
+ "feedRemoved": "订阅源已删除",
42
+ "feedEnabled": "订阅源已启用",
43
+ "feedDisabled": "订阅源已禁用",
44
+ "syncComplete": "同步完成",
45
+ "clearResync": "项目已清除并重新同步"
46
+ },
47
+ "widget": {
48
+ "description": "在公共页面上查看聚合的 RSS 订阅源",
49
+ "view": "查看新闻页面"
50
+ }
51
+ }
52
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rmdes/indiekit-endpoint-rss",
3
- "version": "1.0.11",
3
+ "version": "1.0.12",
4
4
  "description": "RSS feed reader endpoint for Indiekit. Aggregates multiple feeds, caches in MongoDB, displays on frontend.",
5
5
  "keywords": [
6
6
  "indiekit",