@juice789/tf2items 1.0.38 → 2.0.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/api.js CHANGED
@@ -1,11 +1,10 @@
1
- const axios = require('axios').default
2
- const { compose, __, map, applyTo, prop } = require('ramda')
1
+ import axios from 'axios'
3
2
 
4
3
  const myAxios = axios.create()
5
4
 
6
- myAxios.interceptors.response.use(prop('data'), Promise.reject.bind(Promise))
5
+ myAxios.interceptors.response.use(res => res.data, Promise.reject.bind(Promise))
7
6
 
8
- const api = {}
7
+ export const api = {}
9
8
 
10
9
  api.getSchemaItems = ({ steamApiKey: key }) => (start) => myAxios({
11
10
  method: 'get',
@@ -54,9 +53,4 @@ api.getAssetClassInfo = ({ steamApiKey }) => (ids, appId = 440) => myAxios({
54
53
  url: `https://api.steampowered.com/ISteamEconomy/GetAssetClassInfo/v1/?key=${steamApiKey}&appid=${appId}&language=EN&class_count=${ids.length}${ids.join('')}`
55
54
  })
56
55
 
57
- const createApi = compose(map(__, api), applyTo)
58
-
59
- module.exports = {
60
- createApi,
61
- api
62
- }
56
+ export const createApi = (options) => Object.fromEntries(Object.entries(api).map(([k, fn]) => [k, fn(options)]))
package/app.js CHANGED
@@ -1,57 +1,43 @@
1
- const { runSaga } = require('redux-saga')
2
- const { map } = require('ramda')
1
+ import { runSaga } from 'redux-saga'
2
+ import helperObjects from './schemaHelper.json' with { type: 'json' }
3
+ import { createApi } from './api.js'
4
+ import * as sagas from './sagas.js'
5
+ import { saveSchema } from './saveSchema.js'
3
6
 
4
- const helperObjects = require('./schemaHelper.json')
5
- const sagaHelpers = require('./sagaHelpers')
7
+ export * from './schemaItems.js'
8
+ export * from './sku.js'
9
+ export * from './skuBp.js'
10
+ export * from './sagas.js'
11
+ export * from './sagaHelpers.js'
12
+ export * from './skuLinks.js'
13
+ export { saveSchema } from './saveSchema.js'
14
+ export { fromEconItem, fromEconItemOptions } from './fromEconItem.js'
15
+ export { fromListingV1 } from './fromListingV1.js'
16
+ export { fromListingV2 } from './fromListingV2.js'
17
+ export { blanketify } from './blanket.js'
18
+ export { createApi, api } from './api.js'
6
19
 
7
- const items = require('./schemaItems.js')
8
- const sku = require('./sku.js')
9
- const skuBp = require('./skuBp.js')
10
- const skuLinks = require('./skuLinks.js')
20
+ export const {
21
+ qualityNames, qualityIds, rarities, killstreakTiers, wears, classes, itemSlots, itemClasses,
22
+ paintHex, paintDefindex, spellDefindex, cosmeticCollections, weaponCollections, warPaintCollections,
23
+ fabricatorDefindex, strangifierTargets, australiumDefindex, crateSeries, paintableDefindex,
24
+ chemsetDefindex, serieslessDefindex, impossibleEffects
25
+ } = helperObjects
11
26
 
12
- const { createApi, api } = require('./api.js')
13
-
14
- const sagas = require('./sagas.js')
15
- const { saveSchema } = require('./saveSchema.js')
16
-
17
- const { fromEconItem, fromEconItemOptions } = require('./fromEconItem.js')
18
- const { fromListingV1 } = require('./fromListingV1.js')
19
- const { fromListingV2 } = require('./fromListingV2.js')
20
- const { blanketify } = require('./blanket.js')
21
- const { toSearchParams } = require('./toSearchParams.js')
22
-
23
- const getInstance = (options) => {
27
+ export const getInstance = (options) => {
24
28
  const api = createApi(options)
25
29
  const fns = { ...sagas, saveSchema }
26
30
  return options.saga
27
31
  ? fns
28
- : map(
29
- (saga) => (...args) => new Promise((resolve, reject) => {
30
- runSaga({
31
- context: { api }
32
- }, saga, ...args)
33
- .toPromise()
34
- .then(resolve, reject)
35
- }), fns
32
+ : Object.fromEntries(
33
+ Object
34
+ .entries(fns)
35
+ .map(([k, saga]) => [k, (...args) => new Promise((resolve, reject) => {
36
+ runSaga({
37
+ context: { api }
38
+ }, saga, ...args)
39
+ .toPromise()
40
+ .then(resolve, reject)
41
+ })])
36
42
  )
37
43
  }
38
-
39
- module.exports = {
40
- ...helperObjects,
41
- ...items,
42
- ...sku,
43
- ...skuBp,
44
- ...sagas,
45
- ...sagaHelpers,
46
- ...skuLinks,
47
- saveSchema,
48
- getInstance,
49
- createApi,
50
- api,
51
- fromEconItem,
52
- fromEconItemOptions,
53
- fromListingV1,
54
- fromListingV2,
55
- blanketify,
56
- toSearchParams
57
- }
package/blanket.js CHANGED
@@ -1,122 +1,47 @@
1
- const {
2
- defaultTo,
3
- nth,
4
- compose,
5
- length,
6
- prop,
7
- map,
8
- uncurryN,
9
- values,
10
- when,
11
- includes,
12
- __,
13
- propEq,
14
- identity,
15
- filter,
16
- assoc,
17
- chain,
18
- omit,
19
- pickBy,
20
- has,
21
- complement,
22
- allPass,
23
- converge,
24
- concat,
25
- unnest,
26
- pick,
27
- mergeRight,
28
- renameKeys
29
- } = require('ramda')
30
-
31
- const { safeItems: items } = require('./schemaItems.js')
32
- const { skuFromItem, itemFromSku } = require('./sku.js')
1
+ import { safeItems as items } from './schemaItems.js'
2
+ import { skuFromItem, itemFromSku } from './sku.js'
33
3
 
34
4
  const choose = (n, xs) =>
35
5
  n < 1 || n > xs.length
36
6
  ? []
37
- : n == 1
38
- ? [...xs.map(x => [x])]
7
+ : n === 1
8
+ ? xs.map(x => [x])
39
9
  : [
40
10
  ...choose(n - 1, xs.slice(1)).map(ys => [xs[0], ...ys]),
41
11
  ...choose(n, xs.slice(1))
42
12
  ]
43
13
 
44
- const getCombos = uncurryN(3, (min, max, xs) =>
45
- xs.length == 0 || min > max
46
- ? []
47
- : [...choose(min, xs), ...getCombos(min + 1, max, xs)]
48
- )
14
+ function getCombos(min, max, xs) {
15
+ if (xs.length === 0 || min > max) return []
16
+ return [...choose(min, xs), ...getCombos(min + 1, max, xs)]
17
+ }
49
18
 
50
- const unboxSkinsRemap = when(
51
- allPass([
52
- complement(has)('texture'),//no texture
53
- compose(//is an unbox skin
54
- allPass([
55
- has('texture'),
56
- complement(propEq)('War Paint', 'item_name')
57
- ]),
58
- prop(__, items),
59
- prop('defindex')
60
- )
61
- ]),
62
- converge(
63
- concat,
64
- [
65
- Array.of,
66
- compose(
67
- Array.of,
68
- chain(assoc('defindex'), compose(
69
- prop('defindex'),//change defindex from unbox skin defindex to weapon defindex
70
- defaultTo({}),
71
- nth(0),
72
- values,
73
- ({ item_name }) => pickBy(allPass([
74
- propEq(6, 'item_quality'),
75
- propEq(item_name, 'item_name')
76
- ]), items),
77
- prop(__, items),
78
- prop('defindex')
79
- ))
80
- )
81
- ]
82
- )
83
- )
19
+ const warPaintRemap = item =>
20
+ !('texture' in item) && items[item.defindex]?.item_name === 'War Paint'
21
+ ? { ...item, defindex: '9536' }
22
+ : item
84
23
 
85
- const warPaintRemap = when(
86
- allPass([
87
- complement(has)('texture'),
88
- compose(
89
- propEq('War Paint', 'item_name'),
90
- prop(__, items),
91
- prop('defindex')
92
- ),
93
- ]),
94
- assoc('defindex', '9536')
95
- )
24
+ function unboxSkinsRemap(item) {
25
+ const schemaItem = items[item.defindex]
26
+ if ('texture' in item || !schemaItem || !('texture' in schemaItem) || schemaItem.item_name === 'War Paint') {
27
+ return item
28
+ }
29
+ const weapon = Object.values(items).find(si => si.item_quality === 6 && si.item_name === schemaItem.item_name)
30
+ return [item, { ...item, defindex: (weapon ?? {}).defindex }]
31
+ }
96
32
 
97
- const remaps = compose(
98
- unboxSkinsRemap,
99
- warPaintRemap
100
- )
33
+ const remaps = item => unboxSkinsRemap(warPaintRemap(item))
101
34
 
102
35
  const propListDefault = ['killstreakTier', 'elevated', 'festivized', 'effect', 'texture', 'wear', 'craft', 'series']
103
36
 
104
- const blanketify = uncurryN(3, (propList, skus, item) => compose(
105
- map(compose(
106
- mergeRight(item),//merge the props with the item, keeping the assetid for use later
107
- pick(['sku', 'originalSku']),
108
- renameKeys({ _sku: 'sku', sku: 'originalSku' })//reset the sku, save the original sku
109
- )),
110
- filter(compose(includes(__, skus), prop('_sku'))),//find every new combination in the sku list
111
- map(chain(assoc('_sku'), skuFromItem)),//save the new sku
112
- unnest,
113
- map(remaps),//decode defindices that are not possible anymore
114
- map(omit(__, itemFromSku(item.sku))),//create items from the combinations
115
- //concat([[]]),//create the last combination where no prop is removed. If the skus includes the sku we can return it.
116
- chain(compose(getCombos(0), length), identity),//create every possible combination
117
- filter(compose(Boolean, prop(__, itemFromSku(item.sku))))//remove every prop from proplist that is not present in the item
118
- )(propList || propListDefault))
119
-
120
- module.exports = {
121
- blanketify
122
- }
37
+ export const blanketify = (skus, propList = propListDefault) => item => {
38
+ const itemObj = itemFromSku(item.sku)
39
+ const filteredProps = propList.filter(p => Boolean(itemObj[p]))
40
+ const combos = getCombos(0, filteredProps.length, filteredProps)
41
+ return combos
42
+ .map(combo => Object.fromEntries(Object.entries(itemObj).filter(([k]) => !combo.includes(k))))
43
+ .flatMap(v => { const r = remaps(v); return Array.isArray(r) ? r : [r] })
44
+ .map(v => ({ ...v, _sku: skuFromItem(v) }))
45
+ .filter(v => skus.includes(v._sku))
46
+ .map(v => ({ ...item, sku: v._sku, originalSku: item.sku }))
47
+ }
package/browser.js ADDED
@@ -0,0 +1,13 @@
1
+ import helperObjects from './schemaHelper.json' with { type: 'json' }
2
+
3
+ export * from './schemaItems.js'
4
+ export * from './sku.js'
5
+ export * from './skuBp.js'
6
+ export * from './skuLinks.js'
7
+
8
+ export const {
9
+ qualityNames, qualityIds, rarities, killstreakTiers, wears, classes, itemSlots, itemClasses,
10
+ paintHex, paintDefindex, spellDefindex, cosmeticCollections, weaponCollections, warPaintCollections,
11
+ fabricatorDefindex, strangifierTargets, australiumDefindex, crateSeries, paintableDefindex,
12
+ chemsetDefindex, serieslessDefindex, impossibleEffects
13
+ } = helperObjects
@@ -1,48 +1,49 @@
1
- const { call, getContext, delay } = require('redux-saga/effects')
1
+ import { call, getContext, delay } from 'redux-saga/effects'
2
2
 
3
- const {
4
- groupBy, map, compose, uniq, values, mergeRight, indexBy, props, mapObjIndexed, when, complement, has, assoc, unnest, uncurryN, without
5
- } = require('ramda')
3
+ const classKey = (classid, instanceid) => `${classid},${instanceid ?? '0'}`
6
4
 
7
5
  const getAssetClassQuery = assetClassIds => assetClassIds.map(([classid, instanceid], index) => `&classid${index}=${classid}&instanceid${index}=${instanceid}`)
8
6
 
9
- const getAssetClassIds = compose(
10
- uniq,
11
- map(props(['classid', 'instanceid']))
12
- )
7
+ function getAssetClassIds(inventory) {
8
+ const seen = new Set()
9
+ const result = []
10
+ for (const item of inventory) {
11
+ const key = classKey(item.classid, item.instanceid)
12
+ if (!seen.has(key)) {
13
+ seen.add(key)
14
+ result.push([item.classid, item.instanceid])
15
+ }
16
+ }
17
+ return result
18
+ }
13
19
 
14
- const transformAssetClasses = compose(
15
- indexBy(props(['classid', 'instanceid'])),
16
- map(
17
- when(
18
- complement(has)('instanceid'),
19
- assoc('instanceid', '0')
20
- )
21
- ),
22
- values
23
- )
20
+ function transformAssetClasses(items) {
21
+ return Object.fromEntries(
22
+ Object.values(items)
23
+ .filter(item => item !== null && typeof item === 'object')
24
+ .map(item => {
25
+ const withInstanceId = 'instanceid' in item ? item : { ...item, instanceid: '0' }
26
+ return [classKey(withInstanceId.classid, withInstanceId.instanceid), withInstanceId]
27
+ })
28
+ )
29
+ }
24
30
 
25
- const mergeAssetClasses = uncurryN(2, (assetClasses) => compose(
26
- unnest,
27
- values,
28
- mapObjIndexed((v, k) => map(mergeRight(assetClasses[k]), v)),
29
- groupBy(props(['classid', 'instanceid']))
30
- ))
31
+ function mergeAssetClasses(assetClasses, inventory) {
32
+ const groups = Object.groupBy(inventory, item => classKey(item.classid, item.instanceid))
33
+ return Object.keys(groups).flatMap(key => groups[key].map(item => ({ ...assetClasses[key], ...item })))
34
+ }
31
35
 
32
- function* fetchAppDataInventory(inventory, d = 1000, cache = []) {
36
+ export function* fetchAppDataInventory(inventory, d = 1000, cache = []) {
33
37
  let p = 0, assetClasses = transformAssetClasses(cache)
34
38
  const { getAssetClassInfo } = yield getContext('api')
35
- const ids = without(cache.map(props(['classid', 'instanceid'])), getAssetClassIds(inventory))
39
+ const cacheKeys = new Set(cache.map(item => classKey(item.classid, item.instanceid)))
40
+ const ids = getAssetClassIds(inventory).filter(([classid, instanceid]) => !cacheKeys.has(classKey(classid, instanceid)))
36
41
  while (ids.length > 0 && p < ids.length) {
37
42
  yield delay(d)
38
- const query = getAssetClassQuery(ids.slice(p, p + 150))
43
+ const query = getAssetClassQuery(ids.slice(p, p + 125))
39
44
  const { result } = yield call(getAssetClassInfo, query)
40
- assetClasses = mergeRight(assetClasses, transformAssetClasses(result))
41
- p += 150
45
+ assetClasses = { ...assetClasses, ...transformAssetClasses(result) }
46
+ p += 125
42
47
  }
43
48
  return mergeAssetClasses(assetClasses, inventory)
44
49
  }
45
-
46
- module.exports = {
47
- fetchAppDataInventory
48
- }
package/fetchItemsApi.js CHANGED
@@ -1,23 +1,18 @@
1
- const { call, delay, getContext } = require('redux-saga/effects')
2
- const { prop, indexBy, pick, map, compose, evolve, replace, when } = require('ramda')
1
+ import { call, delay, getContext } from 'redux-saga/effects'
3
2
 
4
- const propsToKeep = [
5
- 'image_url'
6
- ]
3
+ const IMAGE_PREFIX = 'http://media.steampowered.com/apps/440/icons/'
7
4
 
8
- const transformItemsApi = compose(
9
- map(
10
- compose(
11
- pick(propsToKeep),
12
- when(
13
- prop('image_url'),
14
- evolve({ image_url: replace('http://media.steampowered.com/apps/440/icons/', '') })
15
- )
16
- )),
17
- indexBy(prop('defindex'))
18
- )
5
+ function transformItemsApi(items) {
6
+ const result = {}
7
+ for (const item of items) {
8
+ result[item.defindex] = item.image_url
9
+ ? { image_url: item.image_url.replace(IMAGE_PREFIX, '') }
10
+ : {}
11
+ }
12
+ return result
13
+ }
19
14
 
20
- function* fetchItemsApi() {
15
+ export function* fetchItemsApi() {
21
16
  const { getSchemaItems } = yield getContext('api')
22
17
  let start = 0, items = []
23
18
  do {
@@ -28,6 +23,3 @@ function* fetchItemsApi() {
28
23
  } while (start >= 0)
29
24
  return transformItemsApi(items)
30
25
  }
31
-
32
-
33
- module.exports = { fetchItemsApi }
package/fetchItemsGame.js CHANGED
@@ -1,12 +1,13 @@
1
- const { call, getContext } = require('redux-saga/effects')
1
+ import { call, getContext } from 'redux-saga/effects'
2
+ import { createRequire } from 'module'
3
+
4
+ const require = createRequire(import.meta.url)
2
5
  const vdf = require('vdf')
3
6
 
4
- function* fetchItemsGame() {
7
+ export function* fetchItemsGame() {
5
8
  const { getItemsGameUrl, getItemsGame } = yield getContext('api')
6
9
  const { result: { items_game_url } } = yield call(getItemsGameUrl)
7
10
  const itemsGameVdf = yield call(getItemsGame, items_game_url)
8
11
  const { items_game } = vdf.parse(itemsGameVdf)
9
12
  return items_game
10
13
  }
11
-
12
- module.exports = { fetchItemsGame }
@@ -1,21 +1,17 @@
1
- const { call, delay, getContext } = require('redux-saga/effects')
2
- const { prop, indexBy, map, compose, pickBy, complement, includes, path, nth, invert, invertObj } = require('ramda')
1
+ import { call, getContext } from 'redux-saga/effects'
3
2
 
4
- const transformEffects = compose(
5
- invertObj,
6
- map(nth(0)),
7
- invert,
8
- pickBy(Boolean),
9
- pickBy(complement(includes)('Attrib_Particle')),
10
- map(prop('name')),
11
- indexBy(prop('id')),
12
- path(['result', 'attribute_controlled_attached_particles'])
13
- )
3
+ function transformEffects(particles) {
4
+ const byName = {}
5
+ for (const { id, name } of particles) {
6
+ if (name && !name.includes('Attrib_Particle')) {
7
+ byName[name] ??= id
8
+ }
9
+ }
10
+ return Object.fromEntries(Object.entries(byName).map(([name, id]) => [id, name]))
11
+ }
14
12
 
15
- function* fetchParticleEffects() {
13
+ export function* fetchParticleEffects() {
16
14
  const { getSchemaOverview } = yield getContext('api')
17
15
  const schema = yield call(getSchemaOverview)
18
- return transformEffects(schema)
16
+ return transformEffects(schema.result.attribute_controlled_attached_particles)
19
17
  }
20
-
21
- module.exports = { fetchParticleEffects }
package/fetchTextures.js CHANGED
@@ -1,20 +1,18 @@
1
- const { call, getContext } = require('redux-saga/effects')
2
- const vdf = require('vdf')
3
-
4
- const { path, compose, pickBy, startsWith, reduce, replace, __, mapKeys } = require('ramda')
5
-
6
- const sanitizeTexture = reduce((all, curr) => replace(curr, '', all), __, ['9_', '_field { field_number: 2 }'])
1
+ import { call, getContext } from 'redux-saga/effects'
2
+ import { createRequire } from 'module'
7
3
 
8
- const transformTextures = compose(
9
- mapKeys(sanitizeTexture),
10
- pickBy((val, key) => startsWith('9', key) && isNaN(val[0])),
11
- path(['lang', 'Tokens'])
12
- )
4
+ const require = createRequire(import.meta.url)
5
+ const vdf = require('vdf')
13
6
 
14
- function* fetchTextures() {
7
+ export function* fetchTextures() {
15
8
  const { fetchProtoObjDefs } = yield getContext('api')
16
9
  const protoObjDefs = yield call(fetchProtoObjDefs)
17
- return transformTextures(vdf.parse(protoObjDefs))
10
+ const tokens = vdf.parse(protoObjDefs).lang.Tokens
11
+ const result = {}
12
+ for (const [key, val] of Object.entries(tokens)) {
13
+ if (key.startsWith('9') && isNaN(val[0])) {
14
+ result[key.replace(/^9_/, '').replace('_field { field_number: 2 }', '')] = val
15
+ }
16
+ }
17
+ return result
18
18
  }
19
-
20
- module.exports = { fetchTextures }
package/fetchTfEnglish.js CHANGED
@@ -1,12 +1,13 @@
1
- const { call, getContext } = require('redux-saga/effects')
1
+ import { call, getContext } from 'redux-saga/effects'
2
+ import { createRequire } from 'module'
3
+
4
+ const require = createRequire(import.meta.url)
2
5
  const vdf = require('vdf')
3
- const { toLower, mapKeys } = require('ramda')
4
6
 
5
- function* fetchTfEnglish() {
6
- const { fetchTfEnglish } = yield getContext('api')
7
- const english = yield call(fetchTfEnglish)
7
+ export function* fetchTfEnglish() {
8
+ const { fetchTfEnglish: fetchTfEnglishApi } = yield getContext('api')
9
+ const english = yield call(fetchTfEnglishApi)
8
10
  const englishVdf = vdf.parse(english)
9
- return mapKeys(toLower, englishVdf.lang.Tokens)
11
+ const tokens = englishVdf.lang.Tokens
12
+ return Object.fromEntries(Object.entries(tokens).map(([k, v]) => [k.toLowerCase(), v]))
10
13
  }
11
-
12
- module.exports = { fetchTfEnglish }