fnapi-js 1.1.0 → 1.1.2
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 +3 -0
- package/package.json +1 -1
- package/src/client/Cosmetics.js +1 -1
- package/src/client/Misc.js +1 -1
- package/src/docs/DOCUMENTATION.md +435 -0
- package/src/enums/CosmeticType.js +1 -1
- package/src/examples/api-example.js +220 -0
- package/src/examples/fnbrjsAndfnapi.js +63 -0
- package/src/index.js +1 -1
- package/src/utils/Enums.js +1 -1
package/README.md
CHANGED
|
@@ -43,6 +43,9 @@ const creatorCode = await fnApi.sac.get('code');
|
|
|
43
43
|
const aesKeys = await fnApi.aes.getKeys();
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
+
## Check out the docs
|
|
47
|
+
- [Documentation](https://github.com/AjaxFNC-YT/fnapi-js/blob/main/src/docs/DOCUMENTATION.md)
|
|
48
|
+
|
|
46
49
|
## Available Endpoints
|
|
47
50
|
|
|
48
51
|
- Stats
|
package/package.json
CHANGED
package/src/client/Cosmetics.js
CHANGED
package/src/client/Misc.js
CHANGED
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
# FNAPI-JS Documentation
|
|
2
|
+
|
|
3
|
+
FNAPI-JS is an unofficial JavaScript wrapper for the [Fortnite-API.com](https://fortnite-api.com/) service. This library provides easy access to various Fortnite game data including cosmetics, shop, stats, news, and more.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install fnapi-js
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Getting Started
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
import { ApiClient, RequestFlags, Enums } from 'fnapi-js';
|
|
15
|
+
|
|
16
|
+
// Initialize the API client
|
|
17
|
+
const client = new ApiClient({
|
|
18
|
+
apiKey: 'your-api-key', // Optional, but required for some endpoints
|
|
19
|
+
timeout: 30000 // Optional, default is 30000ms
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// Example: Get current shop
|
|
23
|
+
const shop = await client.shop.get();
|
|
24
|
+
console.log(shop);
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Table of Contents
|
|
28
|
+
|
|
29
|
+
- [API Client](#api-client)
|
|
30
|
+
- [Response Object](#response-object)
|
|
31
|
+
- [Enums](#enums)
|
|
32
|
+
- [Request Flags](#request-flags)
|
|
33
|
+
- [Account Type](#account-type)
|
|
34
|
+
- [Cosmetic Type](#cosmetic-type)
|
|
35
|
+
- [Language](#language)
|
|
36
|
+
- [Match Method](#match-method)
|
|
37
|
+
- [Stats Image](#stats-image)
|
|
38
|
+
- [Time Window](#time-window)
|
|
39
|
+
- [Endpoints](#endpoints)
|
|
40
|
+
- [Cosmetics](#cosmetics)
|
|
41
|
+
- [Shop](#shop)
|
|
42
|
+
- [Stats](#stats)
|
|
43
|
+
- [AES](#aes)
|
|
44
|
+
- [Banners](#banners)
|
|
45
|
+
- [Creator Code](#creator-code)
|
|
46
|
+
- [Map](#map)
|
|
47
|
+
- [News](#news)
|
|
48
|
+
- [Playlists](#playlists)
|
|
49
|
+
- [Misc](#misc)
|
|
50
|
+
- [Search Options](#search-options)
|
|
51
|
+
|
|
52
|
+
## API Client
|
|
53
|
+
|
|
54
|
+
The `ApiClient` is the main entry point for interacting with the API.
|
|
55
|
+
|
|
56
|
+
```javascript
|
|
57
|
+
import { ApiClient } from 'fnapi-js';
|
|
58
|
+
|
|
59
|
+
const client = new ApiClient({
|
|
60
|
+
apiKey: 'your-api-key', // Optional, but required for some endpoints
|
|
61
|
+
timeout: 30000, // Optional, default is 30000ms
|
|
62
|
+
headers: {} // Optional, additional headers
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Methods
|
|
67
|
+
|
|
68
|
+
- `request(method, path, data, options)`: Make a direct API request
|
|
69
|
+
- `setHeader(key, value)`: Set a custom header for all requests
|
|
70
|
+
- `getBaseUrl()`: Get the base URL of the API
|
|
71
|
+
|
|
72
|
+
## Response Object
|
|
73
|
+
|
|
74
|
+
All API requests return a `Response` object with the following methods:
|
|
75
|
+
|
|
76
|
+
- `status()`: Get the HTTP status code
|
|
77
|
+
- `headers()`: Get the response headers
|
|
78
|
+
- `body()`: Get the response body
|
|
79
|
+
- `isSuccess()`: Check if the request was successful (status code 200-299)
|
|
80
|
+
|
|
81
|
+
## Enums
|
|
82
|
+
|
|
83
|
+
FNAPI-JS provides several enums to make it easier to work with the API. Import them using:
|
|
84
|
+
|
|
85
|
+
```javascript
|
|
86
|
+
import { Enums } from 'fnapi-js';
|
|
87
|
+
// Or import specific enums
|
|
88
|
+
import { RequestFlags, AccountType, Language } from 'fnapi-js';
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Request Flags
|
|
92
|
+
|
|
93
|
+
Request flags can be used to include additional data in responses.
|
|
94
|
+
|
|
95
|
+
```javascript
|
|
96
|
+
import { RequestFlags } from 'fnapi-js';
|
|
97
|
+
|
|
98
|
+
// Available flags
|
|
99
|
+
const allFlags = RequestFlags.all(); // Include all additional data
|
|
100
|
+
const pathsFlag = RequestFlags.paths(); // Include file paths
|
|
101
|
+
const tagsFlag = RequestFlags.gameplayTags(); // Include gameplay tags
|
|
102
|
+
const historyFlag = RequestFlags.shopHistory(); // Include shop history
|
|
103
|
+
const noFlags = RequestFlags.none(); // No additional data
|
|
104
|
+
|
|
105
|
+
// Combine multiple flags
|
|
106
|
+
const combinedFlags = RequestFlags.multiple(
|
|
107
|
+
RequestFlags.FLAGS.INCLUDE_PATHS,
|
|
108
|
+
RequestFlags.FLAGS.INCLUDE_GAMEPLAY_TAGS
|
|
109
|
+
);
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Account Type
|
|
113
|
+
|
|
114
|
+
Used for specifying account platforms when fetching player stats.
|
|
115
|
+
|
|
116
|
+
```javascript
|
|
117
|
+
import { AccountType } from 'fnapi-js';
|
|
118
|
+
|
|
119
|
+
// Available account types
|
|
120
|
+
const epicAccount = AccountType.epic(); // Epic Games account
|
|
121
|
+
const psnAccount = AccountType.psn(); // PlayStation Network account
|
|
122
|
+
const xblAccount = AccountType.xbl(); // Xbox Live account
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Cosmetic Type
|
|
126
|
+
|
|
127
|
+
Used for specifying cosmetic types when searching for cosmetics.
|
|
128
|
+
|
|
129
|
+
```javascript
|
|
130
|
+
import { CosmeticType } from 'fnapi-js';
|
|
131
|
+
|
|
132
|
+
// Available cosmetic types
|
|
133
|
+
const outfit = CosmeticType.outfit(); // Character outfits
|
|
134
|
+
const emote = CosmeticType.emote(); // Emotes/dances
|
|
135
|
+
const wrap = CosmeticType.wrap(); // Weapon/vehicle wraps
|
|
136
|
+
const emoji = CosmeticType.emoji(); // Emojis
|
|
137
|
+
const glider = CosmeticType.glider(); // Gliders
|
|
138
|
+
const spray = CosmeticType.spray(); // Sprays
|
|
139
|
+
const loadingscreen = CosmeticType.loadingscreen(); // Loading screens
|
|
140
|
+
const contrail = CosmeticType.contrail(); // Contrails
|
|
141
|
+
const shoes = CosmeticType.shoes(); // Shoes
|
|
142
|
+
const pickaxe = CosmeticType.pickaxe(); // Harvesting tools
|
|
143
|
+
const backpack = CosmeticType.backpack(); // Back blings
|
|
144
|
+
const musicpack = CosmeticType.musicpack(); // Music packs
|
|
145
|
+
const toy = CosmeticType.toy(); // Toys
|
|
146
|
+
const pet = CosmeticType.pet(); // Pets
|
|
147
|
+
|
|
148
|
+
// Vehicle cosmetics
|
|
149
|
+
const vehicleSkin = CosmeticType.vehicleskin(); // Vehicle skins
|
|
150
|
+
const vehicleWheel = CosmeticType.vehiclewheel(); // Vehicle wheels
|
|
151
|
+
const vehicleBooster = CosmeticType.vehiclebooster(); // Vehicle boosters
|
|
152
|
+
const vehicleDriftTrail = CosmeticType.vehicledrifttrail(); // Vehicle drift trails
|
|
153
|
+
const vehicleBody = CosmeticType.vehiclebody(); // Vehicle bodies
|
|
154
|
+
|
|
155
|
+
// LEGO/Building cosmetics
|
|
156
|
+
const junoBuildingProp = CosmeticType.junobuildingprop(); // Decor bundles
|
|
157
|
+
const junoBuildingSet = CosmeticType.junobuildingset(); // Building sets
|
|
158
|
+
|
|
159
|
+
// Musical instruments
|
|
160
|
+
const sparksGuitar = CosmeticType.sparksguitar(); // Guitars
|
|
161
|
+
const sparksBass = CosmeticType.sparksbass(); // Bass guitars
|
|
162
|
+
const sparksDrum = CosmeticType.sparksdrum(); // Drums
|
|
163
|
+
const sparksMic = CosmeticType.sparksmic(); // Microphones
|
|
164
|
+
const sparksKeyboard = CosmeticType.sparkskeyboard(); // Keytars
|
|
165
|
+
const sparksAura = CosmeticType.sparksaura(); // Auras
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Language
|
|
169
|
+
|
|
170
|
+
Used for specifying language preferences for API responses.
|
|
171
|
+
|
|
172
|
+
```javascript
|
|
173
|
+
import { Language } from 'fnapi-js';
|
|
174
|
+
|
|
175
|
+
// Available languages
|
|
176
|
+
const english = Language.english(); // English (en)
|
|
177
|
+
const german = Language.german(); // German (de)
|
|
178
|
+
const spanish = Language.spanish(); // Spanish (es)
|
|
179
|
+
const spanishLatinAmerica = Language.spanishLatinAmerica(); // Spanish - Latin America (es-419)
|
|
180
|
+
const french = Language.french(); // French (fr)
|
|
181
|
+
const italian = Language.italian(); // Italian (it)
|
|
182
|
+
const japanese = Language.japanese(); // Japanese (ja)
|
|
183
|
+
const korean = Language.korean(); // Korean (ko)
|
|
184
|
+
const polish = Language.polish(); // Polish (pl)
|
|
185
|
+
const portugueseBrazil = Language.portugueseBrazil(); // Portuguese - Brazil (pt-BR)
|
|
186
|
+
const russian = Language.russian(); // Russian (ru)
|
|
187
|
+
const turkish = Language.turkish(); // Turkish (tr)
|
|
188
|
+
const chineseSimplified = Language.chineseSimplified(); // Chinese - Simplified (zh-Hans)
|
|
189
|
+
const chineseTraditional = Language.chineseTraditional(); // Chinese - Traditional (zh-Hant)
|
|
190
|
+
const arabic = Language.arabic(); // Arabic (ar)
|
|
191
|
+
const indonesian = Language.indonesian(); // Indonesian (id)
|
|
192
|
+
const thai = Language.thai(); // Thai (th)
|
|
193
|
+
const vietnamese = Language.vietnamese(); // Vietnamese (vi)
|
|
194
|
+
|
|
195
|
+
// Get all available languages
|
|
196
|
+
const allLanguages = Language.getAll();
|
|
197
|
+
|
|
198
|
+
// Check if a language code is valid
|
|
199
|
+
const isValid = Language.isValid('en'); // true
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Match Method
|
|
203
|
+
|
|
204
|
+
Used for specifying how search terms should match when searching for cosmetics.
|
|
205
|
+
|
|
206
|
+
```javascript
|
|
207
|
+
import { MatchMethod } from 'fnapi-js';
|
|
208
|
+
|
|
209
|
+
// Available match methods
|
|
210
|
+
const fullMatch = MatchMethod.full(); // Exact match (same as exact())
|
|
211
|
+
const exactMatch = MatchMethod.exact(); // Exact match (same as full())
|
|
212
|
+
const containsMatch = MatchMethod.contains(); // Contains the search term
|
|
213
|
+
const startsMatch = MatchMethod.starts(); // Starts with the search term
|
|
214
|
+
const endsMatch = MatchMethod.ends(); // Ends with the search term
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Stats Image
|
|
218
|
+
|
|
219
|
+
Used for specifying which stats images to include when fetching player stats.
|
|
220
|
+
|
|
221
|
+
```javascript
|
|
222
|
+
import { StatsImage } from 'fnapi-js';
|
|
223
|
+
|
|
224
|
+
// Available stats image types
|
|
225
|
+
const allImages = StatsImage.all(); // All input types
|
|
226
|
+
const keyboardMouseImages = StatsImage.keyboardMouse(); // Keyboard and mouse only
|
|
227
|
+
const gamepadImages = StatsImage.gamepad(); // Controller only
|
|
228
|
+
const touchImages = StatsImage.touch(); // Touch input only
|
|
229
|
+
const noImages = StatsImage.none(); // No images
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Time Window
|
|
233
|
+
|
|
234
|
+
Used for specifying the time period when fetching player stats.
|
|
235
|
+
|
|
236
|
+
```javascript
|
|
237
|
+
import { TimeWindow } from 'fnapi-js';
|
|
238
|
+
|
|
239
|
+
// Available time windows
|
|
240
|
+
const lifetime = TimeWindow.lifetime(); // Lifetime stats
|
|
241
|
+
const season = TimeWindow.season(); // Current season stats
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Endpoints
|
|
245
|
+
|
|
246
|
+
### Cosmetics
|
|
247
|
+
|
|
248
|
+
Access Fortnite cosmetic items data.
|
|
249
|
+
|
|
250
|
+
```javascript
|
|
251
|
+
import { RequestFlags, CosmeticType, SearchOptions, MatchMethod, Language } from 'fnapi-js';
|
|
252
|
+
|
|
253
|
+
// Get all cosmetics with additional data
|
|
254
|
+
const cosmetics = await client.cosmetics.getAll(RequestFlags.all());
|
|
255
|
+
|
|
256
|
+
// Get new cosmetics with file paths
|
|
257
|
+
const newCosmetics = await client.cosmetics.getAllNew(RequestFlags.paths());
|
|
258
|
+
|
|
259
|
+
// Get all music tracks
|
|
260
|
+
const tracks = await client.cosmetics.getAllTracks(RequestFlags.none());
|
|
261
|
+
|
|
262
|
+
// Get all instruments
|
|
263
|
+
const instruments = await client.cosmetics.getAllInstrument(RequestFlags.none());
|
|
264
|
+
|
|
265
|
+
// Get all cars
|
|
266
|
+
const cars = await client.cosmetics.getAllCars(RequestFlags.none());
|
|
267
|
+
|
|
268
|
+
// Get all LEGO items
|
|
269
|
+
const lego = await client.cosmetics.getAllLego(RequestFlags.none());
|
|
270
|
+
|
|
271
|
+
// Get all LEGO kits
|
|
272
|
+
const legoKits = await client.cosmetics.getAllLegoKits(RequestFlags.none());
|
|
273
|
+
|
|
274
|
+
// Get all beans
|
|
275
|
+
const beans = await client.cosmetics.getAllBeans(RequestFlags.none());
|
|
276
|
+
|
|
277
|
+
// Get cosmetic by ID with gameplay tags
|
|
278
|
+
const cosmetic = await client.cosmetics.getById('CID_001_Athena_Commando_F_Default', RequestFlags.gameplayTags());
|
|
279
|
+
|
|
280
|
+
// Search cosmetics using enums
|
|
281
|
+
const searchOptions = new SearchOptions()
|
|
282
|
+
.setLanguage(Language.english())
|
|
283
|
+
.setName('Renegade')
|
|
284
|
+
.setType(CosmeticType.outfit())
|
|
285
|
+
.setMatchMethod(MatchMethod.contains());
|
|
286
|
+
|
|
287
|
+
const searchResults = await client.cosmetics.search(searchOptions, RequestFlags.all(), true);
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### Shop
|
|
291
|
+
|
|
292
|
+
Get the current Fortnite item shop.
|
|
293
|
+
|
|
294
|
+
```javascript
|
|
295
|
+
// Get current shop
|
|
296
|
+
const shop = await client.shop.get();
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Stats
|
|
300
|
+
|
|
301
|
+
Get player statistics. Requires an API key.
|
|
302
|
+
|
|
303
|
+
```javascript
|
|
304
|
+
import { AccountType, TimeWindow, StatsImage } from 'fnapi-js';
|
|
305
|
+
|
|
306
|
+
// Get player stats by name
|
|
307
|
+
const stats = await client.stats.get(
|
|
308
|
+
'Ninja', // Player name
|
|
309
|
+
AccountType.epic(), // Account type
|
|
310
|
+
TimeWindow.lifetime(), // Time window
|
|
311
|
+
StatsImage.all() // Image type
|
|
312
|
+
);
|
|
313
|
+
|
|
314
|
+
// Get player stats by ID
|
|
315
|
+
const statsById = await client.stats.byId(
|
|
316
|
+
'player-account-id',
|
|
317
|
+
TimeWindow.season(),
|
|
318
|
+
StatsImage.keyboardMouse()
|
|
319
|
+
);
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### AES
|
|
323
|
+
|
|
324
|
+
Get AES encryption keys used by Fortnite.
|
|
325
|
+
|
|
326
|
+
```javascript
|
|
327
|
+
// Get current AES keys
|
|
328
|
+
const aes = await client.aes.get();
|
|
329
|
+
// Returns: { build, mainKey, dynamicKeys }
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Banners
|
|
333
|
+
|
|
334
|
+
Get Fortnite banner icons and colors.
|
|
335
|
+
|
|
336
|
+
```javascript
|
|
337
|
+
// Get all banners
|
|
338
|
+
const banners = await client.banners.get();
|
|
339
|
+
|
|
340
|
+
// Get all banner colors
|
|
341
|
+
const bannerColors = await client.banners.getColors();
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### Creator Code
|
|
345
|
+
|
|
346
|
+
Look up Support-A-Creator (SAC) codes.
|
|
347
|
+
|
|
348
|
+
```javascript
|
|
349
|
+
// Get creator code information
|
|
350
|
+
const creatorInfo = await client.sac.get('code-name');
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### Map
|
|
354
|
+
|
|
355
|
+
Get the current Fortnite map data.
|
|
356
|
+
|
|
357
|
+
```javascript
|
|
358
|
+
// Get current map
|
|
359
|
+
const map = await client.map.get();
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### News
|
|
363
|
+
|
|
364
|
+
Get the current in-game news.
|
|
365
|
+
|
|
366
|
+
```javascript
|
|
367
|
+
// Get current news
|
|
368
|
+
const news = await client.news.get();
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### Playlists
|
|
372
|
+
|
|
373
|
+
Get information about Fortnite game modes/playlists.
|
|
374
|
+
|
|
375
|
+
```javascript
|
|
376
|
+
// Get all playlists
|
|
377
|
+
const playlists = await client.playlists.all();
|
|
378
|
+
|
|
379
|
+
// Get playlist by ID
|
|
380
|
+
const playlist = await client.playlists.byId('playlist-id');
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### Misc
|
|
384
|
+
|
|
385
|
+
Utility functions.
|
|
386
|
+
|
|
387
|
+
```javascript
|
|
388
|
+
// Fix a file path
|
|
389
|
+
const fixedPath = await client.misc.fixPath('FortniteGame/Content/path/to/file');
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
## Search Options
|
|
393
|
+
|
|
394
|
+
The `SearchOptions` class provides a fluent interface for building search queries.
|
|
395
|
+
|
|
396
|
+
```javascript
|
|
397
|
+
import { SearchOptions, Language, MatchMethod, CosmeticType } from 'fnapi-js';
|
|
398
|
+
|
|
399
|
+
const options = new SearchOptions()
|
|
400
|
+
.setLanguage(Language.english()) // Set response language
|
|
401
|
+
.setSearchLanguage(Language.english()) // Set search language
|
|
402
|
+
.setMatchMethod(MatchMethod.contains()) // Match method
|
|
403
|
+
.setId('CID_001') // Search by ID
|
|
404
|
+
.setName('Renegade') // Search by name
|
|
405
|
+
.setDescription('description') // Search by description
|
|
406
|
+
.setType(CosmeticType.outfit()) // Search by type
|
|
407
|
+
.setDisplayType('Outfit') // Search by display type
|
|
408
|
+
.setBackendType('AthenaCharacter') // Search by backend type
|
|
409
|
+
.setRarity('epic') // Search by rarity
|
|
410
|
+
.setDisplayRarity('Epic') // Search by display rarity
|
|
411
|
+
.setBackendRarity('EFortRarity::Epic') // Search by backend rarity
|
|
412
|
+
.setHasSeries(true) // Filter by whether item has a series
|
|
413
|
+
.setSeries('marvel') // Search by series
|
|
414
|
+
.setBackendSeries('Series.Marvel') // Search by backend series
|
|
415
|
+
.setHasSet(true) // Filter by whether item has a set
|
|
416
|
+
.setSet('marvel') // Search by set
|
|
417
|
+
.setSetText('Marvel') // Search by set text
|
|
418
|
+
.setBackendSet('Set.Marvel') // Search by backend set
|
|
419
|
+
.setHasIntroduction(true) // Filter by whether item has introduction data
|
|
420
|
+
.setBackendIntroduction('Chapter2Season4') // Search by backend introduction
|
|
421
|
+
.setIntroductionChapter(2) // Search by introduction chapter
|
|
422
|
+
.setIntroductionSeason(4) // Search by introduction season
|
|
423
|
+
.setHasFeaturedImage(true) // Filter by whether item has featured image
|
|
424
|
+
.setHasVariants(true) // Filter by whether item has variants
|
|
425
|
+
.setHasGameplayTags(true) // Filter by whether item has gameplay tags
|
|
426
|
+
.setGameplayTag('Cosmetics.Source.ItemShop') // Search by gameplay tag
|
|
427
|
+
.setHasMetaTags(true) // Filter by whether item has meta tags
|
|
428
|
+
.setMetaTag('Cosmetics.Filter.Season.10') // Search by meta tag
|
|
429
|
+
.setHasDynamicPakId(true) // Filter by whether item has dynamic pak ID
|
|
430
|
+
.setDynamicPakId('pak-id') // Search by dynamic pak ID
|
|
431
|
+
.setAdded('2020-01-01T00:00:00Z') // Search by added date
|
|
432
|
+
.setAddedSince('2020-01-01T00:00:00Z') // Search by added since date
|
|
433
|
+
.setUnseenFor(30) // Search by unseen for days
|
|
434
|
+
.setLastAppearance('2020-01-01T00:00:00Z'); // Search by last appearance date
|
|
435
|
+
```
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
|
|
2
|
+
import { ApiClient, Enums, SearchOptions } from '../index.js'; // if you are using this code, change this to the module name, so: fnapi-js
|
|
3
|
+
import readline from 'readline';
|
|
4
|
+
|
|
5
|
+
const fnApi = new ApiClient({ apiKey: 'api-key here' });
|
|
6
|
+
|
|
7
|
+
const rl = readline.createInterface({
|
|
8
|
+
input: process.stdin,
|
|
9
|
+
output: process.stdout
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
const commands = {
|
|
13
|
+
'stats': async (args) => {
|
|
14
|
+
const [username] = args;
|
|
15
|
+
if (!username) {
|
|
16
|
+
console.log('Usage: stats <username>');
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
const stats = await fnApi.stats.get(
|
|
21
|
+
username,
|
|
22
|
+
Enums.accountType.epic(),
|
|
23
|
+
Enums.timeWindow.lifetime(),
|
|
24
|
+
Enums.statsImage.all()
|
|
25
|
+
);
|
|
26
|
+
console.log('Stats:', JSON.stringify(stats, null, 2));
|
|
27
|
+
} catch (error) {
|
|
28
|
+
console.error('Error:', error.message);
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
'help': () => {
|
|
32
|
+
console.log('Available commands:\n' +
|
|
33
|
+
' stats <username> - Get player stats\n' +
|
|
34
|
+
' exit - Exit the program\n' +
|
|
35
|
+
' help - Show this help message\n' +
|
|
36
|
+
' map - Get the map\n' +
|
|
37
|
+
' searchcosmetic <name> - Search for a cosmetic\n' +
|
|
38
|
+
' cosmetics <all|new|tracks|instrument|cars|lego|legokits|beans> - Get cosmetics\n' +
|
|
39
|
+
' cosmetic <id> - Get a specific cosmetic\n' +
|
|
40
|
+
' creatorcode <code> - Get a creator code\n' +
|
|
41
|
+
' aes - Get all aes keys\n' +
|
|
42
|
+
' banners - Get all banners\n' +
|
|
43
|
+
' bannerscolors - Get all banner colors\n' +
|
|
44
|
+
' map - Get the map\n' +
|
|
45
|
+
' news - Get the news\n' +
|
|
46
|
+
' playlists - Get all playlists\n' +
|
|
47
|
+
' shop - Get the shop'
|
|
48
|
+
);
|
|
49
|
+
},
|
|
50
|
+
'news': async () => {
|
|
51
|
+
try {
|
|
52
|
+
const data = await fnApi.news.get();
|
|
53
|
+
console.log(JSON.stringify(data, null, 2));
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.error("Error:", error.message);
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
'playlists': async () => {
|
|
59
|
+
try {
|
|
60
|
+
const data = await fnApi.playlists.all();
|
|
61
|
+
console.log(JSON.stringify(data, null, 2));
|
|
62
|
+
} catch (error) {
|
|
63
|
+
console.error("Error:", error.message);
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
'shop': async () => {
|
|
67
|
+
try {
|
|
68
|
+
const data = await fnApi.shop.get();
|
|
69
|
+
console.log(JSON.stringify(data, null, 2));
|
|
70
|
+
} catch (error) {
|
|
71
|
+
console.error("Error:", error.message);
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
'map': async () => {
|
|
75
|
+
try {
|
|
76
|
+
const data = await fnApi.map.get();
|
|
77
|
+
console.log(JSON.stringify(data, null, 2));
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.error("Error:", error.message);
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
'aes': async () => {
|
|
83
|
+
try {
|
|
84
|
+
const data = await fnApi.aes.get();
|
|
85
|
+
console.log(JSON.stringify(data, null, 2));
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.error("Error:", error.message);
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
'banners': async () => {
|
|
91
|
+
try {
|
|
92
|
+
const data = await fnApi.banners.get();
|
|
93
|
+
console.log(JSON.stringify(data, null, 2));
|
|
94
|
+
} catch (error) {
|
|
95
|
+
console.error("Error:", error.message);
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
'bannerscolors': async () => {
|
|
99
|
+
try {
|
|
100
|
+
const data = await fnApi.banners.getColors();
|
|
101
|
+
console.log(JSON.stringify(data, null, 2));
|
|
102
|
+
} catch (error) {
|
|
103
|
+
console.error("Error:", error.message);
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
'creatorcode': async (args) => {
|
|
107
|
+
const [code] = args;
|
|
108
|
+
if (!code) {
|
|
109
|
+
console.log('Usage creatorcode <code>')
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
const search = await fnApi.sac.get(code);
|
|
115
|
+
console.log('Creator Code:', JSON.stringify(search, null, 2));
|
|
116
|
+
} catch (eorrr) {
|
|
117
|
+
console.error("Error:", eorrr.message);
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
'searchcosmetic': async (args) => {
|
|
121
|
+
const [name] = args;
|
|
122
|
+
if (!name) {
|
|
123
|
+
console.log('Usage: searchcosmetic <name>');
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
const searchOptions = new SearchOptions()
|
|
128
|
+
.setMatchMethod(Enums.matchMethod.exact())
|
|
129
|
+
.setName(name);
|
|
130
|
+
const cosmetics = await fnApi.cosmetics.search(searchOptions, Enums.requestFlags.multiple(Enums.requestFlags.paths(), Enums.requestFlags.gameplayTags()), false);
|
|
131
|
+
console.log('Cosmetics:', JSON.stringify(cosmetics.body().data, null, 2));
|
|
132
|
+
} catch (error) {
|
|
133
|
+
console.error('Error:', error.message);
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
'cosmetic': async (args) => {
|
|
137
|
+
const [id] = args;
|
|
138
|
+
if (!id) {
|
|
139
|
+
console.log('Usage: cosmetic <id>');
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
try {
|
|
143
|
+
const cosmetic = await fnApi.cosmetics.getById(id, Enums.requestFlags.all());
|
|
144
|
+
console.log('Cosmetic:', JSON.stringify(cosmetic.body().data, null, 2));
|
|
145
|
+
} catch (error) {
|
|
146
|
+
console.error('Error:', error.message);
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
'cosmetics': async (args) => {
|
|
150
|
+
const [type] = args;
|
|
151
|
+
if (!type) {
|
|
152
|
+
console.log('Usage: cosmetics <all|new|tracks|instrument|cars|lego|legokits|beans>');
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
try {
|
|
156
|
+
switch (type) {
|
|
157
|
+
case 'all':
|
|
158
|
+
const cosmetics = await fnApi.cosmetics.getAll(Enums.requestFlags.all());
|
|
159
|
+
console.log('Cosmetics:', JSON.stringify(cosmetics.body().data, null, 2));
|
|
160
|
+
break;
|
|
161
|
+
case 'new':
|
|
162
|
+
const cosmeticsNew = await fnApi.cosmetics.getAllNew(Enums.requestFlags.all());
|
|
163
|
+
console.log('Cosmetics:', JSON.stringify(cosmeticsNew.body().data, null, 2));
|
|
164
|
+
break;
|
|
165
|
+
case 'tracks':
|
|
166
|
+
const cosmeticsTracks = await fnApi.cosmetics.getAllTracks(Enums.requestFlags.all());
|
|
167
|
+
console.log('Cosmetics:', JSON.stringify(cosmeticsTracks.body().data, null, 2));
|
|
168
|
+
break;
|
|
169
|
+
case 'instrument':
|
|
170
|
+
const cosmeticsInstrument = await fnApi.cosmetics.getAllInstrument(Enums.requestFlags.all());
|
|
171
|
+
console.log('Cosmetics:', JSON.stringify(cosmeticsInstrument.body().data, null, 2));
|
|
172
|
+
break;
|
|
173
|
+
case 'cars':
|
|
174
|
+
const cosmeticsCars = await fnApi.cosmetics.getAllCars(Enums.requestFlags.all());
|
|
175
|
+
console.log('Cosmetics:', JSON.stringify(cosmeticsCars.body().data, null, 2));
|
|
176
|
+
break;
|
|
177
|
+
case 'lego':
|
|
178
|
+
const cosmeticsLego = await fnApi.cosmetics.getAllLego(Enums.requestFlags.all());
|
|
179
|
+
console.log('Cosmetics:', JSON.stringify(cosmeticsLego.body().data, null, 2));
|
|
180
|
+
break;
|
|
181
|
+
case 'legokits':
|
|
182
|
+
const cosmeticsLegoKits = await fnApi.cosmetics.getAllLegoKits(Enums.requestFlags.all());
|
|
183
|
+
console.log('Cosmetics:', JSON.stringify(cosmeticsLegoKits.body().data, null, 2));
|
|
184
|
+
break;
|
|
185
|
+
case 'beans':
|
|
186
|
+
const cosmeticsBeans = await fnApi.cosmetics.getAllBeans(Enums.requestFlags.all());
|
|
187
|
+
console.log('Cosmetics:', JSON.stringify(cosmeticsBeans.body().data, null, 2));
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
} catch (error) {
|
|
191
|
+
console.error('Error:', error.message);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
console.log('Fortnite API CLI - Type "help" for commands');
|
|
197
|
+
rl.setPrompt('FN> ');
|
|
198
|
+
rl.prompt();
|
|
199
|
+
|
|
200
|
+
rl.on('line', async (line) => {
|
|
201
|
+
const [command, ...args] = line.trim().split(' ');
|
|
202
|
+
|
|
203
|
+
if (command === 'exit') {
|
|
204
|
+
rl.close();
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (commands[command]) {
|
|
209
|
+
await commands[command](args);
|
|
210
|
+
} else {
|
|
211
|
+
console.log('Unknown command. Type "help" for available commands');
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
rl.prompt();
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
rl.on('close', () => {
|
|
218
|
+
console.log('\nGoodbye!');
|
|
219
|
+
process.exit(0);
|
|
220
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const { Client } = require('fnbr');
|
|
2
|
+
const { ApiClient, Enums, SearchOptions } = require('fnapi-js');
|
|
3
|
+
const { SearchSource } = require('jest');
|
|
4
|
+
|
|
5
|
+
const client = new Client();
|
|
6
|
+
|
|
7
|
+
const fnApi = new ApiClient({});
|
|
8
|
+
|
|
9
|
+
const handleCommand = async (m) => {
|
|
10
|
+
// console.log(m.content);
|
|
11
|
+
if (!m.content.startsWith('!')) return;
|
|
12
|
+
const args = m.content.slice(1).split(' ');
|
|
13
|
+
const command = args.shift().toLowerCase();
|
|
14
|
+
|
|
15
|
+
if (command === 'outfit' || command === 'skin') {
|
|
16
|
+
const search = new SearchOptions()
|
|
17
|
+
.setName(`${args.join(' ')}`)
|
|
18
|
+
.setMatchMethod(Enums.matchMethod.contains())
|
|
19
|
+
.setType(Enums.cosmeticType.outfit());
|
|
20
|
+
|
|
21
|
+
const skin = await fnApi.cosmetics.search(search, Enums.requestFlags.paths(), false);
|
|
22
|
+
if (!skin) {
|
|
23
|
+
console.log(`The skin ${args.join(' ')} wasn't found!`);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
await m.client.party.me.setOutfit(skin.body().data.id, undefined, undefined);
|
|
28
|
+
await m.reply(`Set the skin to ${skin.body().data.name}!`);
|
|
29
|
+
|
|
30
|
+
} else if (command === 'emote' || command === 'dance') {
|
|
31
|
+
|
|
32
|
+
const search = new SearchOptions()
|
|
33
|
+
.setName(`${args.join(' ')}`)
|
|
34
|
+
.setMatchMethod(Enums.matchMethod.contains())
|
|
35
|
+
.setType(Enums.cosmeticType.emote());
|
|
36
|
+
|
|
37
|
+
const emote = await fnApi.cosmetics.search(search, Enums.requestFlags.paths(), false);
|
|
38
|
+
if (!emote) {
|
|
39
|
+
console.log(`The emote ${args.join(' ')} wasn't found!`);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
await m.client.party.me.setEmote(emote.body().data.id, fnApi.misc.fixPath(emote.body().data.path));
|
|
45
|
+
console.log(`Set the emote to ${emote.body().data.name}!`);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
console.log(error);
|
|
48
|
+
console.log(`Failed to set the emote due to: ${error.message}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
client.on('friend:message', (message) => {
|
|
54
|
+
console.log(`Message from ${message.author.displayName}: ${message.content}`);
|
|
55
|
+
|
|
56
|
+
handleCommand(message);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
client.on('ready', () => {
|
|
60
|
+
console.log(`Logged in as ${client.user.displayName}`);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
client.login();
|
package/src/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import ApiClient from './client/ApiClient.js';
|
|
2
2
|
import Response from './http/Response.js';
|
|
3
|
-
import RequestFlags from './enums/
|
|
3
|
+
import RequestFlags from './enums/RequestFlags.js';
|
|
4
4
|
import Enums from './utils/Enums.js';
|
|
5
5
|
import SearchOptions from './types/SearchOptions.js';
|
|
6
6
|
|
package/src/utils/Enums.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import CosmeticType from '../enums/CosmeticType.js';
|
|
2
2
|
import Language from '../enums/Language.js';
|
|
3
|
-
import RequestFlags from '../enums/
|
|
3
|
+
import RequestFlags from '../enums/RequestFlags.js';
|
|
4
4
|
import MatchMethod from '../enums/MatchMethod.js';
|
|
5
5
|
import AccountType from '../enums/AccountType.js';
|
|
6
6
|
import StatsImage from '../enums/StatsImage.js';
|