Skip to content

Commit

Permalink
Merge pull request #3 from TurtIeSocks/jsdocs
Browse files Browse the repository at this point in the history
chore: add jsdocs to public APIs
  • Loading branch information
TurtIeSocks authored Apr 21, 2024
2 parents 058275f + c7e7de4 commit 38559ca
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 31 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const pokestop = uicons.pokestop(
quest_active,
ar
)
// Please note that in some cases, such as with Stardust, the `reward_id` is the `amount` of the reward
const reward = uicons.reward(reward_type_id, reward_id, amount)
const invasion = uicons.invasion(grunt_id, confirmed)
const gym = uicons.gym(team_id, trainer_count, in_battle, ex, ar)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "uicons.js",
"version": "1.1.2",
"version": "1.1.3",
"description": "UICONS JavaScript Library",
"repository": "https://github.com/TurtIeSocks/uicons.js",
"author": "TurtIeSocks <[email protected]>",
Expand Down
100 changes: 95 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ export class UICONS<Index extends UiconsIndex = UiconsIndex> {
#type: Set<Index['type'][number]>
#weather: Set<Index['weather'][number]>

/**
* @param path The base URL of the UICONS repository
* @param label Optional label for debugging purposes
*/
constructor(path: string, label?: string) {
this.#path = path.endsWith('/') ? path.slice(0, -1) : path
this.#label = label || this.#path
Expand Down Expand Up @@ -77,6 +81,10 @@ export class UICONS<Index extends UiconsIndex = UiconsIndex> {
this.#weather = new Set()
}

/**
* This is used to initialize the UICONS class asynchronously by automatically fetching the index.json file
* from the remote UICONS repository provided in the constructor
*/
async remoteInit(): Promise<void> {
const data = await fetch(`${this.#path}/index.json`)
if (!data.ok) {
Expand All @@ -88,6 +96,10 @@ export class UICONS<Index extends UiconsIndex = UiconsIndex> {
this.init(indexFile)
}

/**
* This is used to initialize the UICONS class if you have already fetched the index.json file and want init the class synchronously
* @param data The index.json file from the UICONS repository
*/
init(data: UiconsIndex) {
this.#device = new Set(data.device || [])
this.#gym = new Set(data.gym || [])
Expand All @@ -113,6 +125,11 @@ export class UICONS<Index extends UiconsIndex = UiconsIndex> {
this.#extensionMap = buildExtensions(data)
}

/**
* Check to see if an icon path exists in the UICONS repository
* @param location This is the dot notation path of the folders in the UICONS repository
* @param fileName The filename without the extension
*/
has(location: Paths<Index>, fileName: string): boolean {
if (!this.#extensionMap) throw new Error('UICONS not initialized')
const [first, second] = location.split('.', 2)
Expand All @@ -135,9 +152,9 @@ export class UICONS<Index extends UiconsIndex = UiconsIndex> {
return this.#raid.egg.has(`${fileName}.${this.#extensionMap.raid.egg}`)
case 'reward':
return second in this.#reward
? this.#reward[second]?.has(
? !!this.#reward[second]?.has(
`${fileName}.${this.#extensionMap.reward[second]}`
) ?? false
)
: false
case 'spawnpoint':
return this.#spawnpoint.has(
Expand All @@ -154,13 +171,25 @@ export class UICONS<Index extends UiconsIndex = UiconsIndex> {
}
}

/**
* @param online a boolean to determine if the device is online or offline
* @returns the src of the device icon
*/
device(online = false): string {
if (!this.#extensionMap) throw new Error('UICONS not initialized')
return online && this.#device.has(`1.${this.#extensionMap.device}`)
? `${this.#path}/device/1.${this.#extensionMap.device}`
: `${this.#path}/device/0.${this.#extensionMap.device}`
}

/**
* @param teamId the team id of the gym, see Rpc.Team
* @param trainerCount the number of trainers in the gym
* @param inBattle is the gym is in battle
* @param ex is the gym an EX raid gym
* @param ar is the gym AR eligible
* @returns the src of the gym icon
*/
gym(
teamId: string | number = 0,
trainerCount: string | number = 0,
Expand Down Expand Up @@ -192,6 +221,11 @@ export class UICONS<Index extends UiconsIndex = UiconsIndex> {
return `${baseUrl}/0.${this.#extensionMap.gym}`
}

/**
* @param gruntId the grunt id of the invasion, see Rpc.EnumWrapper.InvasionCharacter
* @param confirmed if the invasion is confirmed - used for giovanni/decoy images
* @returns the src of the invasion icon
*/
invasion(gruntId: string | number = 0, confirmed = false): string {
if (!this.#extensionMap) throw new Error('UICONS not initialized')
const baseUrl = `${this.#path}/invasion`
Expand All @@ -208,7 +242,10 @@ export class UICONS<Index extends UiconsIndex = UiconsIndex> {
return `${baseUrl}/0.${this.#extensionMap.invasion}`
}

/** Argument should be the filename without the extension */
/**
* @param fileName the filename without the extension
* @returns the src of the misc icon
*/
misc(fileName: string): string {
if (!this.#extensionMap) throw new Error('UICONS not initialized')
const baseUrl = `${this.#path}/misc`
Expand All @@ -219,6 +256,10 @@ export class UICONS<Index extends UiconsIndex = UiconsIndex> {
return `${baseUrl}/0.${this.#extensionMap.misc}`
}

/**
* @param typeId the pokemon type ID that is nesting, see Rpc.HoloPokemonType
* @returns the src of the nest icon
*/
nest(typeId: string | number = 0): string {
if (!this.#extensionMap) throw new Error('UICONS not initialized')
const baseUrl = `${this.#path}/nest`
Expand All @@ -230,6 +271,16 @@ export class UICONS<Index extends UiconsIndex = UiconsIndex> {
return `${baseUrl}/0.${this.#extensionMap.nest}`
}

/**
* @param pokemonId the pokemon ID
* @param form the form ID of the pokemon, see Rpc.PokemonDisplayProto.Form
* @param evolution the [mega] evolution ID of the pokemon, see Rpc.HoloTemporaryEvolutionId
* @param gender the gender ID of the pokemon, see Rpc.BelugaPokemonProto.PokemonGender
* @param costume the costume ID of the pokemon, see Rpc.PokemonDisplayProto.Costume
* @param alignment the alignment ID of the pokemon, such as shadow or purified, see Rpc.PokemonDisplayProto.Alignment
* @param shiny if the pokemon is shiny
* @returns the src of the pokemon icon
*/
pokemon(
pokemonId: string | number = 0,
form: string | number = 0,
Expand Down Expand Up @@ -272,6 +323,15 @@ export class UICONS<Index extends UiconsIndex = UiconsIndex> {
return `${baseUrl}/0.${this.#extensionMap.pokemon}`
}

/**
* @param lureId the ID of the lure at the pokestop, 0 for no lure, see TROY_DISK values in Rpc.Item
* @param power the power up level of the pokestop, 0 for no power up, see Rpc.FortPowerUpLevel
* @param display the display ID of the pokestop, 0 for no display, see Rpc.IncidentDisplayType
* @param invasionActive does the pokestop currently have an invasion
* @param questActive does the pokestop currently have an active quest
* @param ar is the pokestop AR eligible
* @returns
*/
pokestop(
lureId: string | number = 0,
power: string | number = 0,
Expand Down Expand Up @@ -306,6 +366,12 @@ export class UICONS<Index extends UiconsIndex = UiconsIndex> {
return `${baseUrl}/0.${this.#extensionMap.pokestop}`
}

/**
* @param level the level of the raid egg, see Rpc.RaidLevel
* @param hatched if the raid egg has hatched
* @param ex if the raid egg is an EX raid egg
* @returns the src of the raid egg icon
*/
raidEgg(level: string | number = 0, hatched = false, ex = false): string {
if (!this.#extensionMap) throw new Error('UICONS not initialized')
const baseUrl = `${this.#path}/raid/egg`
Expand All @@ -325,10 +391,16 @@ export class UICONS<Index extends UiconsIndex = UiconsIndex> {
return `${baseUrl}/0.${this.#extensionMap.raid.egg}`
}

/**
* @param questRewardType the type of quest reward, see Rpc.QuestRewardProto.Type
* @param rewardIdOrAmount the ID or the amount of the reward. This depends on the complexity of the reward type. For example, item rewards use the item ID, while stardust rewards use the amount of stardust. Best to check uicons repository to see which of them use the `_a` flag
* @param amount the amount of the reward
* @returns the src of the quest reward icon
*/
reward<U extends RewardTypeKeys>(
// @ts-ignore // TODO: WHY TS
questRewardType: U = 'unset',
rewardId: string | number = 0,
rewardIdOrAmount: string | number = 0,
amount: string | number = 0
): string {
if (!this.#extensionMap) throw new Error('UICONS not initialized')
Expand All @@ -340,8 +412,9 @@ export class UICONS<Index extends UiconsIndex = UiconsIndex> {
Number.isInteger(amountSafe) && amountSafe > 1
? [`_a${amount}`, '']
: ['']
const safeId = +rewardIdOrAmount || amountSafe || 0
for (let a = 0; a < amountSuffixes.length; a += 1) {
const result = `${rewardId}${amountSuffixes[a]}.${
const result = `${safeId}${amountSuffixes[a]}.${
this.#extensionMap.reward[questRewardType]
}`
if (this.#reward[questRewardType].has(result)) {
Expand All @@ -357,13 +430,21 @@ export class UICONS<Index extends UiconsIndex = UiconsIndex> {
return `${baseUrl}/0.${this.#extensionMap.reward[questRewardType]}`
}

/**
* @param hasTth if the spawnpoint has a confirmed timer or not
* @returns the src of the spawnpoint icon
*/
spawnpoint(hasTth = false): string {
if (!this.#extensionMap) throw new Error('UICONS not initialized')
return hasTth && this.#spawnpoint.has(`1.${this.#extensionMap.spawnpoint}`)
? `${this.#path}/spawnpoint/1.${this.#extensionMap.spawnpoint}`
: `${this.#path}/spawnpoint/0.${this.#extensionMap.spawnpoint}`
}

/**
* @param teamId the team ID, see Rpc.Team
* @returns the src of the team icon
*/
team(teamId: string | number = 0): string {
if (!this.#extensionMap) throw new Error('UICONS not initialized')
const baseUrl = `${this.#path}/team`
Expand All @@ -375,6 +456,10 @@ export class UICONS<Index extends UiconsIndex = UiconsIndex> {
return `${baseUrl}/0.${this.#extensionMap.team}`
}

/**
* @param typeId the pokemon type ID, see Rpc.HoloPokemonType
* @returns the src of the pokemon type icon
*/
type(typeId: string | number = 0): string {
if (!this.#extensionMap) throw new Error('UICONS not initialized')
const baseUrl = `${this.#path}/type`
Expand All @@ -386,6 +471,11 @@ export class UICONS<Index extends UiconsIndex = UiconsIndex> {
return `${baseUrl}/0.${this.#extensionMap.type}`
}

/**
* @param weatherId the weather ID, see Rpc.GameplayWeatherProto.WeatherCondition
* @param timeOfDay the time of day, either 'day' or 'night'
* @returns the src of the weather icon
*/
weather(
weatherId: string | number = 0,
timeOfDay: TimeOfDay = 'day'
Expand Down
25 changes: 0 additions & 25 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,31 +28,6 @@ export type ExtensionMap<T = UiconsIndex> = {
: ExtensionMap<T[K]>
}

type DeepKeys<T, P extends string = ''> = {
[K in keyof T]-?: K extends string
? P extends ''
? `${K}` | `${K}.${DeepKeys<T[K], K>}`
: `${P}.${K}.${DeepKeys<T[K], P & K>}`
: never
}[keyof T]

type ConfigPaths<T extends object> = DeepKeys<T>

type PathValue<T, P> = P extends `${infer K}.${infer Rest}`
? K extends keyof T
? Rest extends DeepKeys<T[K]>
? PathValue<T[K], Rest>
: never
: never
: P extends keyof T
? T[P]
: never

type ConfigPathValue<T extends object, P extends ConfigPaths<T>> = PathValue<
T,
P
>

type Join<K, P> = K extends string | number
? P extends string | number
? `${K}${'' extends P ? '' : '.'}${P}`
Expand Down

0 comments on commit 38559ca

Please sign in to comment.