furtrack-api 1.0.1 → 1.1.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 +8 -1
- package/package.json +1 -1
- package/src/index.js +75 -3
- package/src/index.test.js +1 -1
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
An unofficial Node.js package for accessing the Furtrack API.
|
|
4
4
|
|
|
5
|
+
> ⚠️ **Warning**: This package was built by **reverse engineering the FurTrack frontend**, and it is a **best-effort implementation**. FurTrack's internal API may change at any time, which can cause this package to break or behave unexpectedly.
|
|
6
|
+
|
|
5
7
|
|
|
6
8
|
## Features
|
|
7
9
|
|
|
@@ -75,6 +77,11 @@ api.getAlbum('username', 'albumid').then(album => {
|
|
|
75
77
|
console.log(album)
|
|
76
78
|
})
|
|
77
79
|
|
|
80
|
+
// Fetch all tags
|
|
81
|
+
api.getTags().then(tags => {
|
|
82
|
+
console.log(tags);
|
|
83
|
+
})
|
|
84
|
+
|
|
78
85
|
```
|
|
79
86
|
|
|
80
87
|
Functions which return a list of arrays additional support a page argument, FurTrack generally paginates albums longer than 200 images, by default only the first page is retrieved.
|
|
@@ -94,4 +101,4 @@ const characters = FurtrackAPI.getTagsByType(tags, FurtrackAPI.TagTypes.Characte
|
|
|
94
101
|
|
|
95
102
|
---
|
|
96
103
|
|
|
97
|
-
MIT License © 2025 blumlaut
|
|
104
|
+
MIT License © 2025 blumlaut
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -29,6 +29,9 @@ const https = require('https');
|
|
|
29
29
|
* @param {Object} [options] - Additional fetch options.
|
|
30
30
|
* @returns {Promise<Object>} The parsed JSON response.
|
|
31
31
|
*
|
|
32
|
+
* @method getTags Fetches all tags from FurTrack.
|
|
33
|
+
* @returns {Promise<Object>} Tags data with success flag and tags array.
|
|
34
|
+
*
|
|
32
35
|
* @method getTag Fetches information about a specific tag.
|
|
33
36
|
* @param {string} tag - The tag to fetch.
|
|
34
37
|
* @returns {Promise<Object>} Tag information.
|
|
@@ -116,7 +119,7 @@ class FurtrackAPI {
|
|
|
116
119
|
'2:': this.TagTypes.Maker,
|
|
117
120
|
'3:': this.TagTypes.Photographer,
|
|
118
121
|
'5:': this.TagTypes.Event,
|
|
119
|
-
'6': this.TagTypes.Species,
|
|
122
|
+
'6:': this.TagTypes.Species,
|
|
120
123
|
|
|
121
124
|
};
|
|
122
125
|
|
|
@@ -142,6 +145,10 @@ class FurtrackAPI {
|
|
|
142
145
|
return res.json();
|
|
143
146
|
}
|
|
144
147
|
|
|
148
|
+
getTags() {
|
|
149
|
+
return this.fetchJSON(`/get/tags/all`);
|
|
150
|
+
}
|
|
151
|
+
|
|
145
152
|
getTag(tag) {
|
|
146
153
|
return this.fetchJSON(`/get/index/${encodeURIComponent(tag)}`);
|
|
147
154
|
}
|
|
@@ -155,7 +162,7 @@ class FurtrackAPI {
|
|
|
155
162
|
}
|
|
156
163
|
|
|
157
164
|
async getPostsByTag(tag, page = 0) {
|
|
158
|
-
const response = await this.fetchJSON(`/
|
|
165
|
+
const response = await this.fetchJSON(`/view/index/${encodeURIComponent(tag)}${page > 0 ? `/${page}` : ''}`);
|
|
159
166
|
return response.posts || [];
|
|
160
167
|
}
|
|
161
168
|
|
|
@@ -195,13 +202,78 @@ class FurtrackAPI {
|
|
|
195
202
|
}
|
|
196
203
|
|
|
197
204
|
|
|
198
|
-
|
|
205
|
+
static getTagsByType(tags, type) {
|
|
199
206
|
return tags
|
|
200
207
|
.map(tag => this.parseTag(tag.tagName))
|
|
201
208
|
.filter(parsed => parsed.type === type)
|
|
202
209
|
.map(parsed => parsed.value);
|
|
203
210
|
}
|
|
204
211
|
|
|
212
|
+
/**
|
|
213
|
+
* Fetches all character tags associated with a maker tag.
|
|
214
|
+
* Returns the full character metadata including tag counts and followers.
|
|
215
|
+
*
|
|
216
|
+
* @param {string} makerTag - The maker tag (e.g., "wild_dog_works" or "maker:wild_dog_works").
|
|
217
|
+
* @returns {Promise<Array>} Array of character tag objects with metadata.
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* const characters = await api.getCharactersByMaker('wild_dog_works');
|
|
221
|
+
* // Returns: [{ tagName: '1:colby_(husky)', tagType: 1, tagTitle: 'Colby', ... }, ...]
|
|
222
|
+
*/
|
|
223
|
+
async getCharactersByMaker(makerTag) {
|
|
224
|
+
// Normalize tag format
|
|
225
|
+
if (!makerTag.startsWith('2:')) {
|
|
226
|
+
makerTag = `2:${makerTag}`;
|
|
227
|
+
}
|
|
228
|
+
const tagData = await this.getTag(makerTag.replace('2:', 'maker:'));
|
|
229
|
+
return tagData.tagmeta?.tagChildrenFull || [];
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Fetches all related tags for a character, including makers, species, and color tags.
|
|
234
|
+
*
|
|
235
|
+
* @param {string} characterTag - The character tag (e.g., "colby_(husky)" or "character:colby_(husky)").
|
|
236
|
+
* @returns {Promise<Object>} Object with categorized related tags.
|
|
237
|
+
* @returns {Promise<Object>.makers} Array of maker tag values.
|
|
238
|
+
* @returns {Promise<Object>.species} Array of species tag values.
|
|
239
|
+
* @returns {Promise<Object>.colors} Array of color/general tag values.
|
|
240
|
+
* @returns {Promise<Object>.all} Array of all related tag names.
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* const related = await api.getRelatedTagsByCharacter('colby_(husky)');
|
|
244
|
+
* // Returns: { makers: ['wild_dog_works', 'pyrope_costumes'], species: ['husky'], colors: ['black', 'blue', ...], all: [...] }
|
|
245
|
+
*/
|
|
246
|
+
async getRelatedTagsByCharacter(characterTag) {
|
|
247
|
+
// Normalize tag format
|
|
248
|
+
if (!characterTag.startsWith('1:')) {
|
|
249
|
+
characterTag = `1:${characterTag}`;
|
|
250
|
+
}
|
|
251
|
+
const tagData = await this.getTag(characterTag.replace('1:', 'character:'));
|
|
252
|
+
const tagAlso = tagData.tagmeta?.tagAlso || [];
|
|
253
|
+
|
|
254
|
+
return {
|
|
255
|
+
makers: FurtrackAPI.getTagsByType(tagAlso.map(t => ({ tagName: t })), FurtrackAPI.TagTypes.Maker),
|
|
256
|
+
species: FurtrackAPI.getTagsByType(tagAlso.map(t => ({ tagName: t })), FurtrackAPI.TagTypes.Species),
|
|
257
|
+
colors: tagAlso.filter(t => !t.startsWith('1:') && !t.startsWith('2:') && !t.startsWith('3:') && !t.startsWith('5:') && !t.startsWith('6:')),
|
|
258
|
+
all: tagAlso
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Fetches all makers associated with a character tag.
|
|
264
|
+
*
|
|
265
|
+
* @param {string} characterTag - The character tag (e.g., "colby_(husky)" or "character:colby_(husky)").
|
|
266
|
+
* @returns {Promise<Array>} Array of maker tag values.
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* const makers = await api.getMakersByCharacter('colby_(husky)');
|
|
270
|
+
* // Returns: ['wild_dog_works', 'pyrope_costumes']
|
|
271
|
+
*/
|
|
272
|
+
async getMakersByCharacter(characterTag) {
|
|
273
|
+
const related = await this.getRelatedTagsByCharacter(characterTag);
|
|
274
|
+
return related.makers;
|
|
275
|
+
}
|
|
276
|
+
|
|
205
277
|
}
|
|
206
278
|
|
|
207
279
|
module.exports = FurtrackAPI;
|
package/src/index.test.js
CHANGED
|
@@ -50,7 +50,7 @@ describe('FurtrackAPI', () => {
|
|
|
50
50
|
expect(result).toEqual({ type: FurtrackAPI.TagTypes.Event, value: 'SomeEvent' });
|
|
51
51
|
});
|
|
52
52
|
test('parses species tag', () => {
|
|
53
|
-
const result = api.parseTag('
|
|
53
|
+
const result = api.parseTag('6:Wolf');
|
|
54
54
|
expect(result).toEqual({ type: FurtrackAPI.TagTypes.Species, value: 'Wolf' });
|
|
55
55
|
});
|
|
56
56
|
test('parses general tag', () => {
|