mirror of
https://github.com/tcgdex/javascript-sdk.git
synced 2025-07-13 18:45:09 +00:00
Compare commits
30 Commits
dependabot
...
master
Author | SHA1 | Date | |
---|---|---|---|
6849546c1a | |||
95a658f98a | |||
c866b4022f | |||
978a676a79 | |||
1f801f4a94 | |||
4e4bcf9d26
|
|||
0b14e8ddec | |||
fc4a31ef39 | |||
26acb1eb61
|
|||
c03183bd6f
|
|||
07403cb3ae
|
|||
f5dd4cb88c | |||
9b9ff2f028 | |||
ce64a95f4e | |||
460f101026 | |||
b3ba7820a3
|
|||
1f3aae5401 | |||
e501faa823 | |||
e08fd98269 | |||
54a4b729b3 | |||
26af3b0779 | |||
bf54ab3809 | |||
f2621890e1 | |||
4364da480f | |||
0cc8577fe0 | |||
0f2ad36e8c | |||
74de8961ef | |||
98c80fcd20 | |||
c392b27cac | |||
dc5e41a638 |
8
.github/workflows/build.yml
vendored
8
.github/workflows/build.yml
vendored
@ -14,9 +14,10 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
# Follow current releases https://nodejs.org/en/about/releases/
|
# Follow current releases https://github.com/nodejs/release#release-schedule
|
||||||
node-version: [14.x, 16.x, 18.x, 19.x]
|
node-version: [18.x, 20.x, 21.x, 22.x]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@ -26,6 +27,7 @@ jobs:
|
|||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
|
cache: 'npm'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
@ -37,7 +39,7 @@ jobs:
|
|||||||
run: npm run test
|
run: npm run test
|
||||||
|
|
||||||
- name: Upload Coverage
|
- name: Upload Coverage
|
||||||
if: matrix.node-version == '16.x'
|
if: matrix.node-version == '22.x'
|
||||||
uses: codecov/codecov-action@v3
|
uses: codecov/codecov-action@v3
|
||||||
with:
|
with:
|
||||||
# Comma-separated list of files to upload
|
# Comma-separated list of files to upload
|
||||||
|
25
.github/workflows/publish.yml
vendored
25
.github/workflows/publish.yml
vendored
@ -1,19 +1,22 @@
|
|||||||
name: publish
|
name: Publish the Package
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
tags:
|
tags:
|
||||||
- 'v[0-9]+.[0-9]+.[0-9]+*'
|
- v*
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
publish:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Setup NodeJS
|
- name: Setup Publishing to NPMJS
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: '18.x'
|
node-version: '20.x'
|
||||||
registry-url: 'https://registry.npmjs.org'
|
registry-url: 'https://registry.npmjs.org'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
@ -22,7 +25,17 @@ jobs:
|
|||||||
- name: Build
|
- name: Build
|
||||||
run: npm run build
|
run: npm run build
|
||||||
|
|
||||||
- name: Publish
|
- name: Publish on NPM
|
||||||
run: npm publish
|
run: npm publish
|
||||||
env:
|
env:
|
||||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||||
|
|
||||||
|
- name: Setup Publishing to Github Packages
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
registry-url: 'https://npm.pkg.github.com'
|
||||||
|
|
||||||
|
- name: Publish on Github
|
||||||
|
run: npm publish
|
||||||
|
env:
|
||||||
|
NODE_AUTH_TOKEN: ${{ secrets.REPO_TOKEN }}
|
||||||
|
30
CHANGELOG.md
30
CHANGELOG.md
@ -7,6 +7,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## 2.5.1 - 2023-07-18
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- ModuleJS exports not working as intended
|
||||||
|
|
||||||
|
## 2.5.0 - 2023-06-28
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Support for both ModuleJS and CommonJS
|
||||||
|
|
||||||
|
## 2.4.9 - 2022-09-26
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- package not loading on browser
|
||||||
|
|
||||||
|
## 2.4.8 - 2022-09-26
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- fix version number not correctly exposting
|
||||||
|
|
||||||
|
## 2.4.7 - 2022-09-26
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Compatibility with Angular
|
||||||
|
|
||||||
## 2.4.6 - 2022-01-28
|
## 2.4.6 - 2022-01-28
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<img src="https://img.shields.io/github/stars/tcgdex/javascript-sdk?style=flat-square" alt="Github stars">
|
<img src="https://img.shields.io/github/stars/tcgdex/javascript-sdk?style=flat-square" alt="Github stars">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/tcgdex/javascript-sdk/actions/workflows/build.yml">
|
<a href="https://github.com/tcgdex/javascript-sdk/actions/workflows/build.yml">
|
||||||
<img src="https://img.shields.io/github/workflow/status/tcgdex/javascript-sdk/Build%20&%20Test?style=flat-square" alt="the TCGdex JAvascript SDK is released under the MIT license." />
|
<img src="https://img.shields.io/github/actions/workflow/status/tcgdex/javascript-sdk/build.yml?style=flat-square" alt="the TCGdex JAvascript SDK is released under the MIT license." />
|
||||||
</a>
|
</a>
|
||||||
<a href="https://discord.gg/NehYTAhsZE">
|
<a href="https://discord.gg/NehYTAhsZE">
|
||||||
<img src="https://img.shields.io/discord/857231041261076491?color=%235865F2&label=Discord&style=flat-square" alt="Discord Link">
|
<img src="https://img.shields.io/discord/857231041261076491?color=%235865F2&label=Discord&style=flat-square" alt="Discord Link">
|
||||||
@ -82,8 +82,11 @@ _in Browser_
|
|||||||
_in NodeJS (in an async context)_
|
_in NodeJS (in an async context)_
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// Import the SDK in Typescript
|
// Import the SDK in Typescript or moduleJS
|
||||||
import TCGdex from '@tcgdex/sdk';
|
import TCGdex from '@tcgdex/sdk'
|
||||||
|
|
||||||
|
// import the SDK in commonJS
|
||||||
|
const TCGdex = require('@tcgdex/sdk').default
|
||||||
|
|
||||||
// Instantiate the SDK
|
// Instantiate the SDK
|
||||||
const tcgdex = new TCGdex('en');
|
const tcgdex = new TCGdex('en');
|
||||||
|
151
__tests__/basic.test.ts
Normal file
151
__tests__/basic.test.ts
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
import { expect, test, vi } from 'vitest'
|
||||||
|
import TCGdex, { Query } from '../src/tcgdex'
|
||||||
|
|
||||||
|
// change timeout of execution
|
||||||
|
vi.setConfig({ testTimeout: 120000 })
|
||||||
|
|
||||||
|
const fakeFetch = (response: any, status = 200) => vi.fn(() =>
|
||||||
|
Promise.resolve({
|
||||||
|
status: status,
|
||||||
|
json: () => Promise.resolve(response)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
test('Basic test', async () => {
|
||||||
|
const tcgdex = new TCGdex('en')
|
||||||
|
TCGdex.fetch = fakeFetch({ ok: true }) as any
|
||||||
|
const res = await tcgdex.fetch('cards', 'basic-test')
|
||||||
|
expect(res).toEqual({ ok: true })
|
||||||
|
expect(TCGdex.fetch).toHaveBeenCalledTimes(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('endpoint errors', async () => {
|
||||||
|
const tcgdex = new TCGdex('en')
|
||||||
|
TCGdex.fetch = fakeFetch({ ok: 'a' }) as any
|
||||||
|
await expect(tcgdex.fetch('non existing endpoint')).rejects.toThrow()
|
||||||
|
await expect(tcgdex.fetch()).rejects.toThrow()
|
||||||
|
})
|
||||||
|
|
||||||
|
test(`404 error`, async () => {
|
||||||
|
const tcgdex = new TCGdex('en')
|
||||||
|
TCGdex.fetch = fetch
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await tcgdex.card.get('404-error')
|
||||||
|
).toBeNull()
|
||||||
|
})
|
||||||
|
|
||||||
|
test(`test getting full set from list`, async () => {
|
||||||
|
const tcgdex = new TCGdex('en')
|
||||||
|
TCGdex.fetch = fetch
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await (await tcgdex.set.list())[0].getSet()
|
||||||
|
).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
test(`test getting full serie from list`, async () => {
|
||||||
|
const tcgdex = new TCGdex('en')
|
||||||
|
TCGdex.fetch = fetch
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await (await tcgdex.serie.list())[0].getSerie()
|
||||||
|
).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
test(`test getting full card from list`, async () => {
|
||||||
|
const tcgdex = new TCGdex('en')
|
||||||
|
TCGdex.fetch = fetch
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await (await tcgdex.card.list())[0].getCard()
|
||||||
|
).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
test(`test get set from card`, async () => {
|
||||||
|
const tcgdex = new TCGdex('en')
|
||||||
|
TCGdex.fetch = fetch
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await (await tcgdex.card.get('swsh1-136'))!.getSet()
|
||||||
|
).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
test(`test get serie from set`, async () => {
|
||||||
|
const tcgdex = new TCGdex('en')
|
||||||
|
TCGdex.fetch = fetch
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await (await tcgdex.set.get('swsh1'))!.getSerie()
|
||||||
|
).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
test(`advanced query system`, async () => {
|
||||||
|
const tcgdex = new TCGdex('en')
|
||||||
|
TCGdex.fetch = fetch
|
||||||
|
|
||||||
|
expect(
|
||||||
|
(await tcgdex.card.list(
|
||||||
|
Query.create()
|
||||||
|
.equal('name', 'Pikachu')
|
||||||
|
.greaterOrEqualThan('hp', 60)
|
||||||
|
.lesserThan('hp', 70)
|
||||||
|
.contains('localId', '5')
|
||||||
|
.not.contains('localId', 'tg')
|
||||||
|
.not.equal('id', 'cel25-5')
|
||||||
|
.sort('localId', 'ASC')
|
||||||
|
.paginate(3, 2)
|
||||||
|
)).length
|
||||||
|
).toBe(2)
|
||||||
|
})
|
||||||
|
|
||||||
|
const endpoints = [
|
||||||
|
{ endpoint: 'card', params: ['swsh1-136'] },
|
||||||
|
{ endpoint: 'set', params: ['swsh1'] },
|
||||||
|
{ endpoint: 'serie', params: ['swsh'] },
|
||||||
|
{ endpoint: 'type', params: ['fire'] },
|
||||||
|
{ endpoint: 'retreat', params: ['1'] },
|
||||||
|
{ endpoint: 'rarity', params: ['common'] },
|
||||||
|
{ endpoint: 'illustrator', params: [''] },
|
||||||
|
{ endpoint: 'hp', params: ['30'] },
|
||||||
|
{ endpoint: 'categorie', params: ['pokemon'] },
|
||||||
|
{ endpoint: 'dexID', params: ['1'] },
|
||||||
|
{ endpoint: 'energyType', params: ['normal'] },
|
||||||
|
{ endpoint: 'regulationMark', params: ['f'] },
|
||||||
|
{ endpoint: 'stage', params: ['basic'] },
|
||||||
|
{ endpoint: 'suffixe', params: ['ex'] },
|
||||||
|
{ endpoint: 'trainerType', params: ['item'] },
|
||||||
|
{ endpoint: 'variant', params: ['normal'] },
|
||||||
|
]
|
||||||
|
|
||||||
|
for (const endpoint of endpoints) {
|
||||||
|
test(`test real ${endpoint.endpoint} endpoint list`, async () => {
|
||||||
|
const tcgdex = new TCGdex('en')
|
||||||
|
TCGdex.fetch = fetch
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await (tcgdex[endpoint.endpoint]).list()
|
||||||
|
).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
test(`test real ${endpoint.endpoint} endpoint item`, async () => {
|
||||||
|
const tcgdex = new TCGdex('en')
|
||||||
|
TCGdex.fetch = fetch
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await (tcgdex[endpoint.endpoint]).get(endpoint.params[0])
|
||||||
|
).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
test(`random card/set/serie`, async () => {
|
||||||
|
const tcgdex = new TCGdex('en')
|
||||||
|
TCGdex.fetch = fetch
|
||||||
|
|
||||||
|
expect((await tcgdex.random.card())).toBeTruthy()
|
||||||
|
expect((await tcgdex.random.set())).toBeTruthy()
|
||||||
|
expect((await tcgdex.random.serie())).toBeTruthy()
|
||||||
|
})
|
@ -1,43 +1,44 @@
|
|||||||
const TCGdex = require("../src/tcgdex").default
|
import { expect, test, vi } from 'vitest'
|
||||||
const fetch = require('node-fetch')
|
import TCGdex from '../src/tcgdex'
|
||||||
|
|
||||||
const fakeFetch = (response, status = 200) => jest.fn(() =>
|
// change timeout of execution
|
||||||
|
vi.setConfig({ testTimeout: 120000 })
|
||||||
|
|
||||||
|
const fakeFetch = (response, status = 200) => vi.fn(() =>
|
||||||
Promise.resolve({
|
Promise.resolve({
|
||||||
status: status,
|
status: status,
|
||||||
json: () => Promise.resolve(response),
|
json: () => Promise.resolve(response),
|
||||||
})
|
})
|
||||||
);
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
test('Basic test', async () => {
|
test('Basic test', async () => {
|
||||||
const tcgdex = new TCGdex('en')
|
const tcgdex = new TCGdex('en')
|
||||||
TCGdex.fetch = fakeFetch({ok: true})
|
TCGdex.fetch = fakeFetch({ ok: true }) as any
|
||||||
const res = await tcgdex.fetch('cards', 'basic-test')
|
const res = await tcgdex.fetch('cards', 'basic-test')
|
||||||
expect(res).toEqual({ok: true})
|
expect(res).toEqual({ ok: true })
|
||||||
expect(TCGdex.fetch).toHaveBeenCalledTimes(1)
|
expect(TCGdex.fetch).toHaveBeenCalledTimes(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Cache test', async () => {
|
test('Cache test', async () => {
|
||||||
const tcgdex = new TCGdex('en')
|
const tcgdex = new TCGdex('en')
|
||||||
TCGdex.fetch = fakeFetch({ok: 'a'})
|
TCGdex.fetch = fakeFetch({ ok: 'a' }) as any
|
||||||
const res1 = await tcgdex.fetch('cards', 'cache-test')
|
const res1 = await tcgdex.fetch('cards', 'cache-test')
|
||||||
expect(res1).toEqual({ok: 'a'})
|
expect(res1).toEqual({ ok: 'a' })
|
||||||
TCGdex.fetch = fakeFetch({ok: 'b'})
|
TCGdex.fetch = fakeFetch({ ok: 'b' }) as any
|
||||||
const res2 = await tcgdex.fetch('cards', 'cache-test')
|
const res2 = await tcgdex.fetch('cards', 'cache-test')
|
||||||
expect(res2).toEqual({ok: 'a'})
|
expect(res2).toEqual({ ok: 'a' })
|
||||||
})
|
})
|
||||||
|
|
||||||
test('endpoint errors', async () => {
|
test('endpoint errors', async () => {
|
||||||
const tcgdex = new TCGdex('en')
|
const tcgdex = new TCGdex('en')
|
||||||
TCGdex.fetch = fakeFetch({ok: 'a'})
|
TCGdex.fetch = fakeFetch({ ok: 'a' }) as any
|
||||||
await expect(tcgdex.fetch('non existing endpoint')).rejects.toThrow()
|
await expect(tcgdex.fetch('non existing endpoint')).rejects.toThrow()
|
||||||
await expect(tcgdex.fetch()).rejects.toThrow()
|
await expect(tcgdex.fetch()).rejects.toThrow()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('404 test', async () => {
|
test('404 test', async () => {
|
||||||
const tcgdex = new TCGdex('en')
|
const tcgdex = new TCGdex('en')
|
||||||
TCGdex.fetch = fakeFetch(undefined, 404)
|
TCGdex.fetch = fakeFetch(undefined, 404) as any
|
||||||
expect(
|
expect(
|
||||||
await tcgdex.fetch('cards', '404-test')
|
await tcgdex.fetch('cards', '404-test')
|
||||||
).not.toBeDefined()
|
).not.toBeDefined()
|
||||||
@ -47,15 +48,15 @@ test('test real endpoints', async () => {
|
|||||||
const tcgdex = new TCGdex('en')
|
const tcgdex = new TCGdex('en')
|
||||||
TCGdex.fetch = fetch
|
TCGdex.fetch = fetch
|
||||||
const endpoints = [
|
const endpoints = [
|
||||||
{endpoint: 'fetchCard', params: ['swsh1-1']},
|
{ endpoint: 'fetchCard', params: ['swsh1-1'] },
|
||||||
{endpoint: 'fetchCard', params: ['1', 'Sword & Shield']},
|
{ endpoint: 'fetchCard', params: ['1', 'Sword & Shield'] },
|
||||||
{endpoint: 'fetchCards', params: ['swsh1']},
|
{ endpoint: 'fetchCards', params: ['swsh1'] },
|
||||||
{endpoint: 'fetchCards', params: []},
|
{ endpoint: 'fetchCards', params: [] },
|
||||||
{endpoint: 'fetchSet', params: ['swsh1']},
|
{ endpoint: 'fetchSet', params: ['swsh1'] },
|
||||||
{endpoint: 'fetchSets', params: ['swsh']},
|
{ endpoint: 'fetchSets', params: ['swsh'] },
|
||||||
{endpoint: 'fetchSets', params: []},
|
{ endpoint: 'fetchSets', params: [] },
|
||||||
{endpoint: 'fetchSeries', params: []},
|
{ endpoint: 'fetchSeries', params: [] },
|
||||||
{endpoint: 'fetchSerie', params: ['swsh']},
|
{ endpoint: 'fetchSerie', params: ['swsh'] },
|
||||||
]
|
]
|
||||||
|
|
||||||
for await (const item of endpoints) {
|
for await (const item of endpoints) {
|
5317
package-lock.json
generated
5317
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
44
package.json
44
package.json
@ -1,9 +1,22 @@
|
|||||||
{
|
{
|
||||||
"name": "@tcgdex/sdk",
|
"name": "@tcgdex/sdk",
|
||||||
"version": "2.4.9",
|
"version": "2.7.0",
|
||||||
"main": "./dist/cjs/tcgdex.node.js",
|
"main": "./dist/tcgdex.node.js",
|
||||||
"module": "./dist/modules/tcgdex.node.js",
|
"module": "./dist/tcgdex.node.mjs",
|
||||||
"types": "./dist/types/tcgdex.d.ts",
|
"types": "./dist/tcgdex.node.d.ts",
|
||||||
|
"browser": "./dist/tcgdex.browser.global.js",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"require": {
|
||||||
|
"types": "./dist/tcgdex.node.d.ts",
|
||||||
|
"default": "./dist/tcgdex.node.js"
|
||||||
|
},
|
||||||
|
"import": {
|
||||||
|
"types": "./dist/tcgdex.node.d.mts",
|
||||||
|
"default": "./dist/tcgdex.node.mjs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"description": "Communicate with the Open Source TCGdex API in Javascript/Typescript using the SDK",
|
"description": "Communicate with the Open Source TCGdex API in Javascript/Typescript using the SDK",
|
||||||
"repository": "https://github.com/tcgdex/javascript-sdk.git",
|
"repository": "https://github.com/tcgdex/javascript-sdk.git",
|
||||||
"homepage": "https://github.com/tcgdex/javascript-sdk",
|
"homepage": "https://github.com/tcgdex/javascript-sdk",
|
||||||
@ -18,7 +31,9 @@
|
|||||||
"api",
|
"api",
|
||||||
"typescript",
|
"typescript",
|
||||||
"javascript",
|
"javascript",
|
||||||
"typing"
|
"typing",
|
||||||
|
"browser",
|
||||||
|
"node"
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -29,27 +44,28 @@
|
|||||||
"@types/node-fetch": "^2",
|
"@types/node-fetch": "^2",
|
||||||
"@typescript-eslint/eslint-plugin": "^5",
|
"@typescript-eslint/eslint-plugin": "^5",
|
||||||
"@typescript-eslint/parser": "^5",
|
"@typescript-eslint/parser": "^5",
|
||||||
"esbuild": "^0.16.3",
|
"@vitest/coverage-v8": "^2.1.8",
|
||||||
"eslint": "^8",
|
"eslint": "^8",
|
||||||
"jest": "^29",
|
"jest": "^29",
|
||||||
"typescript": "^4"
|
"tsup": "^7",
|
||||||
|
"typescript": "^5",
|
||||||
|
"vitest": "^2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"isomorphic-unfetch": "^3",
|
"@cachex/memory": "^1",
|
||||||
"unfetch": "^4"
|
"@cachex/web-storage": "^1",
|
||||||
|
"@dzeio/object-util": "^1",
|
||||||
|
"isomorphic-unfetch": "^3"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prebuild": "node scripts/export-version-number.js",
|
"prebuild": "node scripts/export-version-number.js",
|
||||||
"build": "npm run build:cjs && npm run build:browser && npm run build:es2015",
|
"build": "rm -rf dist && tsup ./src/tcgdex.node.ts --format cjs,esm --dts --clean && tsup ./src/tcgdex.browser.ts --format iife --global-name TCGdex --sourcemap",
|
||||||
"build:cjs": "tsc --project tsconfig.json",
|
|
||||||
"build:es2015": "tsc --project tsconfig.es2015.json",
|
|
||||||
"build:browser": "esbuild ./src/tcgdex.browser.ts --bundle --minify --sourcemap --target=es2016,chrome90,firefox78,safari14,ios13,edge90 --outfile=dist/tcgdex.browser.js",
|
|
||||||
"prepublishOnly": "npm run build",
|
"prepublishOnly": "npm run build",
|
||||||
"lint": "eslint",
|
"lint": "eslint",
|
||||||
"test": "jest --coverage"
|
"test": "vitest run --coverage"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist"
|
||||||
|
88
src/Query.ts
Normal file
88
src/Query.ts
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
export default class Query {
|
||||||
|
public params: Array<{ key: string, value: string | number | boolean }> = []
|
||||||
|
|
||||||
|
public not: {
|
||||||
|
equal: (key: string, value: string) => Query
|
||||||
|
contains: (key: string, value: string) => Query
|
||||||
|
includes: (key: string, value: string) => Query
|
||||||
|
like: (key: string, value: string) => Query
|
||||||
|
isNull: (key: string) => Query
|
||||||
|
} = {
|
||||||
|
equal: (key: string, value: string) => {
|
||||||
|
this.params.push({ key: key, value: `neq:${value}` })
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
contains: (key: string, value: string) => {
|
||||||
|
this.params.push({ key: key, value: `not:${value}` })
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
includes: (key: string, value: string) => this.not.contains(key, value),
|
||||||
|
like: (key: string, value: string) => this.not.contains(key, value),
|
||||||
|
isNull: (key: string) => {
|
||||||
|
this.params.push({ key: key, value: 'notnull:' })
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static create(): Query {
|
||||||
|
return new Query()
|
||||||
|
}
|
||||||
|
|
||||||
|
public includes(key: string, value: string): this {
|
||||||
|
return this.contains(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public like(key: string, value: string): this {
|
||||||
|
return this.contains(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public contains(key: string, value: string): this {
|
||||||
|
this.params.push({ key: key, value: value })
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
public equal(key: string, value: string): this {
|
||||||
|
this.params.push({ key: key, value: `eq:${value}` })
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
public sort(key: string, order: 'ASC' | 'DESC'): this {
|
||||||
|
this.params.push({ key: 'sort:field', value: key })
|
||||||
|
this.params.push({ key: 'sort:order', value: order })
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
public greaterOrEqualThan(key: string, value: number) {
|
||||||
|
this.params.push({ key: key, value: `gte:${value}` })
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
public lesserOrEqualThan(key: string, value: number) {
|
||||||
|
this.params.push({ key: key, value: `lte:${value}` })
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
public greaterThan(key: string, value: number) {
|
||||||
|
this.params.push({ key: key, value: `gt:${value}` })
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
public lesserThan(key: string, value: number) {
|
||||||
|
this.params.push({ key: key, value: `lt:${value}` })
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
public isNull(key: string) {
|
||||||
|
this.params.push({ key: key, value: 'null:' })
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
public paginate(page: number, itemsPerPage: number): this {
|
||||||
|
this.params.push({ key: 'pagination:page', value: page })
|
||||||
|
this.params.push({ key: 'pagination:itemsPerPage', value: itemsPerPage })
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
@ -1,31 +0,0 @@
|
|||||||
import TCGdex from './tcgdex'
|
|
||||||
import { version } from './version'
|
|
||||||
|
|
||||||
export default class Request {
|
|
||||||
|
|
||||||
// 1 hour of TTL by default
|
|
||||||
public static ttl = 1000 * 60 * 60
|
|
||||||
|
|
||||||
private static cache: Record<string, {response: any, time: number}> = {}
|
|
||||||
|
|
||||||
public static async fetch<T>(url: string): Promise<T | undefined> {
|
|
||||||
let request = this.cache[url]
|
|
||||||
const now = new Date().getTime()
|
|
||||||
if (!request || now - request.time > this.ttl) {
|
|
||||||
const unfetch = TCGdex.fetch
|
|
||||||
const resp = await unfetch(url, {
|
|
||||||
headers: {
|
|
||||||
'user-agent': `@tcgdex/javascript-sdk/${version}`
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if (resp.status !== 200) {
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
this.cache[url] = { response: await resp.json(), time: now }
|
|
||||||
request = this.cache[url]
|
|
||||||
}
|
|
||||||
return request.response
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
26
src/endpoints/Endpoint.ts
Normal file
26
src/endpoints/Endpoint.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import type { Endpoints } from '../interfaces'
|
||||||
|
import Model from '../models/Model'
|
||||||
|
import type Query from '../Query'
|
||||||
|
import type TCGdex from '../tcgdex'
|
||||||
|
|
||||||
|
export default class Endpoint<Item extends Model, List extends Model> {
|
||||||
|
public constructor(
|
||||||
|
protected readonly tcgdex: TCGdex,
|
||||||
|
protected readonly itemModel: new (sdk: TCGdex) => Item,
|
||||||
|
protected readonly listModel: new (sdk: TCGdex) => List,
|
||||||
|
protected readonly endpoint: Endpoints
|
||||||
|
) { }
|
||||||
|
|
||||||
|
public async get(id: string | number): Promise<Item | null> {
|
||||||
|
const res = await this.tcgdex.fetch(this.endpoint as 'cards', id as string)
|
||||||
|
if (!res) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return Model.build(new this.itemModel(this.tcgdex), res)
|
||||||
|
}
|
||||||
|
|
||||||
|
public async list(query?: Query): Promise<Array<List>> {
|
||||||
|
const res = await this.tcgdex.fetchWithQuery([this.endpoint], query?.params)
|
||||||
|
return (res as Array<object> ?? []).map((it) => Model.build(new this.listModel(this.tcgdex), it))
|
||||||
|
}
|
||||||
|
}
|
24
src/endpoints/SimpleEndpoint.ts
Normal file
24
src/endpoints/SimpleEndpoint.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import type { Endpoints } from '../interfaces'
|
||||||
|
import Model from '../models/Model'
|
||||||
|
import type Query from '../Query'
|
||||||
|
import type TCGdex from '../tcgdex'
|
||||||
|
|
||||||
|
export default class SimpleEndpoint<Item extends Model, List extends string | number> {
|
||||||
|
public constructor(
|
||||||
|
protected readonly tcgdex: TCGdex,
|
||||||
|
protected readonly itemModel: new (sdk: TCGdex) => Item,
|
||||||
|
protected readonly endpoint: Endpoints
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public async get(id: string | number): Promise<Item | null> {
|
||||||
|
const res = await this.tcgdex.fetch(this.endpoint as 'cards', id as string)
|
||||||
|
if (!res) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return Model.build(new this.itemModel(this.tcgdex), res)
|
||||||
|
}
|
||||||
|
|
||||||
|
public async list(query?: Query): Promise<Array<List>> {
|
||||||
|
return await this.tcgdex.fetchWithQuery([this.endpoint], query?.params) ?? []
|
||||||
|
}
|
||||||
|
}
|
22
src/interfaces.ts → src/interfaces.d.ts
vendored
22
src/interfaces.ts → src/interfaces.d.ts
vendored
@ -22,9 +22,18 @@ interface variants {
|
|||||||
firstEdition?: boolean
|
firstEdition?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface booster {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
logo?: string
|
||||||
|
artwork_front?: string
|
||||||
|
artwork_back?: string
|
||||||
|
}
|
||||||
|
|
||||||
export type SetList = Array<SetResume>
|
export type SetList = Array<SetResume>
|
||||||
export type SerieList = Array<SerieResume>
|
export type SerieList = Array<SerieResume>
|
||||||
export type CardList = Array<CardResume>
|
export type CardList = Array<CardResume>
|
||||||
|
export type BoosterList = Array<booster>
|
||||||
|
|
||||||
export interface SetResume {
|
export interface SetResume {
|
||||||
id: string
|
id: string
|
||||||
@ -105,6 +114,8 @@ export interface Set extends SetResume {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cards: CardList
|
cards: CardList
|
||||||
|
|
||||||
|
boosters?: BoosterList
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CardResume {
|
export interface CardResume {
|
||||||
@ -302,6 +313,8 @@ export interface Card<SetType extends SetResume = SetResume> extends CardResume
|
|||||||
*/
|
*/
|
||||||
expanded: boolean
|
expanded: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boosters?: BoosterList
|
||||||
}
|
}
|
||||||
|
|
||||||
export type StringEndpointList = Array<string>
|
export type StringEndpointList = Array<string>
|
||||||
@ -310,3 +323,12 @@ export interface StringEndpoint {
|
|||||||
name: string
|
name: string
|
||||||
cards: Array<CardResume>
|
cards: Array<CardResume>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type Quality = 'low' | 'high'
|
||||||
|
|
||||||
|
export type Extension = 'jpg' | 'webp' | 'png'
|
||||||
|
|
||||||
|
export type Endpoints = 'cards' | 'categories' | 'dex-ids' | 'energy-types' |
|
||||||
|
'hp' | 'illustrators' | 'rarities' | 'regulation-marks' |
|
||||||
|
'retreats' | 'series' | 'sets' | 'stages' | 'suffixes' |
|
||||||
|
'trainer-types' | 'types' | 'variants' | 'random'
|
200
src/models/Card.ts
Normal file
200
src/models/Card.ts
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
import CardResume from './CardResume'
|
||||||
|
import type { Booster, Variants } from './Other'
|
||||||
|
import type TCGdexSet from './Set'
|
||||||
|
import type SetResume from './SetResume'
|
||||||
|
|
||||||
|
// TODO: sort elements by alphabetical order
|
||||||
|
export default class Card extends CardResume {
|
||||||
|
/**
|
||||||
|
* Card illustrator
|
||||||
|
*/
|
||||||
|
public illustrator?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Card Rarity
|
||||||
|
*
|
||||||
|
* - None https://www.tcgdex.net/database/sm/smp/SM01
|
||||||
|
* - Common https://www.tcgdex.net/database/xy/xy9/1
|
||||||
|
* - Uncommon https://www.tcgdex.net/database/xy/xy9/2
|
||||||
|
* - Rare https://www.tcgdex.net/database/xy/xy9/3
|
||||||
|
* - Ultra Rare
|
||||||
|
* - Secret Rare
|
||||||
|
*/
|
||||||
|
public rarity!: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Card Category
|
||||||
|
*
|
||||||
|
* - Pokemon
|
||||||
|
* - Trainer
|
||||||
|
* - Energy
|
||||||
|
*/
|
||||||
|
public category!: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Card Variants (Override Set Variants)
|
||||||
|
*/
|
||||||
|
public variants?: Variants
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Card Set
|
||||||
|
*/
|
||||||
|
public set!: SetResume
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pokemon only elements
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pokemon Pokedex ID
|
||||||
|
*/
|
||||||
|
public dexId?: Array<number>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pokemon HP
|
||||||
|
*/
|
||||||
|
public hp?: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pokemon Types
|
||||||
|
* ex for multiple https://www.tcgdex.net/database/ex/ex13/17
|
||||||
|
*/
|
||||||
|
public types?: Array<string>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pokemon Sub Evolution
|
||||||
|
*/
|
||||||
|
public evolveFrom?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pokemon Weight
|
||||||
|
*/
|
||||||
|
public weight?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pokemon Description
|
||||||
|
*/
|
||||||
|
public description?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Level of the Pokemon
|
||||||
|
*
|
||||||
|
* NOTE: can be equal to 'X' when the pokemon is a LEVEL-UP one
|
||||||
|
*/
|
||||||
|
public level?: number | string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pokemon Stage
|
||||||
|
*
|
||||||
|
* - Basic https://www.tcgdex.net/database/xy/xy9/1
|
||||||
|
* - BREAK https://www.tcgdex.net/database/xy/xy9/18
|
||||||
|
* - LEVEL-UP https://www.tcgdex.net/database/dp/dp1/121
|
||||||
|
* - MEGA https://www.tcgdex.net/database/xy/xy1/2
|
||||||
|
* - RESTORED https://www.tcgdex.net/database/bw/bw5/53
|
||||||
|
* - Stage1 https://www.tcgdex.net/database/xy/xy9/2
|
||||||
|
* - Stage2 https://www.tcgdex.net/database/xy/xy9/3
|
||||||
|
* - VMAX https://www.tcgdex.net/database/swsh/swsh1/50
|
||||||
|
*/
|
||||||
|
public stage?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Card Suffix
|
||||||
|
*
|
||||||
|
* - EX https://www.tcgdex.net/database/ex/ex2/94
|
||||||
|
* - GX https://www.tcgdex.net/database/sm/sm12/4
|
||||||
|
* - V https://www.tcgdex.net/database/swsh/swsh1/1
|
||||||
|
* - Legend https://www.tcgdex.net/database/hgss/hgss1/114
|
||||||
|
* - Prime https://www.tcgdex.net/database/hgss/hgss2/85
|
||||||
|
* - SP https://www.tcgdex.net/database/pl/pl1/7
|
||||||
|
* - TAG TEAM-GX https://www.tcgdex.net/database/sm/sm12/226
|
||||||
|
*/
|
||||||
|
public suffix?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pokemon Held Item
|
||||||
|
*
|
||||||
|
* ex https://www.tcgdex.net/database/dp/dp2/75
|
||||||
|
*/
|
||||||
|
public item?: {
|
||||||
|
name: string
|
||||||
|
effect: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pokemon Abilities
|
||||||
|
*
|
||||||
|
* multi abilities ex https://www.tcgdex.net/database/ex/ex15/10
|
||||||
|
*/
|
||||||
|
public abilities?: Array<{
|
||||||
|
type: string
|
||||||
|
name: string
|
||||||
|
effect: string
|
||||||
|
}>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pokemon Attacks
|
||||||
|
*/
|
||||||
|
public attacks?: Array<{
|
||||||
|
cost?: Array<string>
|
||||||
|
name: string
|
||||||
|
effect?: string
|
||||||
|
damage?: string | number
|
||||||
|
}>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pokemon Weaknesses
|
||||||
|
*/
|
||||||
|
public weaknesses?: Array<{
|
||||||
|
type: string
|
||||||
|
value?: string
|
||||||
|
}>
|
||||||
|
|
||||||
|
public resistances?: Array<{
|
||||||
|
type: string
|
||||||
|
value?: string
|
||||||
|
}>
|
||||||
|
|
||||||
|
public retreat?: number
|
||||||
|
|
||||||
|
// Trainer/Energy
|
||||||
|
public effect?: string
|
||||||
|
|
||||||
|
// Trainer Only
|
||||||
|
public trainerType?: string
|
||||||
|
|
||||||
|
// Energy Only
|
||||||
|
public energyType?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define the rotation mark on cards >= Sword & Shield
|
||||||
|
*/
|
||||||
|
public regulationMark?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Card ability to be played in official tournaments
|
||||||
|
*
|
||||||
|
* Note: all cards are avaialable to play in unlimited tournaments
|
||||||
|
*/
|
||||||
|
public legal!: {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ability to play in standard tournaments
|
||||||
|
*/
|
||||||
|
standard: boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ability to play in expanded tournaments
|
||||||
|
*/
|
||||||
|
expanded: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
public boosters?: Array<Booster>
|
||||||
|
|
||||||
|
public override async getCard(): Promise<Card> {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getSet(): Promise<TCGdexSet> {
|
||||||
|
return (await this.sdk.set.get(this.set.id))!
|
||||||
|
}
|
||||||
|
}
|
47
src/models/CardResume.ts
Normal file
47
src/models/CardResume.ts
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import type { Extension, Quality } from '../interfaces'
|
||||||
|
import type Card from './Card'
|
||||||
|
import Model from './Model'
|
||||||
|
|
||||||
|
export default class CardResume extends Model {
|
||||||
|
/**
|
||||||
|
* Globally unique card ID based on the set ID and the cards ID within the set
|
||||||
|
*/
|
||||||
|
public id!: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Card image url without the extension and quality
|
||||||
|
*
|
||||||
|
* @see {@link getImageURL}
|
||||||
|
*/
|
||||||
|
public image?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ID indexing this card within its set, usually just its number
|
||||||
|
*/
|
||||||
|
public localId!: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Card Name (Including the suffix if next to card name)
|
||||||
|
*/
|
||||||
|
public name!: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the the Card Image full URL
|
||||||
|
*
|
||||||
|
* @param {Quality} quality the quality you want your image to be in
|
||||||
|
* @param {Extension} extension extension you want you image to be
|
||||||
|
* @return the full card URL
|
||||||
|
*/
|
||||||
|
public getImageURL(quality: Quality = 'high', extension: Extension = 'png'): string {
|
||||||
|
return `${this.image}/${quality}.${extension}`
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the full Card
|
||||||
|
*
|
||||||
|
* @return the full card if available
|
||||||
|
*/
|
||||||
|
public async getCard(): Promise<Card> {
|
||||||
|
return (await this.sdk.card.get(this.id))!
|
||||||
|
}
|
||||||
|
}
|
28
src/models/Model.ts
Normal file
28
src/models/Model.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { objectLoop } from '@dzeio/object-util'
|
||||||
|
import type TCGdex from '../tcgdex'
|
||||||
|
|
||||||
|
export default abstract class Model {
|
||||||
|
|
||||||
|
public constructor(
|
||||||
|
protected readonly sdk: TCGdex
|
||||||
|
) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* build a model depending on the data given
|
||||||
|
* @param model the model to build
|
||||||
|
* @param data the data to fill it with
|
||||||
|
*/
|
||||||
|
public static build<T extends Model>(model: T, data?: object): T {
|
||||||
|
if (!data) {
|
||||||
|
throw new Error('data is necessary.')
|
||||||
|
}
|
||||||
|
model.fill(data)
|
||||||
|
return model
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fill(obj: object) {
|
||||||
|
objectLoop(obj, (value, key) => {
|
||||||
|
(this as object)[key] = value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
15
src/models/Other.d.ts
vendored
Normal file
15
src/models/Other.d.ts
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
export interface Variants {
|
||||||
|
normal?: boolean
|
||||||
|
reverse?: boolean
|
||||||
|
holo?: boolean
|
||||||
|
firstEdition?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Booster {
|
||||||
|
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
logo?: string
|
||||||
|
artwork_front?: string
|
||||||
|
artwork_back?: string
|
||||||
|
}
|
21
src/models/Serie.ts
Normal file
21
src/models/Serie.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { objectLoop } from '@dzeio/object-util'
|
||||||
|
import Model from './Model'
|
||||||
|
import SerieResume from './SerieResume'
|
||||||
|
import SetResume from './SetResume'
|
||||||
|
|
||||||
|
export default class Serie extends SerieResume {
|
||||||
|
public sets!: Array<SetResume>
|
||||||
|
|
||||||
|
protected fill(obj: object): void {
|
||||||
|
objectLoop(obj, (value, key) => {
|
||||||
|
switch (key) {
|
||||||
|
case 'sets':
|
||||||
|
this.sets = (value as Array<any>).map((it) => Model.build(new SetResume(this.sdk), it))
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
this[key] = value
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
24
src/models/SerieResume.ts
Normal file
24
src/models/SerieResume.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import type { Extension } from '../interfaces'
|
||||||
|
import Model from './Model'
|
||||||
|
import type Serie from './Serie'
|
||||||
|
|
||||||
|
export default class SerieResume extends Model {
|
||||||
|
public id!: string
|
||||||
|
public name!: string
|
||||||
|
public logo?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the the Card Image full URL
|
||||||
|
*
|
||||||
|
* @param {Quality} quality the quality you want your image to be in
|
||||||
|
* @param {Extension} extension extension you want you image to be
|
||||||
|
* @return the full card URL
|
||||||
|
*/
|
||||||
|
public getImageURL(extension: Extension = 'png'): string {
|
||||||
|
return `${this.logo}.${extension}`
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getSerie(): Promise<Serie> {
|
||||||
|
return (await this.sdk.serie.get(this.id))!
|
||||||
|
}
|
||||||
|
}
|
91
src/models/Set.ts
Normal file
91
src/models/Set.ts
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import { objectLoop } from '@dzeio/object-util'
|
||||||
|
import CardResume from './CardResume'
|
||||||
|
import Model from './Model'
|
||||||
|
import type { Booster, Variants } from './Other'
|
||||||
|
import type SerieResume from './SerieResume'
|
||||||
|
|
||||||
|
// biome-ignore lint/suspicious/noShadowRestrictedNames: <explanation>
|
||||||
|
export default class Set extends Model {
|
||||||
|
public id!: string
|
||||||
|
public name!: string
|
||||||
|
public logo?: string
|
||||||
|
public symbol?: string
|
||||||
|
public serie!: SerieResume
|
||||||
|
public tcgOnline?: string
|
||||||
|
public variants?: Variants
|
||||||
|
|
||||||
|
public releaseDate!: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Designate if the set is usable in tournaments
|
||||||
|
*
|
||||||
|
* Note: this is specific to the set and if a
|
||||||
|
* card is banned from the set it will still be true
|
||||||
|
*/
|
||||||
|
public legal!: {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ability to play in standard tournaments
|
||||||
|
*/
|
||||||
|
standard: boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ability to play in expanded tournaments
|
||||||
|
*/
|
||||||
|
expanded: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
public cardCount!: {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* total of number of cards
|
||||||
|
*/
|
||||||
|
total: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* number of cards officialy (on the bottom of each cards)
|
||||||
|
*/
|
||||||
|
official: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* number of cards having a normal version
|
||||||
|
*/
|
||||||
|
normal: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* number of cards having an reverse version
|
||||||
|
*/
|
||||||
|
reverse: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* number of cards having an holo version
|
||||||
|
*/
|
||||||
|
holo: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of possible cards
|
||||||
|
*/
|
||||||
|
firstEd?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
public cards!: Array<CardResume>
|
||||||
|
|
||||||
|
public boosters?: Array<Booster>
|
||||||
|
|
||||||
|
public async getSerie() {
|
||||||
|
return this.sdk.serie.get(this.serie.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fill(obj: object): void {
|
||||||
|
objectLoop(obj, (value, key) => {
|
||||||
|
switch (key) {
|
||||||
|
case 'cards':
|
||||||
|
this.cards = (value as Array<any>).map((it) => Model.build(new CardResume(this.sdk), it))
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
this[key] = value
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
25
src/models/SetResume.ts
Normal file
25
src/models/SetResume.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import Model from './Model'
|
||||||
|
import type TCGdexSet from './Set'
|
||||||
|
|
||||||
|
export default class SetResume extends Model {
|
||||||
|
public id!: string
|
||||||
|
public name!: string
|
||||||
|
public logo?: string
|
||||||
|
public symbol?: string
|
||||||
|
public cardCount!: {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* total of number of cards
|
||||||
|
*/
|
||||||
|
total: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* number of cards officialy (on the bottom of each cards)
|
||||||
|
*/
|
||||||
|
official: number
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getSet(): Promise<TCGdexSet> {
|
||||||
|
return (await this.sdk.set.get(this.id))!
|
||||||
|
}
|
||||||
|
}
|
21
src/models/StringEndpoint.ts
Normal file
21
src/models/StringEndpoint.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { objectLoop } from '@dzeio/object-util'
|
||||||
|
import CardResume from './CardResume'
|
||||||
|
import Model from './Model'
|
||||||
|
|
||||||
|
export default class StringEndpoint extends Model {
|
||||||
|
public name!: string
|
||||||
|
public cards!: Array<CardResume>
|
||||||
|
|
||||||
|
protected fill(obj: object): void {
|
||||||
|
objectLoop(obj, (value, key) => {
|
||||||
|
switch (key) {
|
||||||
|
case 'cards':
|
||||||
|
this.cards = (value as Array<any>).map((it) => Model.build(new CardResume(this.sdk), it))
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
this[key] = value
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,5 @@
|
|||||||
import TCGdex from './tcgdex'
|
import TCGdex from './tcgdex'
|
||||||
import unfetch from 'unfetch'
|
|
||||||
|
|
||||||
TCGdex.fetch = window.fetch ?? unfetch as any
|
TCGdex.fetch = window.fetch
|
||||||
|
|
||||||
if (typeof global !== 'undefined') {
|
export default TCGdex
|
||||||
global.TCGdex = TCGdex
|
|
||||||
}
|
|
||||||
if (typeof window !== 'undefined') {
|
|
||||||
(window as any).TCGdex = TCGdex
|
|
||||||
}
|
|
||||||
|
267
src/tcgdex.ts
267
src/tcgdex.ts
@ -1,24 +1,161 @@
|
|||||||
import RequestWrapper from './Request'
|
import type CacheInterface from '@cachex/core'
|
||||||
import { Serie, Set, Card, CardResume, SerieList, SetList, SupportedLanguages, StringEndpoint } from './interfaces'
|
import MemoryCache from '@cachex/memory'
|
||||||
type Endpoint = 'cards' | 'categories' | 'dex-ids' | 'energy-types' | 'hp' | 'illustrators' | 'rarities' | 'regulation-marks' | 'retreats' | 'series' | 'sets' | 'stages' | 'suffixes' | 'trainer-types' | 'types' | 'variants'
|
import LocalStorageCache from '@cachex/web-storage'
|
||||||
|
import Query from './Query'
|
||||||
|
import Endpoint from './endpoints/Endpoint'
|
||||||
|
import SimpleEndpoint from './endpoints/SimpleEndpoint'
|
||||||
|
import type {
|
||||||
|
Card,
|
||||||
|
CardResume,
|
||||||
|
Endpoints,
|
||||||
|
Serie,
|
||||||
|
SerieList,
|
||||||
|
SetList,
|
||||||
|
StringEndpoint,
|
||||||
|
SupportedLanguages,
|
||||||
|
Set as TCGdexSet
|
||||||
|
} from './interfaces'
|
||||||
|
import CardModel from './models/Card'
|
||||||
|
import CardResumeModel from './models/CardResume'
|
||||||
|
import Model from './models/Model'
|
||||||
|
import SerieModel from './models/Serie'
|
||||||
|
import SerieResume from './models/SerieResume'
|
||||||
|
import SetModel from './models/Set'
|
||||||
|
import SetResumeModel from './models/SetResume'
|
||||||
|
import StringEndpointModel from './models/StringEndpoint'
|
||||||
|
import { ENDPOINTS, detectContext } from './utils'
|
||||||
|
import { version } from './version'
|
||||||
|
|
||||||
const ENDPOINTS: Array<Endpoint> = ['cards', 'categories', 'dex-ids', 'energy-types', 'hp', 'illustrators', 'rarities', 'regulation-marks', 'retreats', 'series', 'sets', 'stages', 'suffixes', 'trainer-types', 'types', 'variants']
|
|
||||||
const BASE_URL = 'https://api.tcgdex.net/v2'
|
|
||||||
export default class TCGdex {
|
export default class TCGdex {
|
||||||
|
|
||||||
public static fetch: typeof fetch
|
/**
|
||||||
|
* How the remote data is going to be fetched
|
||||||
|
*/
|
||||||
|
public static fetch: typeof fetch = fetch
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated to change the lang use `this.lang`
|
* @deprecated to change the lang use {@link TCGdex.getLang} and {@link TCGdex.setLang}
|
||||||
*/
|
*/
|
||||||
public static defaultLang: SupportedLanguages = 'en'
|
public static defaultLang: SupportedLanguages = 'en'
|
||||||
|
|
||||||
public constructor(public lang?: SupportedLanguages) {}
|
/**
|
||||||
|
* the previously hidden caching system used by TCGdex to not kill the API
|
||||||
|
*/
|
||||||
|
public cache: CacheInterface =
|
||||||
|
detectContext() === 'browser' ? new LocalStorageCache('tcgdex-cache') : new MemoryCache()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the default cache TTL, only subsequent requests will have their ttl changed
|
||||||
|
*/
|
||||||
|
public cacheTTL = 60 * 60
|
||||||
|
|
||||||
|
// random card/set/serie endpoints
|
||||||
|
public readonly random = {
|
||||||
|
card: async (): Promise<CardModel> => {
|
||||||
|
const res = await this.fetch('random', 'card')
|
||||||
|
return Model.build(new CardModel(this), res)
|
||||||
|
},
|
||||||
|
set: async (): Promise<SetModel> => {
|
||||||
|
const res = await this.fetch('random', 'set')
|
||||||
|
return Model.build(new SetModel(this), res)
|
||||||
|
},
|
||||||
|
serie: async (): Promise<SerieModel> => {
|
||||||
|
const res = await this.fetch('random', 'serie')
|
||||||
|
return Model.build(new SerieModel(this), res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly card = new Endpoint(this, CardModel, CardResumeModel, 'cards')
|
||||||
|
public readonly set = new Endpoint(this, SetModel, SetResumeModel, 'sets')
|
||||||
|
public readonly serie = new Endpoint(this, SerieModel, SerieResume, 'series')
|
||||||
|
|
||||||
|
public readonly type = new SimpleEndpoint(this, StringEndpointModel, 'types')
|
||||||
|
public readonly retreat = new SimpleEndpoint(this, StringEndpointModel, 'retreats')
|
||||||
|
public readonly rarity = new SimpleEndpoint(this, StringEndpointModel, 'rarities')
|
||||||
|
public readonly illustrator = new SimpleEndpoint(this, StringEndpointModel, 'illustrators')
|
||||||
|
public readonly hp = new SimpleEndpoint(this, StringEndpointModel, 'hp')
|
||||||
|
public readonly categorie = new SimpleEndpoint(this, StringEndpointModel, 'categories')
|
||||||
|
public readonly dexID = new SimpleEndpoint(this, StringEndpointModel, 'dex-ids')
|
||||||
|
public readonly energyType = new SimpleEndpoint(this, StringEndpointModel, 'energy-types')
|
||||||
|
public readonly regulationMark = new SimpleEndpoint(this, StringEndpointModel, 'regulation-marks')
|
||||||
|
public readonly stage = new SimpleEndpoint(this, StringEndpointModel, 'stages')
|
||||||
|
public readonly suffixe = new SimpleEndpoint(this, StringEndpointModel, 'suffixes')
|
||||||
|
public readonly trainerType = new SimpleEndpoint(this, StringEndpointModel, 'trainer-types')
|
||||||
|
public readonly variant = new SimpleEndpoint(this, StringEndpointModel, 'variants')
|
||||||
|
|
||||||
|
private lang: SupportedLanguages = 'en'
|
||||||
|
private endpointURL = 'https://api.tcgdex.net/v2'
|
||||||
|
|
||||||
|
public constructor(lang: SupportedLanguages = 'en') {
|
||||||
|
this.setLang(lang)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use the constructor parameter or {@link TCGdex.setLang} when in an instance
|
||||||
|
*/
|
||||||
|
public static setDefaultLang(lang: SupportedLanguages) {
|
||||||
|
TCGdex.defaultLang = lang
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use {@link TCGdex.setLang} when in an instance
|
||||||
|
*/
|
||||||
|
public static getDefaultLang(): SupportedLanguages {
|
||||||
|
return TCGdex.defaultLang
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the endpoint URL
|
||||||
|
* ex: `https://api.tcgdex.net/v2`
|
||||||
|
* @param endpoint the url
|
||||||
|
*/
|
||||||
|
public setEndpoint(endpoint: string) {
|
||||||
|
this.endpointURL = endpoint
|
||||||
|
}
|
||||||
|
public getEndpoint(): string {
|
||||||
|
return this.endpointURL
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set the current cache methodology
|
||||||
|
* @param cache the cache to use
|
||||||
|
*/
|
||||||
|
public setCache(cache: CacheInterface) {
|
||||||
|
this.cache = cache
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the current cache methodology
|
||||||
|
* @param cache the cache to use
|
||||||
|
*/
|
||||||
|
public getCache(): CacheInterface {
|
||||||
|
return this.cache
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the endpoint URL
|
||||||
|
* ex: `https://api.tcgdex.net/v2`
|
||||||
|
* @param endpoint the url
|
||||||
|
*/
|
||||||
|
public setCacheTTL(seconds: number) {
|
||||||
|
this.cacheTTL = seconds
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* get the current useed cache ttl in seconds
|
||||||
|
* @returns the cache ttl in seconds
|
||||||
|
*/
|
||||||
|
public getCacheTTL(): number {
|
||||||
|
return this.cacheTTL
|
||||||
|
}
|
||||||
|
|
||||||
public getLang(): SupportedLanguages {
|
public getLang(): SupportedLanguages {
|
||||||
return this.lang ?? TCGdex.defaultLang ?? 'en'
|
return this.lang ?? TCGdex.defaultLang ?? 'en'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public setLang(lang: SupportedLanguages) {
|
||||||
|
this.lang = lang
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shortcut to easily fetch a card using both it's global id and it's local ID
|
* Shortcut to easily fetch a card using both it's global id and it's local ID
|
||||||
* @param id the card global/local ID
|
* @param id the card global/local ID
|
||||||
@ -47,7 +184,7 @@ export default class TCGdex {
|
|||||||
/**
|
/**
|
||||||
* @deprecated use `this.fetch('sets', set)`
|
* @deprecated use `this.fetch('sets', set)`
|
||||||
*/
|
*/
|
||||||
public async fetchSet(set: string): Promise<Set | undefined> {
|
public async fetchSet(set: string): Promise<TCGdexSet | undefined> {
|
||||||
return this.fetch('sets', set)
|
return this.fetch('sets', set)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +241,14 @@ export default class TCGdex {
|
|||||||
* @param endpoint_0 'sets'
|
* @param endpoint_0 'sets'
|
||||||
* @param endpoint_1 {string} the set name or ID
|
* @param endpoint_1 {string} the set name or ID
|
||||||
*/
|
*/
|
||||||
public async fetch(...endpoint: ['sets', string]): Promise<Set | undefined>
|
public async fetch(...endpoint: ['sets', string]): Promise<TCGdexSet | undefined>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch a random element
|
||||||
|
* @param endpoint_0 'random'
|
||||||
|
* @param endpoint_1 {'set' | 'card' | 'serie'} the type of random element you want to get
|
||||||
|
*/
|
||||||
|
public async fetch(...endpoint: ['random', 'set' | 'card' | 'serie']): Promise<Card | TCGdexSet | Serie | undefined>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch every sets
|
* Fetch every sets
|
||||||
@ -148,7 +292,7 @@ export default class TCGdex {
|
|||||||
* @param endpoint_1 {string} (Optionnal) some details to go from the index file to the item file (mostly the ID/name)
|
* @param endpoint_1 {string} (Optionnal) some details to go from the index file to the item file (mostly the ID/name)
|
||||||
* @param endpoint_2 {string} (Optionnal) only for sets the card local ID to fetch the card through the set
|
* @param endpoint_2 {string} (Optionnal) only for sets the card local ID to fetch the card through the set
|
||||||
*/
|
*/
|
||||||
public async fetch(...endpoint: Array<Endpoint | string>): Promise<any | undefined> {
|
public async fetch<T = object>(...endpoint: Array<Endpoints | string>): Promise<T | undefined> {
|
||||||
if (endpoint.length === 0) {
|
if (endpoint.length === 0) {
|
||||||
throw new Error('endpoint to fetch is empty!')
|
throw new Error('endpoint to fetch is empty!')
|
||||||
}
|
}
|
||||||
@ -157,29 +301,110 @@ export default class TCGdex {
|
|||||||
if (!ENDPOINTS.includes(baseEndpoint)) {
|
if (!ENDPOINTS.includes(baseEndpoint)) {
|
||||||
throw new Error(`unknown endpoint to fetch! (${baseEndpoint})`)
|
throw new Error(`unknown endpoint to fetch! (${baseEndpoint})`)
|
||||||
}
|
}
|
||||||
return this.makeRequest(baseEndpoint, ...endpoint)
|
return this.actualFetch<T>(this.getFullURL([baseEndpoint, ...endpoint]))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to make the request and normalize the whole path
|
* @param endpoint the endpoint to fetch
|
||||||
|
* @param query the query
|
||||||
*/
|
*/
|
||||||
private makeRequest<T = any>(...url: Array<string | number>) {
|
public async fetchWithQuery<T = object>(
|
||||||
|
endpoint: [Endpoints, ...Array<string>],
|
||||||
|
query?: Array<{ key: string, value: string | number | boolean }>
|
||||||
|
): Promise<T | undefined> {
|
||||||
|
if (endpoint.length === 0) {
|
||||||
|
throw new Error('endpoint to fetch is empty!')
|
||||||
|
}
|
||||||
|
const baseEndpoint = endpoint[0].toLowerCase() as Endpoints
|
||||||
|
if (!ENDPOINTS.includes(baseEndpoint)) {
|
||||||
|
throw new Error(`unknown endpoint to fetch! (${baseEndpoint})`)
|
||||||
|
}
|
||||||
|
return this.actualFetch<T>(this.getFullURL(endpoint, query))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* format the final URL
|
||||||
|
*/
|
||||||
|
private getFullURL(
|
||||||
|
url: Array<string | number>,
|
||||||
|
searchParams?: Array<{ key: string, value: string | number | boolean }>
|
||||||
|
): string {
|
||||||
// Normalize path
|
// Normalize path
|
||||||
const path = url.map((subPath) => encodeURI(
|
let path = url.map(this.encode).join('/')
|
||||||
subPath
|
|
||||||
|
// handle the Search Params
|
||||||
|
if (searchParams) {
|
||||||
|
path += '?' + searchParams.map((it) => `${this.encode(it.key)}=${this.encode(it.value)}`).join('&')
|
||||||
|
}
|
||||||
|
|
||||||
|
// return with the endpoint and all the shit
|
||||||
|
return `${this.getEndpoint()}/${this.getLang()}/${path}`
|
||||||
|
}
|
||||||
|
|
||||||
|
private async actualFetch<T = object>(path: string): Promise<T | undefined> {
|
||||||
|
// get and return the cached value if available
|
||||||
|
const cached = this.cache.get(path)
|
||||||
|
if (cached) {
|
||||||
|
return cached as T
|
||||||
|
}
|
||||||
|
|
||||||
|
// the actual Fetch :D
|
||||||
|
const resp = await TCGdex.fetch(path, {
|
||||||
|
headers: {
|
||||||
|
'user-agent': `@tcgdex/javascript-sdk/${version}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// throw if a server-side error is occured
|
||||||
|
if (resp.status >= 500) {
|
||||||
|
try {
|
||||||
|
const json = JSON.stringify(await resp.json())
|
||||||
|
throw new Error(json)
|
||||||
|
} catch {
|
||||||
|
throw new Error('TCGdex Server responded with an invalid error :(')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// response is not valid :O
|
||||||
|
if (resp.status !== 200) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse, put to cache and return
|
||||||
|
const json = await resp.json()
|
||||||
|
|
||||||
|
this.cache.set(path, json, this.cacheTTL)
|
||||||
|
return json as T
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* encode a string to be used in an url
|
||||||
|
* @param str the string to encode to URL
|
||||||
|
* @returns the encoded string
|
||||||
|
*/
|
||||||
|
private encode(str: string | number | boolean): string {
|
||||||
|
return encodeURI(
|
||||||
|
str
|
||||||
// Transform numbers to string
|
// Transform numbers to string
|
||||||
.toString()
|
.toString()
|
||||||
// replace this special character with an escaped one
|
// replace this special character with an escaped one
|
||||||
.replace('?', '%3F')
|
.replace('?', '%3F')
|
||||||
// normalize the string
|
// normalize the string
|
||||||
.normalize('NFC')
|
.normalize('NFC')
|
||||||
// remove some special chars by nothing
|
// remove some special chars
|
||||||
// eslint-disable-next-line no-misleading-character-class
|
// eslint-disable-next-line no-misleading-character-class
|
||||||
.replace(/["'\u0300-\u036f]/gu, '')
|
.replace(/["'\u0300-\u036f]/gu, '')
|
||||||
)).join('/')
|
)
|
||||||
return RequestWrapper.fetch<T>(`${BASE_URL}/${this.getLang()}/${path}`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export * from './interfaces'
|
// export the old interfaces
|
||||||
|
export type * from './interfaces.d.ts'
|
||||||
|
|
||||||
|
// export the new models items and the Query
|
||||||
|
export {
|
||||||
|
CardModel, CardResumeModel, Endpoint, Model, Query, SerieModel,
|
||||||
|
SerieResume as SerieResumeModel,
|
||||||
|
SetModel,
|
||||||
|
SetResumeModel, SimpleEndpoint
|
||||||
|
}
|
||||||
|
20
src/utils.ts
Normal file
20
src/utils.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import type { Endpoints } from './interfaces'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* detect the current running context ofthe program
|
||||||
|
*/
|
||||||
|
export function detectContext(): 'browser' | 'server' {
|
||||||
|
try {
|
||||||
|
const isBrowser = !!window
|
||||||
|
return isBrowser ? 'browser' : 'server'
|
||||||
|
} catch {
|
||||||
|
return 'server'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ENDPOINTS: ReadonlyArray<Endpoints> = [
|
||||||
|
'cards', 'categories', 'dex-ids', 'energy-types',
|
||||||
|
'hp', 'illustrators', 'rarities', 'regulation-marks',
|
||||||
|
'retreats', 'series', 'sets', 'stages', 'suffixes',
|
||||||
|
'trainer-types', 'types', 'variants', 'random'
|
||||||
|
] as const
|
@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "./tsconfig.json",
|
|
||||||
"include": ["./src/tcgdex.node.ts"],
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "ES2015", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
|
|
||||||
"module": "ES2015", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
|
|
||||||
"declaration": false, /* Generates corresponding '.d.ts' file. */
|
|
||||||
"declarationDir": null,
|
|
||||||
"outDir": "./dist/modules", /* Redirect output structure to the directory. */
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +1,10 @@
|
|||||||
{
|
{
|
||||||
"extends": "./node_modules/@dzeio/config/tsconfig.base",
|
"extends": "./node_modules/@dzeio/config/tsconfig.base",
|
||||||
"include": ["./src/tcgdex.node.ts"],
|
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"outDir": "dist",
|
||||||
"target": "ES2015",
|
"strictNullChecks": true
|
||||||
|
},
|
||||||
"declaration": true,
|
"exclude": [
|
||||||
"declarationDir": "./dist/types",
|
"__tests__"
|
||||||
|
]
|
||||||
"outDir": "./dist/cjs",
|
|
||||||
"rootDir": "./src",
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user