From 4469cbe61aa81b7585717cb2fc2db03586f5e5dd Mon Sep 17 00:00:00 2001 From: darthmaim Date: Fri, 10 Nov 2023 16:27:49 +0100 Subject: [PATCH] Add some test types --- .editorconfig | 18 +++ .gitignore | 1 + package-lock.json | 39 +++++ package.json | 11 ++ packages/types/data.d.ts | 296 ++++++++++++++++++++++++++++++++++ packages/types/endpoints.d.ts | 203 +++++++++++++++++++++++ packages/types/index.d.ts | 2 + packages/types/package.json | 26 +++ packages/types/tsconfig.json | 6 + 9 files changed, 602 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 packages/types/data.d.ts create mode 100644 packages/types/endpoints.d.ts create mode 100644 packages/types/index.d.ts create mode 100644 packages/types/package.json create mode 100644 packages/types/tsconfig.json diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f8f9235 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = false +insert_final_newline = false + +[{*.ts,*.json,*.yml}] +indent_size = 2 +indent_style = space +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +insert_final_newline = true +indent_style = space +indent_size = 2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..b198c0a --- /dev/null +++ b/package-lock.json @@ -0,0 +1,39 @@ +{ + "name": "gw2api", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "gw2api", + "workspaces": [ + "packages/*" + ], + "devDependencies": {} + }, + "node_modules/@gw2api/types": { + "resolved": "packages/types", + "link": true + }, + "node_modules/typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "packages/types": { + "name": "@gw2api/types", + "version": "0.0.1", + "license": "MIT", + "devDependencies": { + "typescript": "^5.2.2" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..ca81622 --- /dev/null +++ b/package.json @@ -0,0 +1,11 @@ +{ + "name": "gw2api", + "private": true, + "workspaces": [ + "packages/*" + ], + "scripts": { + "test": "npm test -w @gw2api/types" + }, + "devDependencies": {} +} diff --git a/packages/types/data.d.ts b/packages/types/data.d.ts new file mode 100644 index 0000000..1e0b4aa --- /dev/null +++ b/packages/types/data.d.ts @@ -0,0 +1,296 @@ +export namespace Gw2Api { + export type Item = { + chat_link: string; + default_skin?: number; + description?: string; + details?: { + apply_count?: number; + attribute_adjustment?: number; + bonuses?: string[]; + charges?: number; + color_id?: number; + damage_type?: 'Choking' | 'Physical' | 'Ice' | 'Fire' | 'Lightning'; + defense?: number; + description?: string; + duration_ms?: number; + extra_recipe_ids?: number[]; + flags?: string[]; + guild_upgrade_id?: number; + icon?: string; + infix_upgrade?: { + attributes: { + attribute: 'Power' | 'Precision' | 'Toughness' | 'Vitality' | 'ConditionDamage' | 'CritDamage' | 'Healing' | 'BoonDuration' | 'ConditionDuration' | 'AgonyResistance'; + modifier: number; + }[]; + buff?: { + description?: string; + skill_id: number; + }; + id: number; + }; + infusion_slots?: { + flags?: string[]; + item_id?: number; + }[]; + infusion_upgrade_flags?: string[]; + max_power?: number; + min_power?: number; + minipet_id?: number; + name?: string; + no_sell_or_sort?: boolean; + recipe_id?: number; + secondary_suffix_item_id?: number; + size?: number; + skins?: number[]; + stat_choices?: number[]; + suffix?: string; + suffix_item_id?: number; + type?: 'Axe' | 'SmallBundle' | 'Hammer' | 'Generic' | 'Staff' | 'Coat' | 'Leggings' | 'Boots' | 'Helm' | 'Shoulders' | 'Gloves' | 'HelmAquatic' | 'LargeBundle' | 'Immediate' | 'Transmutation' | 'Utility' | 'Booze' | 'Food' | 'Default' | 'Unlock' | 'GiftBox' | 'Amulet' | 'Accessory' | 'Ring' | 'Trident' | 'Scepter' | 'Focus' | 'ShortBow' | 'Warhorn' | 'Torch' | 'LongBow' | 'Pistol' | 'Rifle' | 'Speargun' | 'Dagger' | 'Sword' | 'Mace' | 'Shield' | 'Greatsword' | 'Harpoon' | 'ContainerKey' | 'Salvage' | 'Halloween' | 'ContractNpc' | 'OpenUI' | 'UpgradeRemoval' | 'RentableContractNpc' | 'Foraging' | 'Logging' | 'Mining' | 'Gem' | 'Sigil' | 'Rune' | 'AppearanceChange' | 'UnlimitedConsumable' | 'Toy' | 'ToyTwoHanded' | 'TeleportToFriend' | 'Currency' | 'RandomUnlock' | 'MountRandomUnlock' | 'Bait' | 'Lure'; + unlock_type?: 'CraftingRecipe' | 'Content' | 'BagSlot' | 'BankTab' | 'Dye' | 'CollectibleCapacity' | 'Outfit' | 'GliderSkin' | 'SharedSlot' | 'Champion' | 'Minipet' | 'Ms' | 'GearLoadoutTab' | 'BuildLibrarySlot' | 'BuildLoadoutTab' | 'JadeBotSkin'; + vendor_ids?: number[]; + weight_class?: 'Clothing' | 'Light' | 'Medium' | 'Heavy'; + }; + flags: string[]; + game_types: string[]; + icon?: string; + id: number; + level: number; + name: string; + rarity: 'Basic' | 'Fine' | 'Masterwork' | 'Exotic' | 'Rare' | 'Legendary' | 'Junk' | 'Ascended'; + restrictions: string[]; + type: 'Weapon' | 'Consumable' | 'Back' | 'Armor' | 'Trophy' | 'Container' | 'Gizmo' | 'Bag' | 'CraftingMaterial' | 'Trinket' | 'Tool' | 'MiniPet' | 'UpgradeComponent' | 'Gathering' | 'Key' | 'JadeTechModule' | 'PowerCore'; + upgrades_from?: { + item_id: number; + upgrade: 'Infusion' | 'Attunement'; + }[]; + upgrades_into?: { + item_id: number; + upgrade: 'Infusion' | 'Attunement'; + }[]; + vendor_value: number; + }; + + export namespace Commerce { + export type Price = { + id: number; + whitelisted: boolean; + buys: { quantity: number; unit_price: number; } | undefined + sells: { quantity: number; unit_price: number; } | undefined + } + } + + export type Skill = { + attunement?: 'Water' | 'Air' | 'Fire' | 'Earth'; + bundle_skills?: number[]; + categories?: string[]; + chat_link: string; + cost?: number; + description: string; + dual_attunement?: 'Earth' | 'Water' | 'Air'; + dual_wield?: 'Dagger' | 'Pistol' | 'None' | 'Nothing'; + facts?: { + apply_count?: number; + chance?: number; + description?: string; + distance?: number; + dmg_multiplier?: number; + duration: number; + field_type?: 'Ethereal' | 'Water' | 'Fire' | 'Ice' | 'Lightning' | 'Smoke' | 'Light' | 'Poison' | 'Dark'; + finisher_type?: 'Leap' | 'Projectile' | 'Whirl' | 'Blast'; + hit_count?: number; + icon: string; + percent?: number; + prefix?: { + description?: string; + icon: string; + status?: string; + text: string; + }; + status?: string; + target?: 'Healing' | 'Precision' | 'Vitality' | 'Power'; + text: string; + type: 'Range' | 'Damage' | 'Number' | 'Distance' | 'ComboField' | 'ComboFinisher' | 'Buff' | 'AttributeAdjust' | 'Recharge' | 'Time' | 'Unblockable' | 'Radius' | 'Duration' | 'Percent' | 'StunBreak' | 'PrefixedBuff' | 'NoData' | 'HealingAdjust'; + value: number | boolean; + }[]; + flags: string[]; + flip_skill?: number; + icon?: string; + id: number; + initiative?: number; + name: string; + next_chain?: number; + prev_chain?: number; + professions?: string[]; + slot?: 'Profession_2' | 'Downed_4' | 'Weapon_3' | 'Weapon_1' | 'Weapon_5' | 'Profession_1' | 'Profession_3' | 'Profession_4' | 'Weapon_2' | 'Weapon_4' | 'Utility' | 'Heal' | 'Downed_1' | 'Downed_3' | 'Elite' | 'Downed_2' | 'Toolbelt' | 'Transform_1' | 'Pet' | 'Profession_5'; + specialization?: number; + subskills?: { + attunement: 'Fire' | 'Earth' | 'Air' | 'Water'; + form?: 'CelestialAvatar'; + id: number; + }[]; + toolbelt_skill?: number; + traited_facts?: { + apply_count?: number; + description?: string; + distance?: number; + dmg_multiplier?: number; + duration: number; + hit_count?: number; + icon: string; + overrides: number; + percent?: number; + prefix?: { + description?: string; + icon: string; + status?: string; + text: string; + }; + requires_trait: number; + status?: string; + target?: 'Power' | 'Healing'; + text: string; + type: 'Buff' | 'Number' | 'Distance' | 'Time' | 'PrefixedBuff' | 'Duration' | 'Percent' | 'Damage' | 'NoData' | 'AttributeAdjust'; + value?: number; + }[]; + transform_skills?: number[]; + type?: 'Profession' | 'Weapon' | 'Utility' | 'Heal' | 'Elite' | 'Bundle' | 'Toolbelt' | 'Monster' | 'Transform' | 'Pet'; + weapon_type?: 'None' | 'Dagger' | 'Focus' | 'Staff' | 'Scepter' | 'Sword' | 'Trident' | 'Pistol' | 'Rifle' | 'Shield' | 'Speargun' | 'Greatsword' | 'Mace' | 'Torch' | 'Hammer' | 'Spear' | 'Axe' | 'Warhorn' | 'Shortbow' | 'Longbow'; + }; + + export type Skin = { + description?: string; + details?: { + damage_type?: 'Physical' | 'Choking' | 'Fire' | 'Lightning' | 'Ice'; + dye_slots?: { + default: DyeSlot[]; + overrides: { + AsuraFemale?: DyeSlot[]; + AsuraMale?: DyeSlot[]; + CharrFemale?: DyeSlot[]; + CharrMale?: DyeSlot[]; + HumanFemale?: DyeSlot[]; + HumanMale?: DyeSlot[]; + NornFemale?: DyeSlot[]; + NornMale?: { + color_id: number; + material: 'metal' | 'leather' | 'cloth'; + }[]; + SylvariFemale?: DyeSlot[]; + SylvariMale?: null[]; + }; + }; + type: 'Leggings' | 'Coat' | 'Boots' | 'Gloves' | 'Shoulders' | 'Helm' | 'HelmAquatic' | 'Foraging' | 'Logging' | 'Mining' | 'LargeBundle' | 'Rifle' | 'SmallBundle' | 'Toy' | 'ToyTwoHanded' | 'Axe' | 'Staff' | 'Hammer' | 'Pistol' | 'Longbow' | 'Dagger' | 'Sword' | 'Shortbow' | 'Focus' | 'Torch' | 'Spear' | 'Mace' | 'Speargun' | 'Greatsword' | 'Scepter' | 'Warhorn' | 'Shield' | 'Trident' | 'Lure' | 'Bait' | 'Fishing'; + weight_class?: 'Heavy' | 'Light' | 'Medium' | 'Clothing'; + }; + flags: string[]; + icon?: string; + id: number; + name: string; + rarity: 'Basic' | 'Masterwork' | 'Legendary' | 'Rare' | 'Exotic' | 'Ascended'; + restrictions: string[]; + type: 'Armor' | 'Back' | 'Gathering' | 'Weapon'; + }; + + type DyeSlot = { + color_id: number; + material: 'leather' | 'cloth' | 'metal'; + } + + export type Recipe = { + chat_link: string; + disciplines: string[]; + flags: string[]; + id: number; + ingredients: { + count: number; + id: number; + type: 'Item' | 'GuildUpgrade' | 'Currency'; + }[]; + min_rating: number; + output_item_count: number; + output_item_id: number; + output_upgrade_id?: number; + time_to_craft_ms: number; + type: 'Refinement' | 'Insignia' | 'Inscription' | 'Shoulders' | 'Boots' | 'Gloves' | 'Coat' | 'Helm' | 'Leggings' | 'Component' | 'UpgradeComponent' | 'Bag' | 'Bulk' | 'Snack' | 'Seasoning' | 'IngredientCooking' | 'Soup' | 'Meal' | 'Dessert' | 'Feast' | 'Dye' | 'Amulet' | 'Ring' | 'Earring' | 'Staff' | 'Trident' | 'Scepter' | 'Focus' | 'Potion' | 'Consumable' | 'Rifle' | 'Warhorn' | 'LongBow' | 'ShortBow' | 'Torch' | 'Speargun' | 'Pistol' | 'Shield' | 'Harpoon' | 'Sword' | 'Axe' | 'Dagger' | 'Greatsword' | 'Hammer' | 'Mace' | 'RefinementObsidian' | 'RefinementEctoplasm' | 'Backpack' | 'GuildDecoration' | 'LegendaryComponent' | 'GuildConsumableWvw' | 'GuildConsumable'; + }; + + export type Achievement = { + bits?: { + id: number; + text: string; + type: 'Item' | 'Skin' | 'Text' | 'Minipet'; + }[]; + description: string; + flags: string[]; + icon?: string; + id: number; + locked_text: string; + name: string; + point_cap?: number; + prerequisites?: number[]; + requirement: string; + rewards?: { + count?: number; + id: number; + region?: 'Maguuma' | 'Tundra' | 'Unknown' | 'Desert' | 'Tyria'; + type: 'Item' | 'Mastery' | 'Title' | 'Coins'; + }[]; + tiers: { + count: number; + points: number; + }[]; + type: 'Default' | 'ItemSet'; + }; + + export namespace Achievement { + export type Group = { + categories: number[]; + description: string; + id: string; + name: string; + order: number; + }; + + export type Category = { + achievements: { + flags?: string[]; + id: number; + level?: number[]; + required_access?: { + condition: 'NoAccess' | 'HasAccess'; + product: 'PathOfFire' | 'HeartOfThorns'; + }; + }[]; + description: string; + icon: string; + id: number; + name: string; + order: number; + tomorrow?: { + flags: string[]; + id: number; + level?: number[]; + required_access?: { + condition: 'NoAccess' | 'HasAccess'; + product: 'PathOfFire' | 'HeartOfThorns'; + }; + }[]; + }; + } + + export type Currency = { + id: number; + name: string; + description: string; + order: number; + icon: string; + } + + export type Title = { + id: number; + name: string; + achievement?: number; + achievements?: number[]; + ap_required?: number; + } +} diff --git a/packages/types/endpoints.d.ts b/packages/types/endpoints.d.ts new file mode 100644 index 0000000..6ec7909 --- /dev/null +++ b/packages/types/endpoints.d.ts @@ -0,0 +1,203 @@ +import type { Gw2Api } from './data'; + +export type KnwownAuthorizedEndpoints = + | '/v2/account' + | '/v2/account/achievements' + | '/v2/account/bank' + | '/v2/account/buildstorage' + | '/v2/account/dailycrafting' + | '/v2/account/dungeons' + | '/v2/account/dyes' + | '/v2/account/emotes' + | '/v2/account/finishers' + | '/v2/account/gliders' + | '/v2/account/home/cats' + | '/v2/account/home/nodes' + | '/v2/account/inventory' + | '/v2/account/jadebots' + | '/v2/account/legendaryarmory' + | '/v2/account/luck' + | '/v2/account/mail' + | '/v2/account/mailcarriers' + | '/v2/account/mapchests' + | '/v2/account/masteries' + | '/v2/account/mastery/points' + | '/v2/account/materials' + | '/v2/account/minis' + | '/v2/account/mounts/skins' + | '/v2/account/mounts/types' + | '/v2/account/novelties' + | '/v2/account/outfits' + | '/v2/account/progression' + | '/v2/account/pvp/heroes' + | '/v2/account/raids' + | '/v2/account/recipes' + | '/v2/account/skiffs' + | '/v2/account/skins' + | '/v2/account/titles' + | '/v2/account/wallet' + | '/v2/account/worldbosses' + | '/v2/characters' + | `/v2/characters/${string}/backstory` + | `/v2/characters/${string}/buildtabs` + | `/v2/characters/${string}/buildtabs/active` + | `/v2/characters/${string}/core` + | `/v2/characters/${string}/crafting` + | `/v2/characters/${string}/dungeons` + | `/v2/characters/${string}/equipment` + | `/v2/characters/${string}/equipmenttabs` + | `/v2/characters/${string}/equipmenttabs/active` + | `/v2/characters/${string}/heropoints` + | `/v2/characters/${string}/inventory` + | `/v2/characters/${string}/quests` + | `/v2/characters/${string}/recipes` + | `/v2/characters/${string}/sab` + | `/v2/characters/${string}/skills` + | `/v2/characters/${string}/specializations` + | `/v2/characters/${string}/training` + | '/v2/commerce/delivery' + | '/v2/commerce/transactions' + | '/v2/createsubtoken' + | `/v2/guild/${string}` + | `/v2/guild/${string}/log` + | `/v2/guild/${string}/members` + | `/v2/guild/${string}/ranks` + | `/v2/guild/${string}/stash` + | `/v2/guild/${string}/storage` + | `/v2/guild/${string}/teams` + | `/v2/guild/${string}/treasury` + | `/v2/guild/${string}/upgrades` + | '/v2/pvp/games' + | '/v2/pvp/standings' + | '/v2/pvp/stats' + | '/v2/tokeninfo' + +export type KnownUnauthorizedEndpoints = + | '/v2/account/home' + | '/v2/account/mounts' + | '/v2/achievements' + | '/v2/achievements/categories' + | '/v2/achievements/daily' + | '/v2/achievements/daily/tomorrow' + | '/v2/achievements/groups' + | '/v2/adventures' + | `/v2/adventures/${string}/leaderboards` + | `/v2/adventures/${string}/leaderboards/:board/:region` + | '/v2/backstory/answers' + | '/v2/backstory/questions' + | '/v2/build' + | '/v2/colors' + | '/v2/commerce/exchange' + | '/v2/commerce/listings' + | '/v2/commerce/prices' + | '/v2/continents' + | '/v2/currencies' + | '/v2/dailycrafting' + | '/v2/dungeons' + | '/v2/emblem' + | '/v2/emotes' + | '/v2/events' + | '/v2/events-state' + | '/v2/files' + | '/v2/finishers' + | '/v2/gemstore/catalog' + | '/v2/gliders' + | '/v2/guild/permissions' + | '/v2/guild/search' + | '/v2/guild/upgrades' + | '/v2/home' + | '/v2/home/cats' + | '/v2/home/nodes' + | '/v2/items' + | '/v2/itemstats' + | '/v2/jadebots' + | '/v2/legendaryarmory' + | '/v2/legends' + | '/v2/mailcarriers' + | '/v2/mapchests' + | '/v2/maps' + | '/v2/masteries' + | '/v2/materials' + | '/v2/minis' + | '/v2/mounts' + | '/v2/mounts/skins' + | '/v2/mounts/types' + | '/v2/novelties' + | '/v2/outfits' + | '/v2/pets' + | '/v2/professions' + | '/v2/pvp' + | '/v2/pvp/amulets' + | '/v2/pvp/heroes' + | '/v2/pvp/ranks' + | '/v2/pvp/rewardtracks' + | '/v2/pvp/runes' + | '/v2/pvp/seasons' + | `/v2/pvp/seasons/${string}/leaderboards` + | `/v2/pvp/seasons/${string}/leaderboards/${string}/${string}` + | '/v2/pvp/sigils' + | '/v2/quaggans' + | '/v2/quests' + | '/v2/races' + | '/v2/raids' + | '/v2/recipes' + | '/v2/recipes/search' + | '/v2/skiffs' + | '/v2/skills' + | '/v2/skins' + | '/v2/specializations' + | '/v2/stories' + | '/v2/stories/seasons' + | '/v2/titles' + | '/v2/traits' + | '/v2/vendors' + | '/v2/worldbosses' + | '/v2/worlds' + | '/v2/wvw/abilities' + | '/v2/wvw/matches' + | '/v2/wvw/matches/overview' + | '/v2/wvw/matches/scores' + | '/v2/wvw/matches/stats' + | `/v2/wvw/matches/stats/${string}/guilds/${string}` + | `/v2/wvw/matches/stats/${string}/teams/${string}/top/kdr` + | `/v2/wvw/matches/stats/${string}/teams/${string}/top/kills` + | '/v2/wvw/objectives' + | '/v2/wvw/ranks' + | '/v2/wvw/rewardtracks' + | '/v2/wvw/upgrades' + +export type KnownBulkExpandedEndpoints = + | '/v2/items' + +export type KnwownEndpoints = KnwownAuthorizedEndpoints | KnownUnauthorizedEndpoints | KnownBulkExpandedEndpoints; + +// helper types for parameters +type CommonParameters = CombineParameters<`lang=${'de'|'en'|'es'|'fr'}`, `v=${string}`>; +type CombineParameters = P1 | P2 | `${P1}&${P2}` | `${P2}&${P1}`; + +type WithParameters = Parameters extends undefined + ? Url | `${Url}?${CommonParameters}` + : `${Url}?${Parameters | CombineParameters}`; + +type PageParameters = `page=${number}` | CombineParameters<`page=${number}`, `page_size=${number}`>; + +// helper types for bulk requests +type BulkExpandedIdListEndpointUrl = WithParameters; +type BulkExpandedSingleEndpointUrl = WithParameters<`${Endpoint}/${Id}`> | WithParameters +type BulkExpandedManyEndpointUrl = WithParameters +type BulkExpandedEndpointUrl = BulkExpandedIdListEndpointUrl | BulkExpandedSingleEndpointUrl | BulkExpandedManyEndpointUrl + +type BulkExpandedResponseType = + Url extends BulkExpandedIdListEndpointUrl ? Id[] : + Url extends BulkExpandedSingleEndpointUrl ? T : + Url extends BulkExpandedManyEndpointUrl ? T[] : + unknown + +export type EndpointType = + T extends BulkExpandedEndpointUrl<'/v2/items'> ? BulkExpandedResponseType<'/v2/items', T, Gw2Api.Item> : + T extends '/v2/quaggans' ? string[] : + T extends `/v2/characters?ids=${number}` ? { name: string }[] : + T extends '/v2/characters' ? string[] : + unknown; + +type ValidateEndpointUrl = unknown extends EndpointType ? 'unknown endpoint url' : T; diff --git a/packages/types/index.d.ts b/packages/types/index.d.ts new file mode 100644 index 0000000..1348cdd --- /dev/null +++ b/packages/types/index.d.ts @@ -0,0 +1,2 @@ +export * from './data'; +export * from './endpoints'; diff --git a/packages/types/package.json b/packages/types/package.json new file mode 100644 index 0000000..0a32faf --- /dev/null +++ b/packages/types/package.json @@ -0,0 +1,26 @@ +{ + "name": "@gw2api/types", + "version": "0.0.1", + "description": "TypeScript types for all datastructures used by the Guild Wars 2 API", + "license": "MIT", + "main": "", + "types": "index.d.ts", + "repository": { + "type": "git", + "url": "git+https://github.com/darthmaim/gw2api.git", + "directory": "packages/types" + }, + "keywords": [ + "gw2api", + "types", + "gw2", + "api", + "typescript" + ], + "scripts": { + "test": "tsc" + }, + "devDependencies": { + "typescript": "^5.2.2" + } +} diff --git a/packages/types/tsconfig.json b/packages/types/tsconfig.json new file mode 100644 index 0000000..86f6023 --- /dev/null +++ b/packages/types/tsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "noEmit": true + }, + "exclude": ["node_modules"] +}