You've already forked tf2wikipricing
bump version to 0.4.0
Reviewed-on: http://charon.local/git/xen/tf2wikipricing/pulls/15
This commit is contained in:
@@ -49,7 +49,7 @@ describe('Price Service', () => {
|
|||||||
test('fetchPrice returns cached data if available and not expired', async () => {
|
test('fetchPrice returns cached data if available and not expired', async () => {
|
||||||
(getStorageValue as jest.Mock).mockResolvedValue(mockCachedData)
|
(getStorageValue as jest.Mock).mockResolvedValue(mockCachedData)
|
||||||
|
|
||||||
const result = await fetchPrice(mockToken, mockDefIndex, mockQuality)
|
const result = await fetchPrice(mockToken, mockDefIndex + ";" + mockQuality)
|
||||||
|
|
||||||
expect(getStorageValue).toHaveBeenCalledWith(expect.stringContaining(mockSku), null)
|
expect(getStorageValue).toHaveBeenCalledWith(expect.stringContaining(mockSku), null)
|
||||||
expect(result).toEqual(mockCachedData)
|
expect(result).toEqual(mockCachedData)
|
||||||
@@ -60,16 +60,16 @@ describe('Price Service', () => {
|
|||||||
(getStorageValue as jest.Mock).mockResolvedValue(expiredCache);
|
(getStorageValue as jest.Mock).mockResolvedValue(expiredCache);
|
||||||
(priceUsingPricesTF as jest.Mock).mockResolvedValue(mockPriceResponse)
|
(priceUsingPricesTF as jest.Mock).mockResolvedValue(mockPriceResponse)
|
||||||
|
|
||||||
const result = await fetchPrice(mockToken, mockDefIndex, mockQuality)
|
const result = await fetchPrice(mockToken, mockDefIndex + ";" + mockQuality)
|
||||||
|
|
||||||
expect(priceUsingPricesTF).toHaveBeenCalledWith(mockToken, mockDefIndex, mockQuality)
|
expect(priceUsingPricesTF).toHaveBeenCalledWith(mockToken, `${mockDefIndex};${mockQuality}`)
|
||||||
expect(setStorageValue).toHaveBeenCalled()
|
expect(setStorageValue).toHaveBeenCalled()
|
||||||
expect(result.metal).not.toBe(mockCachedData.metal)
|
expect(result.metal).not.toBe(mockCachedData.metal)
|
||||||
expect(result.metal).toBe(mockPriceResponse.metal)
|
expect(result.metal).toBe(mockPriceResponse.metal)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('fetchPrice rejects with 401 when no token provided', async () => {
|
test('fetchPrice rejects with 401 when no token provided', async () => {
|
||||||
await expect(fetchPrice('', mockDefIndex, mockQuality)).rejects.toBe(401)
|
await expect(fetchPrice('', mockDefIndex + ";" + mockQuality)).rejects.toBe(401)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('fetchPrice handles pricing API errors', async () => {
|
test('fetchPrice handles pricing API errors', async () => {
|
||||||
@@ -77,7 +77,7 @@ describe('Price Service', () => {
|
|||||||
(priceUsingPricesTF as jest.Mock).mockRejectedValue(testError);
|
(priceUsingPricesTF as jest.Mock).mockRejectedValue(testError);
|
||||||
(getStorageValue as jest.Mock).mockResolvedValue(null)
|
(getStorageValue as jest.Mock).mockResolvedValue(null)
|
||||||
|
|
||||||
await expect(fetchPrice(mockToken, mockDefIndex, mockQuality)).rejects.toBe(testError)
|
await expect(fetchPrice(mockToken, mockDefIndex + ";" + mockQuality)).rejects.toBe(testError)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('fetchKeyPrice uses correct parameters', async () => {
|
test('fetchKeyPrice uses correct parameters', async () => {
|
||||||
@@ -86,7 +86,7 @@ describe('Price Service', () => {
|
|||||||
|
|
||||||
const result = await fetchKeyPrice(mockToken)
|
const result = await fetchKeyPrice(mockToken)
|
||||||
|
|
||||||
expect(priceUsingPricesTF).toHaveBeenCalledWith(mockToken, defindex_key, 6)
|
expect(priceUsingPricesTF).toHaveBeenCalledWith(mockToken, `${defindex_key};6`)
|
||||||
expect(result.keys).toBe(0) // A key cannot cost a key :P
|
expect(result.keys).toBe(0) // A key cannot cost a key :P
|
||||||
expect(result.metal).toBe(mockKeyPriceResponse.metal)
|
expect(result.metal).toBe(mockKeyPriceResponse.metal)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,16 +1,57 @@
|
|||||||
import { describe, expect, test } from "bun:test";
|
import { describe, expect, test, mock } from "bun:test";
|
||||||
import { ItemSchema, getItemIndexByName, getTradableStatusByDefindex, getTradableStatusByName} from '../src/content/schemaService'
|
import { ItemSchema, ItemSlot, getItemIndexByName, getTradableStatusByDefindex, getTradableStatusByName, prepareSchema } from '../src/content/schemaService'
|
||||||
|
|
||||||
|
// Mock the storage and log functions
|
||||||
|
mock.module('../src/content/storage', () => ({
|
||||||
|
setStorageValue: mock(async (key: string, value: any) => {}),
|
||||||
|
getStorageValue: mock(async (key: string, defaultValue: any) => defaultValue)
|
||||||
|
}));
|
||||||
|
|
||||||
|
mock.module('../src/content/utils/log', () => ({
|
||||||
|
logDebug: mock(() => {}),
|
||||||
|
log: mock(() => {}),
|
||||||
|
logError: mock(() => {})
|
||||||
|
}));
|
||||||
|
|
||||||
const mockSchema: ItemSchema = {
|
const mockSchema: ItemSchema = {
|
||||||
'21': { name: 'Flame Thrower', tradable: false },
|
'21': {
|
||||||
'208': { name: 'Flame Thrower', tradable: true },
|
name: 'Flame Thrower',
|
||||||
'5021': { name: 'Mann Co. Supply Crate Key', tradable: true },
|
slot: ItemSlot.Primary,
|
||||||
'15141': { name: 'Flame Thrower', tradable: true },
|
tradable: false,
|
||||||
'69420': { name: 'Non-Tradable Item', tradable: false }
|
hasAustraliumVariant: false,
|
||||||
|
canKillstreakify: true
|
||||||
|
},
|
||||||
|
'208': {
|
||||||
|
name: 'Flame Thrower',
|
||||||
|
slot: ItemSlot.Primary,
|
||||||
|
tradable: true,
|
||||||
|
hasAustraliumVariant: true,
|
||||||
|
canKillstreakify: true
|
||||||
|
},
|
||||||
|
'5021': {
|
||||||
|
name: 'Mann Co. Supply Crate Key',
|
||||||
|
slot: ItemSlot.Tool,
|
||||||
|
tradable: true,
|
||||||
|
hasAustraliumVariant: false,
|
||||||
|
canKillstreakify: false
|
||||||
|
},
|
||||||
|
'15141': {
|
||||||
|
name: 'Flame Thrower',
|
||||||
|
slot: ItemSlot.Primary,
|
||||||
|
tradable: true,
|
||||||
|
hasAustraliumVariant: false,
|
||||||
|
canKillstreakify: true
|
||||||
|
},
|
||||||
|
'69420': {
|
||||||
|
name: 'Non-Tradable Item',
|
||||||
|
slot: ItemSlot.Misc,
|
||||||
|
tradable: false,
|
||||||
|
hasAustraliumVariant: false,
|
||||||
|
canKillstreakify: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('Schema Service', () => {
|
describe('Schema Service', () => {
|
||||||
|
|
||||||
test('getItemIndexByName returns correct defindex', () => {
|
test('getItemIndexByName returns correct defindex', () => {
|
||||||
expect(getItemIndexByName(mockSchema, 'Flame Thrower')).toBe(208)
|
expect(getItemIndexByName(mockSchema, 'Flame Thrower')).toBe(208)
|
||||||
expect(getItemIndexByName(mockSchema, 'Mann Co. Supply Crate Key')).toBe(5021)
|
expect(getItemIndexByName(mockSchema, 'Mann Co. Supply Crate Key')).toBe(5021)
|
||||||
@@ -30,4 +71,50 @@ describe('Schema Service', () => {
|
|||||||
expect(getTradableStatusByName(mockSchema, 'Non-Tradable Item')).toBe(false)
|
expect(getTradableStatusByName(mockSchema, 'Non-Tradable Item')).toBe(false)
|
||||||
expect(getTradableStatusByName(mockSchema, 'Non-Existent Item')).toBe(true)
|
expect(getTradableStatusByName(mockSchema, 'Non-Existent Item')).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('prepareSchema fetches and processes schema correctly', async () => {
|
||||||
|
// Mock GM_fetch response
|
||||||
|
const mockResponse = {
|
||||||
|
ok: true,
|
||||||
|
json: async () => [
|
||||||
|
{
|
||||||
|
defindex: 1,
|
||||||
|
item_name: 'Test Item',
|
||||||
|
item_slot: 'misc',
|
||||||
|
attributes: [
|
||||||
|
{ "name": "cannot trade", "class": "cannot_trade", "value": 1 }
|
||||||
|
],
|
||||||
|
capabilities: {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
defindex: 208,
|
||||||
|
item_name: 'Flame Thrower',
|
||||||
|
item_slot: 'primary',
|
||||||
|
capabilities: { can_killstreakify: true }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mock GM_fetch
|
||||||
|
globalThis.GM_fetch = mock(async () => mockResponse);
|
||||||
|
|
||||||
|
const result = await prepareSchema();
|
||||||
|
|
||||||
|
expect(result).toEqual({
|
||||||
|
'1': {
|
||||||
|
name: 'Test Item',
|
||||||
|
slot: ItemSlot.Misc,
|
||||||
|
tradable: false,
|
||||||
|
canKillstreakify: false,
|
||||||
|
hasAustraliumVariant: false
|
||||||
|
},
|
||||||
|
'208': {
|
||||||
|
name: 'Flame Thrower',
|
||||||
|
slot: ItemSlot.Primary,
|
||||||
|
tradable: true,
|
||||||
|
canKillstreakify: true,
|
||||||
|
hasAustraliumVariant: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
})
|
})
|
||||||
7
global.d.ts
vendored
Normal file
7
global.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export {};
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
GM_fetch: typeof fetch; // or a more specific custom type
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "tf2wikipricing",
|
"name": "tf2wikipricing",
|
||||||
"version": "0.3.1",
|
"version": "0.4.0",
|
||||||
"description": "Adds item pricing to the Team Fortress 2 wiki",
|
"description": "Adds item pricing to the Team Fortress 2 wiki",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@happy-dom/global-registrator": "^17.4.4",
|
"@happy-dom/global-registrator": "^17.4.4",
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ async function inject() {
|
|||||||
|
|
||||||
var data: ItemPriceData | null
|
var data: ItemPriceData | null
|
||||||
try {
|
try {
|
||||||
data = await fetchPrice(token, itemIndex, quality, currentTime);
|
data = await fetchPrice(token, itemIndex + ";" + quality, currentTime);
|
||||||
updateTime = new Date(data.update)
|
updateTime = new Date(data.update)
|
||||||
} catch {
|
} catch {
|
||||||
log(`${qualifiedName} is unpriced or unavailable, skipping...`)
|
log(`${qualifiedName} is unpriced or unavailable, skipping...`)
|
||||||
@@ -217,6 +217,27 @@ async function inject() {
|
|||||||
|
|
||||||
priceRows.push({quality: quality, row: priceRow})
|
priceRows.push({quality: quality, row: priceRow})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Check item schema for Australium variant of current defindex
|
||||||
|
if(itemSchema[itemIndex].hasAustraliumVariant) {
|
||||||
|
promises.push(new Promise(async (resolve) => {
|
||||||
|
logDebug(`Fetching price for Australium ${itemName}`)
|
||||||
|
var data: ItemPriceData | null
|
||||||
|
try {
|
||||||
|
data = await fetchPrice(token, `${itemIndex};11;australium`, currentTime);
|
||||||
|
updateTime = new Date(data.update)
|
||||||
|
} catch {
|
||||||
|
log(`Australium ${itemName} is unpriced or unavailable, skipping...`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const priceRow = createPriceRow($T("Australium"), data, keyPrice, locale, "https://wiki.teamfortress.com/wiki/Australium_weapons")
|
||||||
|
|
||||||
|
priceRows.push({quality: 99, row: priceRow})
|
||||||
|
resolve()
|
||||||
|
return
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
Promise.all(promises).then(() => {
|
Promise.all(promises).then(() => {
|
||||||
priceRows.sort((a, b) => {
|
priceRows.sort((a, b) => {
|
||||||
// Sort 6 first always, then numerically
|
// Sort 6 first always, then numerically
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export class ItemPriceData {
|
|||||||
|
|
||||||
|
|
||||||
export async function fetchKeyPrice(token: string) {
|
export async function fetchKeyPrice(token: string) {
|
||||||
return fetchPrice(token, defindex_key, 6, new Date(), 86400000)
|
return fetchPrice(token, `${defindex_key};6`, new Date(), 86400000)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,9 +39,8 @@ export async function fetchKeyPrice(token: string) {
|
|||||||
* @param update Date retrieved.
|
* @param update Date retrieved.
|
||||||
* @param ttl Time to cache results in milliseconds. 30 minutes by default.
|
* @param ttl Time to cache results in milliseconds. 30 minutes by default.
|
||||||
*/
|
*/
|
||||||
export async function fetchPrice(token: string, defIndex: number, quality: number, update: Date = new Date(), ttl: number = 30 * 60 * 1000): Promise<ItemPriceData> {
|
export async function fetchPrice(token: string, sku: string, update: Date = new Date(), ttl: number = 30 * 60 * 1000): Promise<ItemPriceData> {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
const sku = defIndex.toString() + ";" + quality.toString();
|
|
||||||
var data: ItemPriceData | null
|
var data: ItemPriceData | null
|
||||||
|
|
||||||
const cached = await getStorageValue(storage_priceprefix + sku, null)
|
const cached = await getStorageValue(storage_priceprefix + sku, null)
|
||||||
@@ -60,7 +59,7 @@ export async function fetchPrice(token: string, defIndex: number, quality: numbe
|
|||||||
data.ttl = ttl
|
data.ttl = ttl
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await priceUsingPricesTF(token, defIndex, quality)
|
const response = await priceUsingPricesTF(token, sku)
|
||||||
if (response) {
|
if (response) {
|
||||||
data.keys = response.keys
|
data.keys = response.keys
|
||||||
data.metal = response.metal
|
data.metal = response.metal
|
||||||
|
|||||||
@@ -31,13 +31,13 @@ class PricesResponse {
|
|||||||
* and uses it to fetch the latest pricing data for the given item in keys and metal.
|
* and uses it to fetch the latest pricing data for the given item in keys and metal.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* const price = await priceUsingPricesTF(token, 105, 11);
|
* const price = await priceUsingPricesTF(token, '105;11');
|
||||||
* console.log("Strange Brigade Helm price: ${price.keys} keys ${price.metal} metal")
|
* console.log("Strange Brigade Helm price: ${price.keys} keys ${price.metal} metal")
|
||||||
*
|
*
|
||||||
* @returns {Promise<PricesResponse>} Object containing 'keys' and 'metal' prices
|
* @returns {Promise<PricesResponse>} Object containing 'keys' and 'metal' prices
|
||||||
* @throws When authentication fails or API returns non-200 status code
|
* @throws When authentication fails or API returns non-200 status code
|
||||||
*/
|
*/
|
||||||
async function priceUsingPricesTF(token: string, defIndex: number, quality: number): Promise<PricesResponse> {
|
async function priceUsingPricesTF(token: string, sku: string): Promise<PricesResponse> {
|
||||||
// prices.tf
|
// prices.tf
|
||||||
// https://api2.prices.tf/prices/${sku}
|
// https://api2.prices.tf/prices/${sku}
|
||||||
// Authorization: Bearer ${token}
|
// Authorization: Bearer ${token}
|
||||||
@@ -45,7 +45,6 @@ async function priceUsingPricesTF(token: string, defIndex: number, quality: numb
|
|||||||
if (!token) {
|
if (!token) {
|
||||||
reject(401)
|
reject(401)
|
||||||
}
|
}
|
||||||
const sku = defIndex + ";" + quality;
|
|
||||||
var response = await GM_fetch(`https://api2.prices.tf/prices/${encodeURIComponent(sku)}`, {
|
var response = await GM_fetch(`https://api2.prices.tf/prices/${encodeURIComponent(sku)}`, {
|
||||||
method: 'get',
|
method: 'get',
|
||||||
headers: new Headers({
|
headers: new Headers({
|
||||||
@@ -53,15 +52,18 @@ async function priceUsingPricesTF(token: string, defIndex: number, quality: numb
|
|||||||
'Authorization': `Bearer ${token}`
|
'Authorization': `Bearer ${token}`
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
if (response.status === 404 && quality === 6) {
|
if (response.status === 404 && sku.includes(';')) {
|
||||||
// Try uncraftable variant
|
const quality: number = parseInt(sku.split(';')[1], 10);
|
||||||
response = await GM_fetch(`https://api2.prices.tf/prices/${encodeURIComponent(sku + ';uncraftable')}`, {
|
if(quality === 6) {
|
||||||
method: 'get',
|
// Try uncraftable variant if unique weapon
|
||||||
headers: new Headers({
|
response = await GM_fetch(`https://api2.prices.tf/prices/${encodeURIComponent(sku + ';uncraftable')}`, {
|
||||||
'Accept': 'application/json',
|
method: 'get',
|
||||||
'Authorization': `Bearer ${token}`
|
headers: new Headers({
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
const json = await response.json()
|
const json = await response.json()
|
||||||
|
|||||||
@@ -4,8 +4,13 @@ import './config'
|
|||||||
declare function GM_fetch(input: string | URL | globalThis.Request, init?: RequestInit): Promise<Response>
|
declare function GM_fetch(input: string | URL | globalThis.Request, init?: RequestInit): Promise<Response>
|
||||||
import './GM_fetch'
|
import './GM_fetch'
|
||||||
import { storage_version, storage_schema, storage_lastUpdateTime } from './config'
|
import { storage_version, storage_schema, storage_lastUpdateTime } from './config'
|
||||||
|
import Australiums from '../resources/australiums.json'
|
||||||
const semver = require('semver')
|
const semver = require('semver')
|
||||||
|
|
||||||
|
export function checkAustraliumVariant(defindex: number): boolean {
|
||||||
|
return Object.prototype.hasOwnProperty.call(Australiums, defindex.toString());
|
||||||
|
}
|
||||||
|
|
||||||
export declare const __VERSION__: string;
|
export declare const __VERSION__: string;
|
||||||
|
|
||||||
function isDateAfterOneDay(date1: Date, date2: Date): boolean {
|
function isDateAfterOneDay(date1: Date, date2: Date): boolean {
|
||||||
@@ -14,7 +19,28 @@ function isDateAfterOneDay(date1: Date, date2: Date): boolean {
|
|||||||
return diffDays > 1;
|
return diffDays > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ItemSchema { [key: string]: {name: string, tradable: Boolean}; }
|
export enum ItemSlot {
|
||||||
|
Primary = "primary",
|
||||||
|
Secondary = "secondary",
|
||||||
|
Melee = "melee",
|
||||||
|
PDA = "pda",
|
||||||
|
PDA2 = "pda2",
|
||||||
|
Building = "building",
|
||||||
|
Misc = "misc",
|
||||||
|
Special = "special",
|
||||||
|
Taunt = "taunt",
|
||||||
|
Tool = "tool",
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ItemSchema {
|
||||||
|
[key: string]: {
|
||||||
|
name: string,
|
||||||
|
slot: ItemSlot,
|
||||||
|
tradable: Boolean,
|
||||||
|
hasAustraliumVariant: Boolean,
|
||||||
|
canKillstreakify: Boolean
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function getItemIndexByName(schema: ItemSchema, name: string, excludeStock: Boolean = true, excludeDecorated: Boolean = true) {
|
export function getItemIndexByName(schema: ItemSchema, name: string, excludeStock: Boolean = true, excludeDecorated: Boolean = true) {
|
||||||
for (const [defindex, value] of Object.entries(schema)) {
|
for (const [defindex, value] of Object.entries(schema)) {
|
||||||
@@ -63,6 +89,7 @@ export async function prepareSchema(): Promise<ItemSchema> {
|
|||||||
log(`Cache is from a previous version (${storedVersion}) of the extension. Updating for version ${__VERSION__}`);
|
log(`Cache is from a previous version (${storedVersion}) of the extension. Updating for version ${__VERSION__}`);
|
||||||
needsUpdate = true
|
needsUpdate = true
|
||||||
} else {
|
} else {
|
||||||
|
log(`Cache is from current version (${storedVersion}) of the extension.`);
|
||||||
itemSchema = await getStorageValue(storage_schema, null);
|
itemSchema = await getStorageValue(storage_schema, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,8 +114,8 @@ export async function prepareSchema(): Promise<ItemSchema> {
|
|||||||
var responseItems: any[] = await response.json()
|
var responseItems: any[] = await response.json()
|
||||||
// We want to keep the keys `defindex`, `item_name`, and `attributes`
|
// We want to keep the keys `defindex`, `item_name`, and `attributes`
|
||||||
responseItems.forEach((item: any) => {
|
responseItems.forEach((item: any) => {
|
||||||
const defindex = item['defindex']
|
const defindex: number = item['defindex']
|
||||||
const name = item['item_name']
|
|
||||||
var tradable: Boolean = true
|
var tradable: Boolean = true
|
||||||
try {
|
try {
|
||||||
if(item['attributes'] != null) {
|
if(item['attributes'] != null) {
|
||||||
@@ -100,7 +127,26 @@ export async function prepareSchema(): Promise<ItemSchema> {
|
|||||||
logError(error)
|
logError(error)
|
||||||
log(item)
|
log(item)
|
||||||
}
|
}
|
||||||
(cacheItems as any)[defindex.toString()] = { "name": name, "tradable": tradable }
|
|
||||||
|
var canKillstreakify: Boolean = false
|
||||||
|
try {
|
||||||
|
if(item['capabilities'] != null) {
|
||||||
|
if(item['capabilities']['can_killstreakify'] != null && item['capabilities']['can_killstreakify'] == true) {
|
||||||
|
canKillstreakify = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(error) {
|
||||||
|
logError(error)
|
||||||
|
log(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
(cacheItems as any)[defindex.toString()] = {
|
||||||
|
"name": item['item_name'],
|
||||||
|
"slot": item['item_slot'],
|
||||||
|
"tradable": tradable,
|
||||||
|
"canKillstreakify": canKillstreakify,
|
||||||
|
"hasAustraliumVariant": checkAustraliumVariant(defindex)
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await setStorageValue(storage_schema, (cacheItems));
|
await setStorageValue(storage_schema, (cacheItems));
|
||||||
|
|||||||
@@ -2,13 +2,16 @@ import { ItemPriceData } from "./priceService";
|
|||||||
import { formatPrice } from "./utils/formatting";
|
import { formatPrice } from "./utils/formatting";
|
||||||
import { $T } from "./utils/localization";
|
import { $T } from "./utils/localization";
|
||||||
|
|
||||||
export function createPriceRow(qualityName: string, data: ItemPriceData, keyPrice: ItemPriceData, locale: string): HTMLTableRowElement {
|
export function createPriceRow(qualityName: string, data: ItemPriceData, keyPrice: ItemPriceData, locale: string, wikiPage: string = null): HTMLTableRowElement {
|
||||||
const priceRow = document.createElement("tr");
|
const priceRow = document.createElement("tr");
|
||||||
|
|
||||||
const priceLabel = document.createElement("td");
|
const priceLabel = document.createElement("td");
|
||||||
priceLabel.className = "infobox-label";
|
priceLabel.className = "infobox-label";
|
||||||
const priceLabelLink = document.createElement("a");
|
const priceLabelLink = document.createElement("a");
|
||||||
priceLabelLink.href = locale === 'en' ? `https://wiki.teamfortress.com/wiki/${qualityName}` : `https://wiki.teamfortress.com/wiki/${qualityName}/${locale}`
|
if (wikiPage == null) {
|
||||||
|
wikiPage = `https://wiki.teamfortress.com/wiki/${qualityName}`
|
||||||
|
}
|
||||||
|
priceLabelLink.href = locale === 'en' ? wikiPage : `${wikiPage}/${locale}`
|
||||||
priceLabelLink.innerText = $T(qualityName)
|
priceLabelLink.innerText = $T(qualityName)
|
||||||
priceLabel.appendChild(priceLabelLink);
|
priceLabel.appendChild(priceLabelLink);
|
||||||
priceLabel.innerHTML += ':'
|
priceLabel.innerHTML += ':'
|
||||||
|
|||||||
21
src/resources/australiums.json
Normal file
21
src/resources/australiums.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"36": "Blutsauger",
|
||||||
|
"38": "Axtinguisher",
|
||||||
|
"45": "Force-A-Nature",
|
||||||
|
"61": "Ambassador",
|
||||||
|
"132": "Eyelander",
|
||||||
|
"141": "Frontier Justice",
|
||||||
|
"194": "Knife",
|
||||||
|
"197": "Wrench",
|
||||||
|
"200": "Scattergun",
|
||||||
|
"201": "Sniper Rifle",
|
||||||
|
"202": "Minigun",
|
||||||
|
"203": "SMG",
|
||||||
|
"205": "Rocket Launcher",
|
||||||
|
"206": "Grenade Launcher",
|
||||||
|
"207": "Stickybomb Launcher",
|
||||||
|
"208": "Flame Thrower",
|
||||||
|
"211": "Medi Gun",
|
||||||
|
"228": "Black Box",
|
||||||
|
"424": "Tomislav"
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"include": ["src/**/*", "declarations.d.ts", "global.d.ts"],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "./dist/",
|
"outDir": "./dist/",
|
||||||
"noImplicitAny": true,
|
"noImplicitAny": true,
|
||||||
|
|||||||
Reference in New Issue
Block a user