diff --git a/bun.lockb b/bun.lockb index 261ba835..c065b399 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/dist/index.css b/dist/index.css index 0b61dd0a..bc1a3f9a 100644 --- a/dist/index.css +++ b/dist/index.css @@ -506,10 +506,12 @@ body[showing-chat] #chat-page-wrapper { height: var(--ribbon-size); overflow-x: auto; padding: 0px; + overflow-y: hidden; } #chat-page > div > #main > div > .pane-wrapper > .pane > .toolbar > span { display: flex; align-items: center; + overflow-y: hidden; } #chat-page > div > #main > div > .pane-wrapper > .pane > .toolbar > span.title { padding-left: var(--content-padding); diff --git a/dist/index.js b/dist/index.js index 095294bd..5c69824b 100644 --- a/dist/index.js +++ b/dist/index.js @@ -357,8 +357,7 @@ updateButton: (version) => `Update to ${version}`, /// typeChat: "chat", - addChatPlaceholder: "Add chat", - addChatButton: "Add chat" + noChatsPlaceholder: "No chats" }, settings: { pages: { @@ -478,6 +477,7 @@ encryptionKeyLabel: "Encryption key", setEncryptionKeyButtonAudioLabel: "set encryption key", showEncryptionKey: "Show encryption key", + randomizeKey: "Randomize", setColorButtonAudioLabel: "set color", deleteChatButton: "Delete entire chat" }, @@ -628,8 +628,7 @@ transferDataButton: "Daten \xFCbertragen", updateButton: (version) => `Aktualisieren: ${version}`, typeChat: "Chat", - addChatPlaceholder: "Chat hinzuf\xFCgen", - addChatButton: "Chat hinzuf\xFCgen" + noChatsPlaceholder: "Keine Chats" }, settings: { pages: { @@ -743,6 +742,7 @@ encryptionKeyLabel: "Schl\xFCssel", setEncryptionKeyButtonAudioLabel: "Schl\xFCssel festlegen", showEncryptionKey: "Schl\xFCssel anzeigen", + randomizeKey: "Zuf\xE4llig generieren", setColorButtonAudioLabel: "Farbe festlegen", deleteChatButton: "Gesamten Chat l\xF6schen" }, @@ -880,8 +880,7 @@ transferDataButton: "Enviar o exportar archivos", updateButton: (version) => `Actualizar a ${version}`, typeChat: "chat", - addChatPlaceholder: "A\xF1adir chat", - addChatButton: "A\xF1adir chat" + noChatsPlaceholder: "No hay chats" }, settings: { pages: { @@ -995,6 +994,7 @@ encryptionKeyLabel: "Clave de encriptaci\xF3n", setEncryptionKeyButtonAudioLabel: "establecer clave de encriptaci\xF3n", showEncryptionKey: "Mostrar clave de encriptaci\xF3n", + randomizeKey: "Aleatorizar", setColorButtonAudioLabel: "establecer color", deleteChatButton: "Eliminar todo el chat" }, @@ -2966,9 +2966,144 @@ } }; + // node_modules/uint8array-extras/index.js + var objectToString = Object.prototype.toString; + var uint8ArrayStringified = "[object Uint8Array]"; + var arrayBufferStringified = "[object ArrayBuffer]"; + function isType(value, typeConstructor, typeStringified) { + if (!value) { + return false; + } + if (value.constructor === typeConstructor) { + return true; + } + return objectToString.call(value) === typeStringified; + } + function isUint8Array(value) { + return isType(value, Uint8Array, uint8ArrayStringified); + } + function isArrayBuffer(value) { + return isType(value, ArrayBuffer, arrayBufferStringified); + } + function isUint8ArrayOrArrayBuffer(value) { + return isUint8Array(value) || isArrayBuffer(value); + } + function toUint8ArrayIfArrayBuffer(value) { + return isArrayBuffer(value) ? new Uint8Array(value) : value; + } + function assertUint8ArrayOrArrayBuffer(value) { + if (!isUint8ArrayOrArrayBuffer(value)) { + throw new TypeError(`Expected \`Uint8Array\` or \`ArrayBuffer\`, got \`${typeof value}\``); + } + } + var cachedDecoders = { + utf8: new globalThis.TextDecoder("utf8") + }; + var cachedEncoder = new globalThis.TextEncoder(); + function base64ToBase64Url(base64) { + return base64.replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/, ""); + } + var MAX_BLOCK_SIZE = 65535; + function uint8ArrayToBase64(array, { urlSafe = false } = {}) { + assertUint8ArrayOrArrayBuffer(array); + array = toUint8ArrayIfArrayBuffer(array); + let base64 = ""; + for (let index = 0; index < array.length; index += MAX_BLOCK_SIZE) { + const chunk = array.subarray(index, index + MAX_BLOCK_SIZE); + base64 += globalThis.btoa(String.fromCodePoint.apply(void 0, chunk)); + } + return urlSafe ? base64ToBase64Url(base64) : base64; + } + var byteToHexLookupTable = Array.from({ length: 256 }, (_, index) => index.toString(16).padStart(2, "0")); + function uint8ArrayToHex(array) { + assertUint8ArrayOrArrayBuffer(array); + array = toUint8ArrayIfArrayBuffer(array); + let hexString = ""; + for (let index = 0; index < array.length; index++) { + hexString += byteToHexLookupTable[array[index]]; + } + return hexString; + } + + // node_modules/crypto-random-string/index.js + var maxBytesPerRequest = 65536; + var maxCharacterSetSize = 65536; + function fillWithRandomValues(typedArray) { + const maxElementsPerRequest = maxBytesPerRequest / typedArray.BYTES_PER_ELEMENT; + for (let offset = 0; offset < typedArray.length; offset += maxElementsPerRequest) { + crypto.getRandomValues(typedArray.subarray(offset, offset + maxElementsPerRequest)); + } + return typedArray; + } + var randomBytes = (byteLength) => fillWithRandomValues(new Uint8Array(byteLength)); + var generateForCustomCharacters = (length, characters) => { + const characterCount = characters.length; + const validSelectorCount = Math.floor(maxCharacterSetSize / characterCount) * characterCount; + const entropyLength = Math.ceil(1.1 * length * (maxCharacterSetSize / validSelectorCount)); + let string = ""; + let stringLength = 0; + while (stringLength < length) { + const entropy = fillWithRandomValues(new Uint16Array(entropyLength)); + for (let index = 0; index < entropyLength; index++) { + const entropyValue = entropy[index]; + if (entropyValue < validSelectorCount) { + string += characters[entropyValue % characterCount]; + stringLength++; + if (stringLength === length) { + return string; + } + } + } + } + return string; + }; + var characterSets = /* @__PURE__ */ new Map([ + ["url-safe", [..."abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~"]], + ["numeric", [..."0123456789"]], + ["distinguishable", [..."CDEHKMPRTUWXY012458"]], + ["ascii-printable", [..."!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"]], + ["alphanumeric", [..."ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"]] + ]); + var allowedTypes = /* @__PURE__ */ new Set(["hex", "base64", ...characterSets.keys()]); + function cryptoRandomString({ length, type, characters }) { + if (!Number.isSafeInteger(length) || length < 0) { + throw new TypeError("Expected `length` to be a non-negative integer"); + } + if (type !== void 0 && characters !== void 0) { + throw new TypeError("Expected either `type` or `characters`"); + } + if (characters !== void 0) { + if (typeof characters !== "string") { + throw new TypeError("Expected `characters` to be a string"); + } + const customCharacterSet = [...characters]; + if (customCharacterSet.length === 0) { + throw new TypeError("Expected `characters` to contain at least 1 character"); + } + if (customCharacterSet.length > maxCharacterSetSize) { + throw new TypeError(`Expected \`characters\` to contain at most ${maxCharacterSetSize} characters, got ${customCharacterSet.length}`); + } + return generateForCustomCharacters(length, customCharacterSet); + } + if (type !== void 0 && !allowedTypes.has(type)) { + throw new TypeError(`Unknown type: ${type}`); + } + const characterSet = characterSets.get(type); + if (characterSet !== void 0) { + return generateForCustomCharacters(length, characterSet); + } + if (type === "base64") { + return uint8ArrayToBase64(randomBytes(Math.ceil(length * 0.75))).slice(0, length); + } + return uint8ArrayToHex(randomBytes(Math.ceil(length * 0.5))).slice(0, length); + } + // src/Model/Utility/crypto.ts var IV_SIZE = 12; var ENCRYPTION_ALG = "AES-GCM"; + function random(length) { + return cryptoRandomString({ length }); + } async function encryptString(plaintext, passphrase) { if (!window.crypto.subtle) return plaintext; const iv = generateIV(); @@ -4090,6 +4225,7 @@ }; this.clear = () => { this.searchInput.value = ""; + this.applySearch(); }; this.deleteSuggestion = (suggestion) => { this.suggestions.remove(suggestion); @@ -4273,6 +4409,9 @@ const index = this.taskPageViewModel.boardIndexManager.getIndex(this); this.index.value = index; }; + this.resetPinchZoom = () => { + this.pinchToZoomData.value = { x: 0, y: 0, zoom: 1 }; + }; // load this.preloadData = () => { this.name.value = this.boardInfo.name; @@ -4321,27 +4460,6 @@ this.taskPageViewModel.storeLastUsedBoard(); }; this.preloadData(); - this.isSelected = createProxyState( - [this.taskPageViewModel.selectedBoardId], - () => this.taskPageViewModel.selectedBoardId.value == this.boardInfo.fileId - ); - this.color.subscribe(() => { - if (this.isSelected.value == false) return; - if (this.chatViewModel.selectedPage.value != "tasks" /* Tasks */) - return; - this.applyColor(); - }); - this.selectedPage.subscribeSilent(() => { - this.storeLastUsedView(); - }); - boardsAndTasksModel.taskHandlerManager.setHandler( - this.boardInfo.fileId, - (taskFileContent) => { - if (taskFileContent.boardId != this.boardInfo.fileId) return; - this.showTask(taskFileContent); - this.updateTaskIndices(); - } - ); this.searchViewModel = new SearchViewModel( this.taskViewModels, this.filteredTaskViewModels, @@ -4357,6 +4475,30 @@ [this.searchViewModel.appliedQuery], () => this.searchViewModel.appliedQuery.value != "" ); + this.isSelected = createProxyState( + [this.taskPageViewModel.selectedBoardId], + () => this.taskPageViewModel.selectedBoardId.value == this.boardInfo.fileId + ); + this.color.subscribe(() => { + if (this.isSelected.value == false) return; + if (this.chatViewModel.selectedPage.value != "tasks" /* Tasks */) + return; + this.applyColor(); + }); + this.selectedPage.subscribeSilent(() => { + this.storeLastUsedView(); + }); + this.searchViewModel.appliedQuery.subscribeSilent(() => { + this.resetPinchZoom(); + }); + boardsAndTasksModel.taskHandlerManager.setHandler( + this.boardInfo.fileId, + (taskFileContent) => { + if (taskFileContent.boardId != this.boardInfo.fileId) return; + this.showTask(taskFileContent); + this.updateTaskIndices(); + } + ); this.registerKeyStroke("=" /* Filter */, this.showFilterModal); this.registerKeyStroke("-" /* Reset */, this.resetFilter); this.registerKeyStroke("backspace" /* CloseOrCancel */, this.hideFilterModal); @@ -4598,6 +4740,10 @@ ); this.encryptionKeyInput.callSubscriptions(); }; + this.randomizeKey = () => { + this.encryptionKeyInput.value = random(24); + this.setEncryptionKey(); + }; this.applyColor = () => { this.chatViewModel.setColor(this.color.value); this.appliedColor.value = this.color.value; @@ -5411,6 +5557,7 @@ // src/View/homePage.tsx function HomePage(coreViewModel2, storageViewModel2, settingsViewModel2, connectionViewModel2, fileTransferViewModel2, chatListViewModel2) { const greeting = createProxyState([settingsViewModel2.username], () => coreViewModel2.translations.homePage.greeting(settingsViewModel2.username.value)); + const isChatPlaceholderHidden = createProxyState([chatListViewModel2.chatMatches, chatListViewModel2.chatQuery], () => chatListViewModel2.chatMatches.value.size > 0 || chatListViewModel2.chatQuery.value != ""); const overviewSection = /* @__PURE__ */ createElement("div", { id: "overview-section" }, /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "cell_tower"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.homePage.serverAddress), /* @__PURE__ */ createElement( "input", { @@ -5491,6 +5638,13 @@ "on:enter": chatListViewModel2.createChat } )), /* @__PURE__ */ createElement("hr", null), NewItemEntry(coreViewModel2, chatListViewModel2.chatQuery, chatListViewModel2.createChat), /* @__PURE__ */ createElement( + "span", + { + class: "secondary", + "toggle:hidden": isChatPlaceholderHidden + }, + coreViewModel2.translations.homePage.noChatsPlaceholder + ), /* @__PURE__ */ createElement( "div", { id: "chat-grid", @@ -6303,6 +6457,7 @@ function BoardViewToggleButton(label, icon, page, boardViewModel, key) { function select() { boardViewModel.selectedPage.value = page; + boardViewModel.resetPinchZoom(); } const isSelected = createProxyState( [boardViewModel.selectedPage], @@ -6604,7 +6759,15 @@ "on:enter": settingsPageViewModel.setEncryptionKey, "set:type": settingsPageViewModel.encryptionKeyInputType } - ))), /* @__PURE__ */ createElement("div", { class: "flex-row justify-end width-input" }, /* @__PURE__ */ createElement( + ))), /* @__PURE__ */ createElement("div", { class: "flex-row width-input" }, /* @__PURE__ */ createElement( + "button", + { + class: "width-50", + "on:click": settingsPageViewModel.randomizeKey + }, + coreViewModel2.translations.chatPage.settings.randomizeKey, + /* @__PURE__ */ createElement("span", { class: "icon" }, "shuffle") + ), /* @__PURE__ */ createElement( "button", { class: "width-50", diff --git a/dist/sw.js b/dist/sw.js index a0b43ab7..d08b6820 100644 --- a/dist/sw.js +++ b/dist/sw.js @@ -1,4 +1,4 @@ -const VERSION = "2610 Beta 21.11" +const VERSION = "2610 Beta 21.12" function processUrl(event) { const url = event.request.url; diff --git a/dist/version.txt b/dist/version.txt index 50679254..8c98f5f9 100644 --- a/dist/version.txt +++ b/dist/version.txt @@ -1 +1 @@ -2610 Beta 21.11 +2610 Beta 21.12 diff --git a/node_modules/crypto-random-string/index.d.ts b/node_modules/crypto-random-string/index.d.ts new file mode 100644 index 00000000..3e5cb877 --- /dev/null +++ b/node_modules/crypto-random-string/index.d.ts @@ -0,0 +1,90 @@ +import {type MergeExclusive} from 'type-fest'; + +type BaseOptions = { + /** + Length of the returned string. + + Must be a non-negative integer. + + This is the number of characters, so a string generated from a `characters` set with characters outside the [Basic Multilingual Plane](https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane), like emoji, has a larger `.length` than this. + */ + length: number; +}; + +type TypeOption = { + /** + Use only characters from a predefined set of allowed characters. + + Cannot be set at the same time as the `characters` option. + + @default 'hex' + + The `distinguishable` set contains only uppercase characters that are not easily confused: `CDEHKMPRTUWXY012458`. It can be useful if you need to print out a short string that you'd like users to read and type back in with minimal errors. For example, reading a code off of a screen that needs to be typed into a phone to connect two devices. + + The `ascii-printable` set contains all [printable ASCII characters](https://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters) except the space: ``!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~`` Useful for generating passwords where all possible ASCII characters should be used. + + The `alphanumeric` set contains uppercase letters, lowercase letters, and digits: `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`. Useful for generating [nonce](https://developer.mozilla.org/en-US/docs/Web/API/HTMLOrForeignElement/nonce) values. + + @example + ``` + cryptoRandomString({length: 10}); + //=> '87fc70e2b9' + + cryptoRandomString({length: 10, type: 'base64'}); + //=> 'mhsX7xmIv/' + + cryptoRandomString({length: 10, type: 'url-safe'}); + //=> 'VEjfNW3Yej' + + cryptoRandomString({length: 10, type: 'numeric'}); + //=> '8314659141' + + cryptoRandomString({length: 6, type: 'distinguishable'}); + //=> 'CDEHKM' + + cryptoRandomString({length: 10, type: 'ascii-printable'}); + //=> '`#Rt8$IK>B' + + cryptoRandomString({length: 10, type: 'alphanumeric'}); + //=> 'DMuKL8YtE7' + ``` + */ + type?: 'hex' | 'base64' | 'url-safe' | 'numeric' | 'distinguishable' | 'ascii-printable' | 'alphanumeric'; +}; + +type CharactersOption = { + /** + Use only characters from a custom set of allowed characters. + + Cannot be set at the same time as the `type` option. + + Each character is picked with equal probability, so repeating a character in the set makes it more likely to be picked. The length limits count Unicode characters, not UTF-16 code units, so characters outside the [Basic Multilingual Plane](https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane), like emoji, are handled correctly. + + Minimum length: `1` + Maximum length: `65536` + + @example + ``` + cryptoRandomString({length: 10, characters: '0123456789'}); + //=> '8796225811' + ``` + */ + characters?: string; +}; + +export type Options = BaseOptions & MergeExclusive; + +/** +Generate a [cryptographically strong](https://en.wikipedia.org/wiki/Strong_cryptography) random string. + +@returns A randomized string. + +@example +``` +import cryptoRandomString from 'crypto-random-string'; + +cryptoRandomString({length: 10}); +//=> '2cf05d94db' +``` +*/ +export default function cryptoRandomString(options: Options): string; diff --git a/node_modules/crypto-random-string/index.js b/node_modules/crypto-random-string/index.js new file mode 100644 index 00000000..eb3c5082 --- /dev/null +++ b/node_modules/crypto-random-string/index.js @@ -0,0 +1,104 @@ +import {uint8ArrayToBase64, uint8ArrayToHex} from 'uint8array-extras'; + +// `crypto.getRandomValues` throws an error if too much entropy is requested at once. (https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#exceptions) +const maxBytesPerRequest = 65_536; + +// Each character is picked with a single `Uint16` selector value, so a character set cannot be larger than the range of one. +const maxCharacterSetSize = 0x1_00_00; + +function fillWithRandomValues(typedArray) { + const maxElementsPerRequest = maxBytesPerRequest / typedArray.BYTES_PER_ELEMENT; + + for (let offset = 0; offset < typedArray.length; offset += maxElementsPerRequest) { + // `TypedArray#subarray` clamps the end index and shares the underlying buffer, so this fills the array in place without any copying. + crypto.getRandomValues(typedArray.subarray(offset, offset + maxElementsPerRequest)); + } + + return typedArray; +} + +const randomBytes = byteLength => fillWithRandomValues(new Uint8Array(byteLength)); + +const generateForCustomCharacters = (length, characters) => { + // Generating entropy is faster than complex math operations, so we use the simplest way + const characterCount = characters.length; + const validSelectorCount = Math.floor(maxCharacterSetSize / characterCount) * characterCount; // Using values at or above this will ruin distribution when using modular division + // Generating a bit more than required, adjusted for how many values we expect to discard, so we usually only need one pass + const entropyLength = Math.ceil(1.1 * length * (maxCharacterSetSize / validSelectorCount)); + let string = ''; + let stringLength = 0; + + while (stringLength < length) { + const entropy = fillWithRandomValues(new Uint16Array(entropyLength)); + + for (let index = 0; index < entropyLength; index++) { + const entropyValue = entropy[index]; + + if (entropyValue < validSelectorCount) { // Skip values which will ruin distribution when using modular division + string += characters[entropyValue % characterCount]; + stringLength++; + + if (stringLength === length) { + return string; + } + } + } + } + + return string; +}; + +const characterSets = new Map([ + ['url-safe', [...'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~']], + ['numeric', [...'0123456789']], + ['distinguishable', [...'CDEHKMPRTUWXY012458']], + ['ascii-printable', [...'!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~']], + ['alphanumeric', [...'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789']], +]); + +const allowedTypes = new Set(['hex', 'base64', ...characterSets.keys()]); + +export default function cryptoRandomString({length, type, characters}) { + if (!Number.isSafeInteger(length) || length < 0) { + throw new TypeError('Expected `length` to be a non-negative integer'); + } + + if (type !== undefined && characters !== undefined) { + throw new TypeError('Expected either `type` or `characters`'); + } + + if (characters !== undefined) { + if (typeof characters !== 'string') { + throw new TypeError('Expected `characters` to be a string'); + } + + // Spread to keep characters outside the Basic Multilingual Plane, like emoji, intact. + const customCharacterSet = [...characters]; + + if (customCharacterSet.length === 0) { + throw new TypeError('Expected `characters` to contain at least 1 character'); + } + + if (customCharacterSet.length > maxCharacterSetSize) { + throw new TypeError(`Expected \`characters\` to contain at most ${maxCharacterSetSize} characters, got ${customCharacterSet.length}`); + } + + return generateForCustomCharacters(length, customCharacterSet); + } + + if (type !== undefined && !allowedTypes.has(type)) { + throw new TypeError(`Unknown type: ${type}`); + } + + const characterSet = characterSets.get(type); + + if (characterSet !== undefined) { + return generateForCustomCharacters(length, characterSet); + } + + if (type === 'base64') { + return uint8ArrayToBase64(randomBytes(Math.ceil(length * 0.75))).slice(0, length); // Needs 0.75 bytes of entropy per character + } + + return uint8ArrayToHex(randomBytes(Math.ceil(length * 0.5))).slice(0, length); // Needs 0.5 bytes of entropy per character +} diff --git a/node_modules/crypto-random-string/license b/node_modules/crypto-random-string/license new file mode 100644 index 00000000..fa7ceba3 --- /dev/null +++ b/node_modules/crypto-random-string/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/crypto-random-string/package.json b/node_modules/crypto-random-string/package.json new file mode 100644 index 00000000..f16bddf2 --- /dev/null +++ b/node_modules/crypto-random-string/package.json @@ -0,0 +1,54 @@ +{ + "name": "crypto-random-string", + "version": "6.0.0", + "description": "Generate a cryptographically strong random string", + "license": "MIT", + "repository": "sindresorhus/crypto-random-string", + "funding": "https://github.com/sponsors/sindresorhus", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "https://sindresorhus.com" + }, + "type": "module", + "exports": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "sideEffects": false, + "engines": { + "node": ">=22" + }, + "scripts": { + "test": "xo && ava && tsd" + }, + "files": [ + "index.js", + "index.d.ts" + ], + "keywords": [ + "random", + "string", + "text", + "id", + "identifier", + "slug", + "salt", + "pin", + "crypto", + "strong", + "secure", + "hex", + "secret", + "protect" + ], + "dependencies": { + "type-fest": "^5.8.0", + "uint8array-extras": "^1.5.0" + }, + "devDependencies": { + "ava": "^8.0.1", + "tsd": "^0.33.0", + "xo": "^4.0.0" + } +} diff --git a/node_modules/crypto-random-string/readme.md b/node_modules/crypto-random-string/readme.md new file mode 100644 index 00000000..35eb3231 --- /dev/null +++ b/node_modules/crypto-random-string/readme.md @@ -0,0 +1,100 @@ +# crypto-random-string + +> Generate a [cryptographically strong](https://en.wikipedia.org/wiki/Strong_cryptography) random string + +Can be useful for creating an identifier, slug, salt, PIN code, fixture, etc. + +Works in Node.js and browsers. + +## Install + +```sh +npm install crypto-random-string +``` + +## Usage + +```js +import cryptoRandomString from 'crypto-random-string'; + +cryptoRandomString({length: 10}); +//=> '2cf05d94db' + +cryptoRandomString({length: 10, type: 'base64'}); +//=> 'YMiMbaQl6I' + +cryptoRandomString({length: 10, type: 'url-safe'}); +//=> 'YN-tqc8pOw' + +cryptoRandomString({length: 10, type: 'numeric'}); +//=> '8314659141' + +cryptoRandomString({length: 6, type: 'distinguishable'}); +//=> 'CDEHKM' + +cryptoRandomString({length: 10, type: 'ascii-printable'}); +//=> '`#Rt8$IK>B' + +cryptoRandomString({length: 10, type: 'alphanumeric'}); +//=> 'DMuKL8YtE7' + +cryptoRandomString({length: 10, characters: 'abc'}); +//=> 'abaaccabac' +``` + +## API + +### cryptoRandomString(options) + +Returns a randomized string. [Hex](https://en.wikipedia.org/wiki/Hexadecimal) by default. + +#### options + +Type: `object` + +##### length + +*Required*\ +Type: `number` *(non-negative integer)* + +Length of the returned string. + +This is the number of characters, so a string generated from a `characters` set with characters outside the [Basic Multilingual Plane](https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane), like emoji, has a larger `.length` than this. + +##### type + +Type: `string`\ +Default: `'hex'`\ +Values: `'hex' | 'base64' | 'url-safe' | 'numeric' | 'distinguishable' | 'ascii-printable' | 'alphanumeric'` + +Use only characters from a predefined set of allowed characters. + +Cannot be set at the same time as the `characters` option. + +The `distinguishable` set contains only uppercase characters that are not easily confused: `CDEHKMPRTUWXY012458`. It can be useful if you need to print out a short string that you'd like users to read and type back in with minimal errors. For example, reading a code off of a screen that needs to be typed into a phone to connect two devices. + +The `ascii-printable` set contains all [printable ASCII characters](https://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters) except the space: ``!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~`` Useful for generating passwords where all possible ASCII characters should be used. + +The `alphanumeric` set contains uppercase letters, lowercase letters, and digits: `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`. Useful for generating [nonce](https://developer.mozilla.org/en-US/docs/Web/API/HTMLOrForeignElement/nonce) values. + +##### characters + +Type: `string`\ +Minimum length: `1`\ +Maximum length: `65536` + +Use only characters from a custom set of allowed characters. + +Cannot be set at the same time as the `type` option. + +Each character is picked with equal probability, so repeating a character in the set makes it more likely to be picked. The length limits count Unicode characters, not UTF-16 code units, so characters outside the [Basic Multilingual Plane](https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane), like emoji, are handled correctly. + +## Related + +- [random-int](https://github.com/sindresorhus/random-int) - Generate a random integer +- [random-float](https://github.com/sindresorhus/random-float) - Generate a random float +- [random-item](https://github.com/sindresorhus/random-item) - Get a random item from an array +- [random-boolean](https://github.com/arthurvr/random-boolean) - Get a random boolean +- [random-object-key](https://github.com/sindresorhus/random-object-key) - Get a random key from an object +- [random-object-value](https://github.com/sindresorhus/random-object-value) - Get a random value from an object +- [unique-random](https://github.com/sindresorhus/unique-random) - Generate random numbers that are consecutively unique diff --git a/node_modules/tagged-tag/index.d.ts b/node_modules/tagged-tag/index.d.ts new file mode 100644 index 00000000..d68b8568 --- /dev/null +++ b/node_modules/tagged-tag/index.d.ts @@ -0,0 +1,3 @@ +declare const tag: unique symbol; + +export default tag; diff --git a/node_modules/tagged-tag/license b/node_modules/tagged-tag/license new file mode 100644 index 00000000..fa7ceba3 --- /dev/null +++ b/node_modules/tagged-tag/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/tagged-tag/package.json b/node_modules/tagged-tag/package.json new file mode 100644 index 00000000..6d714abc --- /dev/null +++ b/node_modules/tagged-tag/package.json @@ -0,0 +1,36 @@ +{ + "name": "tagged-tag", + "version": "1.0.0", + "description": "Unique tag for use in the type-fest Tagged type", + "license": "MIT", + "repository": "sindresorhus/tagged-tag", + "funding": "https://github.com/sponsors/sindresorhus", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "https://sindresorhus.com" + }, + "type": "module", + "exports": { + "types": "./index.d.ts" + }, + "engines": { + "node": ">=20" + }, + "scripts": { + "test": "tsc index.d.ts" + }, + "files": [ + "index.d.ts" + ], + "keywords": [ + "tagged", + "tag", + "unique", + "symbol", + "type-fest" + ], + "devDependencies": { + "typescript": "^5.8.3" + } +} diff --git a/node_modules/tagged-tag/readme.md b/node_modules/tagged-tag/readme.md new file mode 100644 index 00000000..33ccacfc --- /dev/null +++ b/node_modules/tagged-tag/readme.md @@ -0,0 +1,5 @@ +# tagged-tag + +> Unique tag used in the [type-fest](https://github.com/sindresorhus/type-fest) [`Tagged`](https://github.com/sindresorhus/type-fest/blob/a6612048e1bf4c6e787b1a10007dd90c5c9f34e7/source/opaque.d.ts#L122-L184) type + +This package provides a singular, unified tag to prevent the duplication of tag symbols when multiple versions of type-fest coexist in a project's dependency tree. Such duplication could lead to ambiguity when using the `Tagged` type. Because of this, this package will never have another major version. diff --git a/node_modules/type-fest/index.d.ts b/node_modules/type-fest/index.d.ts new file mode 100644 index 00000000..096385d1 --- /dev/null +++ b/node_modules/type-fest/index.d.ts @@ -0,0 +1,227 @@ +// Basic +export type * from './source/primitive.d.ts'; +export type * from './source/typed-array.d.ts'; +export type * from './source/basic.d.ts'; +export type * from './source/json-value.d.ts'; +export type * from './source/characters.d.ts'; + +// Utilities +export type {KeysOfUnion} from './source/keys-of-union.d.ts'; +export type {DistributedOmit} from './source/distributed-omit.d.ts'; +export type {DistributedPick} from './source/distributed-pick.d.ts'; +export type {EmptyObject, IsEmptyObject} from './source/empty-object.d.ts'; +export type {IfEmptyObject} from './source/if-empty-object.d.ts'; +export type {NonEmptyObject} from './source/non-empty-object.d.ts'; +export type {NonEmptyString} from './source/non-empty-string.d.ts'; +export type {UnknownRecord} from './source/unknown-record.d.ts'; +export type {UnknownArray} from './source/unknown-array.d.ts'; +export type {UnknownSet} from './source/unknown-set.d.ts'; +export type {UnknownMap} from './source/unknown-map.d.ts'; +export type {Except, ExceptOptions} from './source/except.d.ts'; +export type {TaggedUnion} from './source/tagged-union.d.ts'; +export type {Writable} from './source/writable.d.ts'; +export type {WritableDeep} from './source/writable-deep.d.ts'; +export type {Merge} from './source/merge.d.ts'; +export type {ObjectMerge} from './source/object-merge.d.ts'; +export type {MergeDeep, MergeDeepOptions} from './source/merge-deep.d.ts'; +export type {MergeExclusive} from './source/merge-exclusive.d.ts'; +export type {RequireAtLeastOne} from './source/require-at-least-one.d.ts'; +export type {RequireExactlyOne} from './source/require-exactly-one.d.ts'; +export type {RequireAllOrNone} from './source/require-all-or-none.d.ts'; +export type {RequireOneOrNone} from './source/require-one-or-none.d.ts'; +export type {SingleKeyObject} from './source/single-key-object.d.ts'; +export type {OmitIndexSignature} from './source/omit-index-signature.d.ts'; +export type {PickIndexSignature} from './source/pick-index-signature.d.ts'; +export type {PartialDeep, PartialDeepOptions} from './source/partial-deep.d.ts'; +export type {UnwrapPartial} from './source/unwrap-partial.d.ts'; +export type {UnwrapRequired} from './source/unwrap-required.d.ts'; +export type {RequiredDeep} from './source/required-deep.d.ts'; +export type {PickDeep} from './source/pick-deep.d.ts'; +export type {OmitDeep} from './source/omit-deep.d.ts'; +export type {PartialOnUndefinedDeep, PartialOnUndefinedDeepOptions} from './source/partial-on-undefined-deep.d.ts'; +export type {UndefinedOnPartialDeep} from './source/undefined-on-partial-deep.d.ts'; +export type {ReadonlyDeep} from './source/readonly-deep.d.ts'; +export type {LiteralUnion} from './source/literal-union.d.ts'; +export type {Promisable} from './source/promisable.d.ts'; +export type {Arrayable} from './source/arrayable.d.ts'; +export type {Optional} from './source/optional.d.ts'; +export type {Opaque, UnwrapOpaque, Tagged, GetTagMetadata, UnwrapTagged} from './source/tagged.d.ts'; +export type {InvariantOf} from './source/invariant-of.d.ts'; +export type {SetOptional} from './source/set-optional.d.ts'; +export type {SetReadonly} from './source/set-readonly.d.ts'; +export type {SetRequired} from './source/set-required.d.ts'; +export type {SetRequiredDeep} from './source/set-required-deep.d.ts'; +export type {SetNonNullable} from './source/set-non-nullable.d.ts'; +export type {SetNonNullableDeep} from './source/set-non-nullable-deep.d.ts'; +export type {NonNullableDeep} from './source/non-nullable-deep.d.ts'; +export type {ValueOf} from './source/value-of.d.ts'; +export type {AsyncReturnType} from './source/async-return-type.d.ts'; +export type {ConditionalExcept} from './source/conditional-except.d.ts'; +export type {ConditionalKeys} from './source/conditional-keys.d.ts'; +export type {ConditionalPick} from './source/conditional-pick.d.ts'; +export type {ConditionalPickDeep, ConditionalPickDeepOptions} from './source/conditional-pick-deep.d.ts'; +export type {UnionToIntersection} from './source/union-to-intersection.d.ts'; +export type {Stringified} from './source/stringified.d.ts'; +export type {StringSlice} from './source/string-slice.d.ts'; +export type {FixedLengthArray} from './source/fixed-length-array.d.ts'; +export type {MultidimensionalArray} from './source/multidimensional-array.d.ts'; +export type {MultidimensionalReadonlyArray} from './source/multidimensional-readonly-array.d.ts'; +export type {IterableElement} from './source/iterable-element.d.ts'; +export type {Entry} from './source/entry.d.ts'; +export type {Entries} from './source/entries.d.ts'; +export type {SetReturnType} from './source/set-return-type.d.ts'; +export type {SetParameterType} from './source/set-parameter-type.d.ts'; +export type {Asyncify} from './source/asyncify.d.ts'; +export type {Simplify} from './source/simplify.d.ts'; +export type {SimplifyDeep} from './source/simplify-deep.d.ts'; +export type {Jsonify} from './source/jsonify.d.ts'; +export type {Jsonifiable} from './source/jsonifiable.d.ts'; +export type {StructuredCloneable} from './source/structured-cloneable.d.ts'; +export type {Schema, SchemaOptions} from './source/schema.d.ts'; +export type {LiteralToPrimitive} from './source/literal-to-primitive.d.ts'; +export type {LiteralToPrimitiveDeep} from './source/literal-to-primitive-deep.d.ts'; +export type { + PositiveInfinity, + NegativeInfinity, + Finite, + Integer, + Float, + NegativeFloat, + Negative, + NonNegative, + NegativeInteger, + NonNegativeInteger, + IsNegative, +} from './source/numeric.d.ts'; +export type {GreaterThan} from './source/greater-than.d.ts'; +export type {GreaterThanOrEqual} from './source/greater-than-or-equal.d.ts'; +export type {LessThan} from './source/less-than.d.ts'; +export type {LessThanOrEqual} from './source/less-than-or-equal.d.ts'; +export type {Sum} from './source/sum.d.ts'; +export type {Subtract} from './source/subtract.d.ts'; +export type {UnionMax} from './source/union-max.d.ts'; +export type {KeyAsString} from './source/key-as-string.d.ts'; +export type {Exact} from './source/exact.d.ts'; +export type {ReadonlyTuple} from './source/readonly-tuple.d.ts'; +export type {OverrideProperties} from './source/override-properties.d.ts'; +export type {RenameKeys} from './source/rename-keys.d.ts'; +export type {OptionalKeysOf} from './source/optional-keys-of.d.ts'; +export type {IsOptionalKeyOf} from './source/is-optional-key-of.d.ts'; +export type {HasOptionalKeys} from './source/has-optional-keys.d.ts'; +export type {RequiredKeysOf} from './source/required-keys-of.d.ts'; +export type {IsRequiredKeyOf} from './source/is-required-key-of.d.ts'; +export type {HasRequiredKeys} from './source/has-required-keys.d.ts'; +export type {ReadonlyKeysOf} from './source/readonly-keys-of.d.ts'; +export type {IsReadonlyKeyOf} from './source/is-readonly-key-of.d.ts'; +export type {HasReadonlyKeys} from './source/has-readonly-keys.d.ts'; +export type {WritableKeysOf} from './source/writable-keys-of.d.ts'; +export type {IsWritableKeyOf} from './source/is-writable-key-of.d.ts'; +export type {HasWritableKeys} from './source/has-writable-keys.d.ts'; +export type {Spread} from './source/spread.d.ts'; +export type {SplitOnRestElement} from './source/split-on-rest-element.d.ts'; +export type {ExtractRestElement} from './source/extract-rest-element.d.ts'; +export type {ExcludeRestElement} from './source/exclude-rest-element.d.ts'; +export type {IsInteger} from './source/is-integer.d.ts'; +export type {IsFloat} from './source/is-float.d.ts'; +export type {TupleToObject} from './source/tuple-to-object.d.ts'; +export type {TupleToUnion} from './source/tuple-to-union.d.ts'; +export type {UnionToTuple} from './source/union-to-tuple.d.ts'; +export type {IntRange} from './source/int-range.d.ts'; +export type {IntClosedRange} from './source/int-closed-range.d.ts'; +export type {IsEqual} from './source/is-equal.d.ts'; +export type {IsLiteral} from './source/is-literal.d.ts'; +export type {IsStringLiteral} from './source/is-string-literal.d.ts'; +export type {IsNumericLiteral} from './source/is-numeric-literal.d.ts'; +export type {IsBooleanLiteral} from './source/is-boolean-literal.d.ts'; +export type {IsSymbolLiteral} from './source/is-symbol-literal.d.ts'; +export type {IsAny} from './source/is-any.d.ts'; +export type {IfAny} from './source/if-any.d.ts'; +export type {IsNever} from './source/is-never.d.ts'; +export type {IfNever} from './source/if-never.d.ts'; +export type {IsUnknown} from './source/is-unknown.d.ts'; +export type {IfUnknown} from './source/if-unknown.d.ts'; +export type {IsTuple, IsTupleOptions} from './source/is-tuple.d.ts'; +export type {ArrayIndices} from './source/array-indices.d.ts'; +export type {ArrayValues} from './source/array-values.d.ts'; +export type {ArraySlice} from './source/array-slice.d.ts'; +export type {ArraySplice} from './source/array-splice.d.ts'; +export type {ArrayTail} from './source/array-tail.d.ts'; +export type {ArrayElement} from './source/array-element.d.ts'; +export type {ArrayLength} from './source/array-length.d.ts'; +export type {SetFieldType, SetFieldTypeOptions} from './source/set-field-type.d.ts'; +export type {Paths, PathsOptions} from './source/paths.d.ts'; +export type {AllUnionFields} from './source/all-union-fields.d.ts'; +export type {SharedUnionFields} from './source/shared-union-fields.d.ts'; +export type {SharedUnionFieldsDeep, SharedUnionFieldsDeepOptions} from './source/shared-union-fields-deep.d.ts'; +export type {IsNull} from './source/is-null.d.ts'; +export type {IfNull} from './source/if-null.d.ts'; +export type {IsUndefined} from './source/is-undefined.d.ts'; +export type {And} from './source/and.d.ts'; +export type {AndAll} from './source/and-all.d.ts'; +export type {Or} from './source/or.d.ts'; +export type {OrAll} from './source/or-all.d.ts'; +export type {Xor} from './source/xor.d.ts'; +export type {AllExtend, AllExtendOptions} from './source/all-extend.d.ts'; +export type {SomeExtend, SomeExtendOptions} from './source/some-extend.d.ts'; +export type {NonEmptyTuple} from './source/non-empty-tuple.d.ts'; +export type {FindGlobalInstanceType, FindGlobalType} from './source/find-global-type.d.ts'; +export type {If} from './source/if.d.ts'; +export type {IsUnion} from './source/is-union.d.ts'; +export type {IsLowercase} from './source/is-lowercase.d.ts'; +export type {IsUppercase} from './source/is-uppercase.d.ts'; +export type {IsOptional} from './source/is-optional.d.ts'; +export type {IsNullable} from './source/is-nullable.d.ts'; +export type {TupleOf} from './source/tuple-of.d.ts'; +export type {ExclusifyUnion} from './source/exclusify-union.d.ts'; +export type {ArrayReverse} from './source/array-reverse.d.ts'; +export type {UnionMember} from './source/union-member.d.ts'; +export type {Absolute} from './source/absolute.d.ts'; +export type {UnionLength} from './source/union-length.d.ts'; +export type {StringToNumber} from './source/string-to-number.d.ts'; + +// Template literal types +export type {CamelCase, CamelCaseOptions} from './source/camel-case.d.ts'; +export type {CamelCasedProperties} from './source/camel-cased-properties.d.ts'; +export type {CamelCasedPropertiesDeep} from './source/camel-cased-properties-deep.d.ts'; +export type {KebabCase} from './source/kebab-case.d.ts'; +export type {KebabCasedProperties} from './source/kebab-cased-properties.d.ts'; +export type {KebabCasedPropertiesDeep} from './source/kebab-cased-properties-deep.d.ts'; +export type {PascalCase} from './source/pascal-case.d.ts'; +export type {PascalCasedProperties} from './source/pascal-cased-properties.d.ts'; +export type {PascalCasedPropertiesDeep} from './source/pascal-cased-properties-deep.d.ts'; +export type {SnakeCase} from './source/snake-case.d.ts'; +export type {SnakeCasedProperties} from './source/snake-cased-properties.d.ts'; +export type {SnakeCasedPropertiesDeep} from './source/snake-cased-properties-deep.d.ts'; +export type {ScreamingSnakeCase} from './source/screaming-snake-case.d.ts'; +export type {DelimiterCase} from './source/delimiter-case.d.ts'; +export type {DelimiterCasedProperties} from './source/delimiter-cased-properties.d.ts'; +export type {DelimiterCasedPropertiesDeep} from './source/delimiter-cased-properties-deep.d.ts'; +export type {Join} from './source/join.d.ts'; +export type {Split, SplitOptions} from './source/split.d.ts'; +export type {Words, WordsOptions} from './source/words.d.ts'; +export type {Trim} from './source/trim.d.ts'; +export type {Replace, ReplaceOptions} from './source/replace.d.ts'; +export type {StringRepeat} from './source/string-repeat.d.ts'; +export type {Includes} from './source/includes.d.ts'; +export type {Get, GetOptions} from './source/get.d.ts'; +export type {LastArrayElement} from './source/last-array-element.d.ts'; +export type {ConditionalSimplify} from './source/conditional-simplify.d.ts'; +export type {ConditionalSimplifyDeep} from './source/conditional-simplify-deep.d.ts'; +export type {RemovePrefix, RemovePrefixOptions} from './source/remove-prefix.d.ts'; +export type {RemoveSuffix, RemoveSuffixOptions} from './source/remove-suffix.d.ts'; +export type {StringToArray, StringToArrayOptions} from './source/string-to-array.d.ts'; +export type {StringLength} from './source/string-length.d.ts'; + +// Miscellaneous +export type {GlobalThis} from './source/global-this.d.ts'; +export type {PackageJson} from './source/package-json.d.ts'; +export type {TsConfigJson} from './source/tsconfig-json.d.ts'; + +// Improved built-in +export type {ExtendsStrict, ExtendsStrictOptions} from './source/extends-strict.d.ts'; +export type {ExtractStrict} from './source/extract-strict.d.ts'; +export type {ExcludeStrict} from './source/exclude-strict.d.ts'; +export type {ExcludeExactly} from './source/exclude-exactly.d.ts'; +export type {ExtractExactly} from './source/extract-exactly.d.ts'; + +export {}; diff --git a/node_modules/type-fest/license-cc0 b/node_modules/type-fest/license-cc0 new file mode 100644 index 00000000..0e259d42 --- /dev/null +++ b/node_modules/type-fest/license-cc0 @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/node_modules/type-fest/license-mit b/node_modules/type-fest/license-mit new file mode 100644 index 00000000..fa7ceba3 --- /dev/null +++ b/node_modules/type-fest/license-mit @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/type-fest/package.json b/node_modules/type-fest/package.json new file mode 100644 index 00000000..eeb947b5 --- /dev/null +++ b/node_modules/type-fest/package.json @@ -0,0 +1,76 @@ +{ + "name": "type-fest", + "version": "5.10.0", + "description": "A collection of essential TypeScript types", + "license": "(MIT OR CC0-1.0)", + "repository": "sindresorhus/type-fest", + "funding": "https://github.com/sponsors/sindresorhus", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "https://sindresorhus.com" + }, + "type": "module", + "exports": { + ".": { + "types": "./index.d.ts" + }, + "./globals": { + "types": "./source/globals/index.d.ts" + } + }, + "types": "./index.d.ts", + "sideEffects": false, + "engines": { + "node": ">=20" + }, + "scripts": { + "test:tsc": "node --max-old-space-size=6144 ./node_modules/.bin/tsc", + "test:minimum-lib": "node --max-old-space-size=6144 ./node_modules/.bin/tsc -p tsconfig.minimum-lib.json", + "test:tsd": "node --max-old-space-size=6144 ./node_modules/.bin/tsd", + "test:xo": "node --max-old-space-size=6144 ./node_modules/.bin/xo --ignores=lint-processors/fixtures/**/*.d.ts '**/*.{js,ts,md}'", + "test:linter": "node --test", + "test": "run-p test:*" + }, + "files": [ + "index.d.ts", + "source", + "license-mit", + "license-cc0" + ], + "keywords": [ + "typescript", + "ts", + "types", + "utility", + "util", + "utilities", + "omit", + "merge", + "json", + "generics" + ], + "dependencies": { + "tagged-tag": "^1.0.0" + }, + "devDependencies": { + "@eslint/markdown": "^8.0.1", + "@sindresorhus/tsconfig": "^8.0.1", + "@types/node": "^25.5.0", + "@typescript-eslint/parser": "^8.44.0", + "@typescript/vfs": "^1.6.1", + "dedent": "^1.7.0", + "eslint": "^10.1.0", + "expect-type": "^1.2.2", + "npm-run-all2": "^8.0.4", + "tsd": "^0.33.0", + "typescript": "^5.9.2", + "typescript-eslint": "^8.47.0", + "xo": "^2.0.2" + }, + "tsd": { + "compilerOptions": { + "noUnusedLocals": false + } + } +} diff --git a/node_modules/type-fest/readme.md b/node_modules/type-fest/readme.md new file mode 100644 index 00000000..87048261 --- /dev/null +++ b/node_modules/type-fest/readme.md @@ -0,0 +1,1076 @@ +
+
+
+ type-fest +
+
+ A collection of essential TypeScript types +
+
+
+
+
+ +
+
+
+
+
+ +[![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://giphy.com/gifs/illustration-rainbow-unicorn-26AHG5KGFxSkUWw1i) +[![npm dependents](https://badgen.net/npm/dependents/type-fest)](https://www.npmjs.com/package/type-fest?activeTab=dependents) +[![npm downloads](https://badgen.net/npm/dt/type-fest)](https://www.npmjs.com/package/type-fest) + +Many of the types here should have been built-in. You can help by suggesting some of them to the [TypeScript project](https://github.com/Microsoft/TypeScript/blob/main/CONTRIBUTING.md). + +Either add this package as a dependency or copy-paste the needed types. No credit required. 👌 + +PR welcome for additional commonly needed types and docs improvements. Read the [contributing guidelines](.github/contributing.md) first. + +**Help wanted with reviewing [proposals](https://github.com/sindresorhus/type-fest/issues) and [pull requests](https://github.com/sindresorhus/type-fest/pulls).** + +## Install + +```sh +npm install type-fest +``` + +*Requires TypeScript >=5.9, [ESM](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c), and [`{strict: true}`](https://www.typescriptlang.org/tsconfig#strict) in your tsconfig.* + +> [!NOTE] +> This readme shows the current development version. For docs about the latest version, see the [npm page](https://www.npmjs.com/package/type-fest). + +*You may also like my [`ts-extras`](https://github.com/sindresorhus/ts-extras) package which provides runtime functions for some of these types.* + +## Usage + +```ts +import type {Except} from 'type-fest'; + +type Foo = { + unicorn: string; + rainbow: boolean; +}; + +type FooWithoutRainbow = Except; +//=> {unicorn: string} +``` + +## API + +Click the type names for complete docs. + +### Basic + +- [`Primitive`](source/primitive.d.ts) - Matches any [primitive value](https://developer.mozilla.org/en-US/docs/Glossary/Primitive). +- [`Class`](source/basic.d.ts) - Matches a [`class`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes). +- [`Constructor`](source/basic.d.ts) - Matches a [`class` constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes). +- [`AbstractClass`](source/basic.d.ts) - Matches an [`abstract class`](https://www.typescriptlang.org/docs/handbook/2/classes.html#abstract-classes-and-members). +- [`AbstractConstructor`](source/basic.d.ts) - Matches an [`abstract class`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-2.html#abstract-construct-signatures) constructor. +- [`TypedArray`](source/typed-array.d.ts) - Matches any [typed array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray), like `Uint8Array` or `Float64Array`. +- [`ObservableLike`](source/globals/observable-like.d.ts) - Matches a value that is like an [Observable](https://github.com/tc39/proposal-observable). +- [`LowercaseLetter`](source/characters.d.ts) - Matches any lowercase letter in the basic Latin alphabet (a-z). +- [`UppercaseLetter`](source/characters.d.ts) - Matches any uppercase letter in the basic Latin alphabet (A-Z). +- [`DigitCharacter`](source/characters.d.ts) - Matches any digit as a string ('0'-'9'). +- [`Alphanumeric`](source/characters.d.ts) - Matches any lowercase letter (a-z), uppercase letter (A-Z), or digit ('0'-'9') in the basic Latin alphabet. + +### Utilities + +- [`EmptyObject`](source/empty-object.d.ts) - Represents a strictly empty plain object, the `{}` value. +- [`NonEmptyObject`](source/non-empty-object.d.ts) - Represents an object with at least 1 non-optional key. +- [`UnknownRecord`](source/unknown-record.d.ts) - Represents an object with `unknown` value. You probably want this instead of `{}`. +- [`UnknownArray`](source/unknown-array.d.ts) - Represents an array with `unknown` value. +- [`UnknownMap`](source/unknown-map.d.ts) - Represents a map with `unknown` key and value. +- [`UnknownSet`](source/unknown-set.d.ts) - Represents a set with `unknown` value. +- [`Except`](source/except.d.ts) - Create a type from an object type without certain keys. +- [`Writable`](source/writable.d.ts) - Create a type that strips `readonly` from the given type. Inverse of `Readonly`. +- [`WritableDeep`](source/writable-deep.d.ts) - Create a deeply mutable version of an `object`/`ReadonlyMap`/`ReadonlySet`/`ReadonlyArray` type. The inverse of `ReadonlyDeep`. Use `Writable` if you only need one level deep. +- [`Merge`](source/merge.d.ts) - Merge two types into a new type. Keys of the second type overrides keys of the first type. +- [`ObjectMerge`](source/object-merge.d.ts) - Merge two object types into a new object type, where keys from the second override keys from the first. +- [`MergeDeep`](source/merge-deep.d.ts) - Merge two objects or two arrays/tuples recursively into a new type. +- [`MergeExclusive`](source/merge-exclusive.d.ts) - Create a type that has mutually exclusive keys. +- [`OverrideProperties`](source/override-properties.d.ts) - Override existing properties of the given type. Similar to `Merge`, but enforces that the original type has the properties you want to override. +- [`RenameKeys`](source/rename-keys.d.ts) - Rename keys in an object type according to a map of old-to-new names. +- [`RequireAtLeastOne`](source/require-at-least-one.d.ts) - Create a type that requires at least one of the given keys, while keeping the remaining keys as is. +- [`RequireExactlyOne`](source/require-exactly-one.d.ts) - Create a type that requires exactly one of the given keys and disallows more, while keeping the remaining keys as is. +- [`RequireAllOrNone`](source/require-all-or-none.d.ts) - Create a type that requires all of the given keys or none of the given keys, while keeping the remaining keys as is. +- [`RequireOneOrNone`](source/require-one-or-none.d.ts) - Create a type that requires exactly one of the given keys or none of the given keys, while keeping the remaining keys as is. +- [`SingleKeyObject`](source/single-key-object.d.ts) - Create a type that only accepts an object with a single key. +- [`RequiredDeep`](source/required-deep.d.ts) - Create a deeply required version of another type. +- [`PickDeep`](source/pick-deep.d.ts) - Pick properties from a deeply-nested object. +- [`OmitDeep`](source/omit-deep.d.ts) - Omit properties from a deeply-nested object. +- [`OmitIndexSignature`](source/omit-index-signature.d.ts) - Omit any index signatures from the given object type, leaving only explicitly defined properties. +- [`PickIndexSignature`](source/pick-index-signature.d.ts) - Pick only index signatures from the given object type, leaving out all explicitly defined properties. +- [`PartialDeep`](source/partial-deep.d.ts) - Create a deeply optional version of another type. +- [`PartialOnUndefinedDeep`](source/partial-on-undefined-deep.d.ts) - Create a deep version of another type where all keys accepting `undefined` type are set to optional. +- [`UndefinedOnPartialDeep`](source/undefined-on-partial-deep.d.ts) - Create a deep version of another type where all optional keys are set to also accept `undefined`. +- [`UnwrapPartial`](source/unwrap-partial.d.ts) - Revert the `Partial` modifier on an object type. +- [`UnwrapRequired`](source/unwrap-required.d.ts) - Revert the `Required` modifier on an object type. +- [`ReadonlyDeep`](source/readonly-deep.d.ts) - Create a deeply immutable version of another type. +- [`LiteralUnion`](source/literal-union.d.ts) - Create a union type by combining primitive types and literal types without sacrificing auto-completion in IDEs for the literal type part of the union. +- [`Tagged`](source/tagged.d.ts) - Create a [tagged type](https://medium.com/@KevinBGreene/surviving-the-typescript-ecosystem-branding-and-type-tagging-6cf6e516523d) that can support [multiple tags](https://github.com/sindresorhus/type-fest/issues/665) and [per-tag metadata](https://medium.com/@ethanresnick/advanced-typescript-tagged-types-improved-with-type-level-metadata-5072fc125fcf). +- [`UnwrapTagged`](source/tagged.d.ts) - Get the untagged portion of a tagged type created with `Tagged`. +- [`InvariantOf`](source/invariant-of.d.ts) - Create an [invariant type](https://basarat.gitbook.io/typescript/type-system/type-compatibility#footnote-invariance), which is a type that does not accept supertypes and subtypes. +- [`SetOptional`](source/set-optional.d.ts) - Create a type that makes the given keys optional, while keeping the remaining keys as is. +- [`SetReadonly`](source/set-readonly.d.ts) - Create a type that makes the given keys readonly, while keeping the remaining keys as is. +- [`SetRequired`](source/set-required.d.ts) - Create a type that makes the given keys required, while keeping the remaining keys as is. +- [`SetRequiredDeep`](source/set-required-deep.d.ts) - Create a type that makes the given keys required, with support for deeply nested key paths, while keeping the remaining keys as is. +- [`SetNonNullable`](source/set-non-nullable.d.ts) - Create a type that makes the given keys non-nullable, while keeping the remaining keys as is. +- [`SetNonNullableDeep`](source/set-non-nullable-deep.d.ts) - Create a type that makes the specified keys non-nullable (removes `null` and `undefined`), supports deeply nested key paths, and leaves all other keys unchanged. +- [`NonNullableDeep`](source/non-nullable-deep.d.ts) - Recursively removes `null` and `undefined` from the specified type. +- [`ValueOf`](source/value-of.d.ts) - Create a union of the given object's values, and optionally specify which keys to get the values from. +- [`ConditionalKeys`](source/conditional-keys.d.ts) - Extract the keys from a type where the value type of the key extends the given `Condition`. +- [`ConditionalPick`](source/conditional-pick.d.ts) - Pick keys from the shape that matches the given `Condition`. +- [`ConditionalPickDeep`](source/conditional-pick-deep.d.ts) - Pick keys recursively from the shape that matches the given condition. +- [`ConditionalExcept`](source/conditional-except.d.ts) - Exclude keys from a shape that matches the given `Condition`. +- [`UnionToIntersection`](source/union-to-intersection.d.ts) - Convert a union type to an intersection type. +- [`LiteralToPrimitive`](source/literal-to-primitive.d.ts) - Given a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) return the [primitive type](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) it belongs to, or `never` if it's not a primitive. +- [`LiteralToPrimitiveDeep`](source/literal-to-primitive-deep.d.ts) - Like `LiteralToPrimitive` except it converts literal types inside an object or array deeply. +- [`Stringified`](source/stringified.d.ts) - Create a type with the keys of the given type changed to `string` type. +- [`IterableElement`](source/iterable-element.d.ts) - Get the element type of an `Iterable`/`AsyncIterable`. For example, `Array`, `Set`, `Map`, generator, stream, etc. +- [`Entry`](source/entry.d.ts) - Create a type that describes a single key-value pair produced when calling a collection’s `entries` method. +- [`Entries`](source/entries.d.ts) - Create a type that describes the key-value pairs produced when calling a collection’s `entries` method. +- [`SetReturnType`](source/set-return-type.d.ts) - Create a function type with a return type of your choice and the same parameters as the given function type. +- [`SetParameterType`](source/set-parameter-type.d.ts) - Create a function that replaces some parameters with the given parameters. +- [`Simplify`](source/simplify.d.ts) - Useful to flatten the type output to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability. +- [`SimplifyDeep`](source/simplify-deep.d.ts) - Deeply simplifies an object type. +- [`Get`](source/get.d.ts) - Get a deeply-nested property from an object using a key path, like [Lodash's `.get()`](https://lodash.com/docs#get) function. +- [`KeyAsString`](source/key-as-string.d.ts) - Get keys of the given type as strings. +- [`Schema`](source/schema.d.ts) - Create a deep version of another object type where property values are recursively replaced into a given value type. +- [`Exact`](source/exact.d.ts) - Create a type that does not allow extra properties, meaning it only allows properties that are explicitly declared. +- [`KeysOfUnion`](source/keys-of-union.d.ts) - Create a union of all keys from a given type, even those exclusive to specific union members. +- [`OptionalKeysOf`](source/optional-keys-of.d.ts) - Extract all optional keys from the given type. +- [`HasOptionalKeys`](source/has-optional-keys.d.ts) - Returns a boolean for whether the given type has any optional fields. +- [`RequiredKeysOf`](source/required-keys-of.d.ts) - Extract all required keys from the given type. +- [`HasRequiredKeys`](source/has-required-keys.d.ts) - Returns a boolean for whether the given type has any required fields. +- [`ReadonlyKeysOf`](source/readonly-keys-of.d.ts) - Extract all readonly keys from the given type. +- [`HasReadonlyKeys`](source/has-readonly-keys.d.ts) - Returns a boolean for whether the given type has any readonly fields. +- [`WritableKeysOf`](source/writable-keys-of.d.ts) - Extract all writable keys from the given type. +- [`HasWritableKeys`](source/has-writable-keys.d.ts) - Returns a boolean for whether the given type has any writable fields. +- [`Spread`](source/spread.d.ts) - Mimic the type inferred by TypeScript when merging two objects or two arrays/tuples using the spread syntax. +- [`IsEqual`](source/is-equal.d.ts) - Returns a boolean for whether the two given types are equal. +- [`TaggedUnion`](source/tagged-union.d.ts) - Create a union of types that share a common discriminant property. +- [`IntRange`](source/int-range.d.ts) - Generate a union of numbers between a specified start (inclusive) and end (exclusive), with an optional step. +- [`IntClosedRange`](source/int-closed-range.d.ts) - Generate a union of numbers between a specified start and end (both inclusive), with an optional step. +- [`ArrayIndices`](source/array-indices.d.ts) - Provides valid indices for a constant array or tuple. +- [`ArrayValues`](source/array-values.d.ts) - Provides all values for a constant array or tuple. +- [`ArraySplice`](source/array-splice.d.ts) - Create a new array type by adding or removing elements at a specified index range in the original array. +- [`ArrayTail`](source/array-tail.d.ts) - Extract the type of an array or tuple minus the first element. +- [`SetFieldType`](source/set-field-type.d.ts) - Create a type that changes the type of the given keys. +- [`Paths`](source/paths.d.ts) - Generate a union of all possible paths to properties in the given object. +- [`SharedUnionFields`](source/shared-union-fields.d.ts) - Create a type with shared fields from a union of object types. +- [`SharedUnionFieldsDeep`](source/shared-union-fields-deep.d.ts) - Create a type with shared fields from a union of object types, deeply traversing nested structures. +- [`AllUnionFields`](source/all-union-fields.d.ts) - Create a type with all fields from a union of object types. +- [`DistributedOmit`](source/distributed-omit.d.ts) - Omits keys from a type, distributing the operation over a union. +- [`DistributedPick`](source/distributed-pick.d.ts) - Pick keys from a type, distributing the operation over a union. +- [`And`](source/and.d.ts) - Returns a boolean for whether two given types are both `true`. +- [`Or`](source/or.d.ts) - Returns a boolean for whether either of two given types is `true`. +- [`Xor`](source/xor.d.ts) - Returns a boolean for whether only one of two given types is `true`. +- [`AndAll`](source/and-all.d.ts) - Returns a boolean for whether all of the given elements are `true`. +- [`OrAll`](source/or-all.d.ts) - Returns a boolean for whether any of the given elements is `true`. +- [`AllExtend`](source/all-extend.d.ts) - Returns a boolean for whether every element in an array type extends another type. +- [`SomeExtend`](source/some-extend.d.ts) - Returns a boolean for whether some element in an array type extends another type. +- [`NonEmptyTuple`](source/non-empty-tuple.d.ts) - Matches any non-empty tuple. +- [`NonEmptyString`](source/non-empty-string.d.ts) - Matches any non-empty string. +- [`FindGlobalType`](source/find-global-type.d.ts) - Tries to find the type of a global with the given name. +- [`FindGlobalInstanceType`](source/find-global-type.d.ts) - Tries to find one or more types from their globally-defined constructors. +- [`ConditionalSimplify`](source/conditional-simplify.d.ts) - Simplifies a type while including and/or excluding certain types from being simplified. +- [`ConditionalSimplifyDeep`](source/conditional-simplify-deep.d.ts) - Recursively simplifies a type while including and/or excluding certain types from being simplified. +- [`ExclusifyUnion`](source/exclusify-union.d.ts) - Ensure mutual exclusivity in object unions by adding other members’ keys as `?: never`. +- [`Optional`](source/optional.d.ts) - Create a type that represents either the value or `undefined`, while stripping `null` from the type. +- [`UnionMember`](source/union-member.d.ts) - Returns an arbitrary member of a union type. +- [`UnionLength`](source/union-length.d.ts) - Returns the length of a union type. + +### Type Guard + +- [`If`](source/if.d.ts) - An if-else-like type that resolves depending on whether the given `boolean` type is `true` or `false`. +- [`IsLiteral`](source/is-literal.d.ts) - Returns a boolean for whether the given type is a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). +- [`IsStringLiteral`](source/is-string-literal.d.ts) - Returns a boolean for whether the given type is a `string` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). +- [`IsNumericLiteral`](source/is-numeric-literal.d.ts) - Returns a boolean for whether the given type is a `number` or `bigint` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). +- [`IsBooleanLiteral`](source/is-boolean-literal.d.ts) - Returns a boolean for whether the given type is a `true` or `false` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). +- [`IsSymbolLiteral`](source/is-symbol-literal.d.ts) - Returns a boolean for whether the given type is a `symbol` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). +- [`IsAny`](source/is-any.d.ts) - Returns a boolean for whether the given type is `any`. +- [`IsNever`](source/is-never.d.ts) - Returns a boolean for whether the given type is `never`. +- [`IsUnknown`](source/is-unknown.d.ts) - Returns a boolean for whether the given type is `unknown`. +- [`IsEmptyObject`](source/empty-object.d.ts) - Returns a boolean for whether the type is strictly equal to an empty plain object, the `{}` value. +- [`IsNull`](source/is-null.d.ts) - Returns a boolean for whether the given type is `null`. +- [`IsUndefined`](source/is-undefined.d.ts) - Returns a boolean for whether the given type is `undefined`. +- [`IsTuple`](source/is-tuple.d.ts) - Returns a boolean for whether the given array is a tuple. +- [`IsUnion`](source/is-union.d.ts) - Returns a boolean for whether the given type is a union. +- [`IsLowercase`](source/is-lowercase.d.ts) - Returns a boolean for whether the given string literal is lowercase. +- [`IsUppercase`](source/is-uppercase.d.ts) - Returns a boolean for whether the given string literal is uppercase. +- [`IsOptional`](source/is-optional.d.ts) - Returns a boolean for whether the given type includes `undefined`. +- [`IsNullable`](source/is-nullable.d.ts) - Returns a boolean for whether the given type includes `null`. +- [`IsOptionalKeyOf`](source/is-optional-key-of.d.ts) - Returns a boolean for whether the given key is an optional key of type. +- [`IsRequiredKeyOf`](source/is-required-key-of.d.ts) - Returns a boolean for whether the given key is a required key of type. +- [`IsReadonlyKeyOf`](source/is-readonly-key-of.d.ts) - Returns a boolean for whether the given key is a readonly key of type. +- [`IsWritableKeyOf`](source/is-writable-key-of.d.ts) - Returns a boolean for whether the given key is a writable key of type. + +### JSON + +- [`Jsonify`](source/jsonify.d.ts) - Transform a type to one that is assignable to the `JsonValue` type. +- [`Jsonifiable`](source/jsonifiable.d.ts) - Matches a value that can be losslessly converted to JSON. +- [`JsonPrimitive`](source/json-value.d.ts) - Matches any valid JSON primitive value. +- [`JsonObject`](source/json-value.d.ts) - Matches a JSON object. +- [`JsonArray`](source/json-value.d.ts) - Matches a JSON array. +- [`JsonValue`](source/json-value.d.ts) - Matches any valid JSON value. + +### Structured clone + +- [`StructuredCloneable`](source/structured-cloneable.d.ts) - Matches a value that can be losslessly cloned using `structuredClone`. + +### Async + +- [`Promisable`](source/promisable.d.ts) - Create a type that represents either the value or the value wrapped in `PromiseLike`. +- [`AsyncReturnType`](source/async-return-type.d.ts) - Unwrap the return type of a function that returns a `Promise`. +- [`Asyncify`](source/asyncify.d.ts) - Create an async version of the given function type, by boxing the return type in `Promise` while keeping the same parameter types. + +### String + +- [`Trim`](source/trim.d.ts) - Remove leading and trailing spaces from a string. +- [`Split`](source/split.d.ts) - Represents an array of strings split using a given character or character set. +- [`Words`](source/words.d.ts) - Split a string similar to Lodash's `_.words()` function. +- [`Replace`](source/replace.d.ts) - Represents a string with some or all matches replaced by a replacement. +- [`StringSlice`](source/string-slice.d.ts) - Returns a string slice of a given range, just like `String#slice()`. +- [`StringRepeat`](source/string-repeat.d.ts) - Returns a new string which contains the specified number of copies of a given string, just like `String#repeat()`. +- [`RemovePrefix`](source/remove-prefix.d.ts) - Remove the specified prefix from the start of a string. +- [`RemoveSuffix`](source/remove-suffix.d.ts) - Remove the specified suffix from the end of a string. +- [`StringToArray`](source/string-to-array.d.ts) - Returns an array of the characters of the specified string. +- [`StringLength`](source/string-length.d.ts) - Returns the length of the given string. + +### Array + +- [`Arrayable`](source/arrayable.d.ts) - Create a type that represents either the value or an array of the value. +- [`Includes`](source/includes.d.ts) - Returns a boolean for whether the given array includes the given item. +- [`Join`](source/join.d.ts) - Join an array of strings and/or numbers using the given string as a delimiter. +- [`ArraySlice`](source/array-slice.d.ts) - Returns an array slice of a given range, just like `Array#slice()`. +- [`ArrayElement`](source/array-element.d.ts) - Extracts the element type of an array or tuple. +- [`LastArrayElement`](source/last-array-element.d.ts) - Extract the type of the last element of an array. +- [`FixedLengthArray`](source/fixed-length-array.d.ts) - Create a type that represents an array of the given type and length. The `Array` prototype methods that manipulate its length are excluded from the resulting type. +- [`MultidimensionalArray`](source/multidimensional-array.d.ts) - Create a type that represents a multidimensional array of the given type and dimension. +- [`MultidimensionalReadonlyArray`](source/multidimensional-readonly-array.d.ts) - Create a type that represents a multidimensional readonly array of the given type and dimension. +- [`ReadonlyTuple`](source/readonly-tuple.d.ts) - Create a type that represents a read-only tuple of the given type and length. +- [`TupleToUnion`](source/tuple-to-union.d.ts) - Convert a tuple/array into a union type of its elements. +- [`UnionToTuple`](source/union-to-tuple.d.ts) - Convert a union type into an unordered tuple type of its elements. +- [`TupleToObject`](source/tuple-to-object.d.ts) - Transforms a tuple into an object, mapping each tuple index to its corresponding type as a key-value pair. +- [`TupleOf`](source/tuple-of.d.ts) - Create a tuple type of the specified length with elements of the specified type. +- [`SplitOnRestElement`](source/split-on-rest-element.d.ts) - Splits an array into three parts, where the first contains all elements before the rest element, the second is the [`rest`](https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types) element itself, and the third contains all elements after the rest element. +- [`ExtractRestElement`](source/extract-rest-element.d.ts) - Extract the [`rest`](https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types) element type from an array. +- [`ExcludeRestElement`](source/exclude-rest-element.d.ts) - Create a tuple with the [`rest`](https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types) element removed. +- [`ArrayReverse`](source/array-reverse.d.ts) - Reverse the order of elements in a tuple type. +- [`ArrayLength`](source/array-length.d.ts) - Return the length of an array. Equivalent to `T['length']` where `T` extends any array. + +### Numeric + +- [`PositiveInfinity`](source/numeric.d.ts) - Matches the hidden `Infinity` type. +- [`NegativeInfinity`](source/numeric.d.ts) - Matches the hidden `-Infinity` type. +- [`Finite`](source/numeric.d.ts) - A finite `number`. +- [`Integer`](source/numeric.d.ts) - A `number` that is an integer. +- [`Float`](source/numeric.d.ts) - A `number` that is not an integer. +- [`NegativeFloat`](source/numeric.d.ts) - A negative (`-∞ < x < 0`) `number` that is not an integer. +- [`Negative`](source/numeric.d.ts) - A negative `number`/`bigint` (`-∞ < x < 0`) +- [`NonNegative`](source/numeric.d.ts) - A non-negative `number`/`bigint` (`0 <= x < ∞`). +- [`NegativeInteger`](source/numeric.d.ts) - A negative (`-∞ < x < 0`) `number` that is an integer. +- [`NonNegativeInteger`](source/numeric.d.ts) - A non-negative (`0 <= x < ∞`) `number` that is an integer. +- [`IsNegative`](source/numeric.d.ts) - Returns a boolean for whether the given number is a negative number. +- [`IsFloat`](source/is-float.d.ts) - Returns a boolean for whether the given number is a float, like `1.5` or `-1.5`. +- [`IsInteger`](source/is-integer.d.ts) - Returns a boolean for whether the given number is an integer, like `-5`, `1.0`, or `100`. +- [`GreaterThan`](source/greater-than.d.ts) - Returns a boolean for whether a given number is greater than another number. +- [`GreaterThanOrEqual`](source/greater-than-or-equal.d.ts) - Returns a boolean for whether a given number is greater than or equal to another number. +- [`LessThan`](source/less-than.d.ts) - Returns a boolean for whether a given number is less than another number. +- [`LessThanOrEqual`](source/less-than-or-equal.d.ts) - Returns a boolean for whether a given number is less than or equal to another number. +- [`Sum`](source/sum.d.ts) - Returns the sum of two numbers. +- [`Subtract`](source/subtract.d.ts) - Returns the difference between two numbers. +- [`UnionMax`](source/union-max.d.ts) - Returns the maximum number in a union of numbers. +- [`Absolute`](source/absolute.d.ts) - Returns the absolute value of the specified number or bigint. +- [`StringToNumber`](source/string-to-number.d.ts) - Converts a numeric string to a number. + +### Change case + +- [`CamelCase`](source/camel-case.d.ts) - Convert a string literal to camel-case. +- [`CamelCasedProperties`](source/camel-cased-properties.d.ts) - Convert top-level object properties to camel case. +- [`CamelCasedPropertiesDeep`](source/camel-cased-properties-deep.d.ts) - Convert object properties to camel case recursively. +- [`KebabCase`](source/kebab-case.d.ts) - Convert a string literal to kebab-case. +- [`KebabCasedProperties`](source/kebab-cased-properties.d.ts) - Convert top-level object properties to kebab case. +- [`KebabCasedPropertiesDeep`](source/kebab-cased-properties-deep.d.ts) - Convert object properties to kebab case recursively. +- [`PascalCase`](source/pascal-case.d.ts) - Convert a string literal to pascal-case. +- [`PascalCasedProperties`](source/pascal-cased-properties.d.ts) - Convert top-level object properties to pascal case. +- [`PascalCasedPropertiesDeep`](source/pascal-cased-properties-deep.d.ts) - Convert object properties to pascal case recursively. +- [`SnakeCase`](source/snake-case.d.ts) - Convert a string literal to snake-case. +- [`SnakeCasedProperties`](source/snake-cased-properties.d.ts) - Convert top-level object properties to snake case. +- [`SnakeCasedPropertiesDeep`](source/snake-cased-properties-deep.d.ts) - Convert object properties to snake case recursively. +- [`ScreamingSnakeCase`](source/screaming-snake-case.d.ts) - Convert a string literal to screaming-snake-case. +- [`DelimiterCase`](source/delimiter-case.d.ts) - Convert a string literal to a custom string delimiter casing. +- [`DelimiterCasedProperties`](source/delimiter-cased-properties.d.ts) - Convert object properties to a custom string delimiter casing. +- [`DelimiterCasedPropertiesDeep`](source/delimiter-cased-properties-deep.d.ts) - Convert object properties to a custom string delimiter casing recursively. + +### Miscellaneous + +- [`GlobalThis`](source/global-this.d.ts) - Declare locally scoped properties on `globalThis`. +- [`PackageJson`](source/package-json.d.ts) - Type for [npm's `package.json` file](https://docs.npmjs.com/creating-a-package-json-file). Also includes types for fields used by other popular projects, like TypeScript and Yarn. +- [`TsConfigJson`](source/tsconfig-json.d.ts) - Type for [TypeScript's `tsconfig.json` file](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html). + +### Improved built-in + +- [`ExtendsStrict`](source/extends-strict.d.ts) - A customizable version of `extends` for checking whether one type is assignable to another. +- [`ExtractStrict`](source/extract-strict.d.ts) - A stricter version of `Extract` that ensures every member of `U` can successfully extract something from `T`. +- [`ExcludeStrict`](source/exclude-strict.d.ts) - A stricter version of `Exclude` that ensures every member of `U` can successfully exclude something from `T`. +- [`ExcludeExactly`](source/exclude-exactly.d.ts) - A stricter version of `Exclude` that excludes types only when they are exactly identical. +- [`ExtractExactly`](source/extract-exactly.d.ts) - A stricter version of `Extract` that extracts types only when they are exactly identical. + +## Declined types + +*If we decline a type addition, we will make sure to document the better solution here.* + +- [`Diff` and `Spread`](https://github.com/sindresorhus/type-fest/pull/7) - The pull request author didn't provide any real-world use-cases and the PR went stale. If you think this type is useful, provide some real-world use-cases and we might reconsider. +- [`Dictionary`](https://github.com/sindresorhus/type-fest/issues/33) - You only save a few characters (`Dictionary` vs `Record`) from [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type), which is more flexible and well-known. Also, you shouldn't use an object as a dictionary. We have `Map` in JavaScript now. +- [`ExtractProperties` and `ExtractMethods`](https://github.com/sindresorhus/type-fest/pull/4) - The types violate the single responsibility principle. Instead, refine your types into more granular type hierarchies. +- [`Url2Json`](https://github.com/sindresorhus/type-fest/pull/262) - Inferring search parameters from a URL string is a cute idea, but not very useful in practice, since search parameters are usually dynamic and defined separately. +- [`Nullish`](https://github.com/sindresorhus/type-fest/pull/318) - The type only saves a couple of characters, not everyone knows what "nullish" means, and I'm also trying to [get away from `null`](https://github.com/sindresorhus/meta/discussions/7). +- [`TitleCase`](https://github.com/sindresorhus/type-fest/pull/303) - It's not solving a common need and is a better fit for a separate package. +- [`ExtendOr` and `ExtendAnd`](https://github.com/sindresorhus/type-fest/pull/247) - The benefits don't outweigh having to learn what they mean. +- [`PackageJsonExtras`](https://github.com/sindresorhus/type-fest/issues/371) - There are too many possible configurations that can be put into `package.json`. If you would like to extend `PackageJson` to support an additional configuration in your project, please see the *Extending existing types* section below. + +## Alternative type names + +*If you know one of our types by a different name, add it here for discovery.* + +- `Prettify`- See [`Simplify`](source/simplify.d.ts) +- `Expand`- See [`Simplify`](source/simplify.d.ts) +- `PartialBy` - See [`SetOptional`](source/set-optional.d.ts) +- `RecordDeep`- See [`Schema`](source/schema.d.ts) +- `Mutable`- See [`Writable`](source/writable.d.ts) +- `RequireOnlyOne`, `OneOf` - See [`RequireExactlyOne`](source/require-exactly-one.d.ts) +- `AtMostOne` - See [`RequireOneOrNone`](source/require-one-or-none.d.ts) +- `AllKeys` - See [`KeysOfUnion`](source/keys-of-union.d.ts) +- `Branded` - See [`Tagged`](source/tagged.d.ts) +- `Opaque` - See [`Tagged`](source/tagged.d.ts) +- `SetElement` - See [`IterableElement`](source/iterable-element.d.ts) +- `SetEntry` - See [`IterableElement`](source/iterable-element.d.ts) +- `SetValues` - See [`IterableElement`](source/iterable-element.d.ts) +- `PickByTypes` - See [`ConditionalPick`](source/conditional-pick.d.ts) +- `HomomorphicOmit` - See [`Except`](source/except.d.ts) +- `IfAny`, `IfNever`, `If*` - See [`If`](source/if.d.ts) +- `Maybe`, `Option` - See [`Optional`](source/optional.d.ts) +- `MaybePromise` - See [`Promisable`](source/promisable.d.ts) +- `ReadonlyTuple` - See [`TupleOf`](source/tuple-of.d.ts) +- `LastOfUnion` - See [`UnionMember`](source/union-member.d.ts) +- `FirstOfUnion` - See [`UnionMember`](source/union-member.d.ts) + +## Tips + +### Extending existing types + + +- [`PackageJson`](source/package-json.d.ts) - There are a lot of tools that place extra configurations inside the `package.json` file. You can extend `PackageJson` to support these additional configurations. +
+ + Example + + + [Playground](https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBDAnmApnA3gBQIYGMDW2A5igFIDOEAdnNuXAEJ0o4HFmVUC+cAZlBBBwA5ElQBaXinIxhAbgCwAKFCRYCZGnQAZYFRgooPfoJHSANntmKlysWlaESFanAC8jZo-YuaAMgwLKwBhal5gIgB+AC44XX1DADpQqnCiLhsgA) + + ```ts + import type {PackageJson as BasePackageJson} from 'type-fest'; + import type {Linter} from 'eslint'; + + type PackageJson = BasePackageJson & {eslintConfig?: Linter.Config}; + ``` +
+ +### Related + +- [typed-query-selector](https://github.com/g-plane/typed-query-selector) - Enhances `document.querySelector` and `document.querySelectorAll` with a template literal type that matches element types returned from an HTML element query selector. +- [`Linter.Config`](https://github.com/eslint/eslint/blob/main/lib/types/index.d.ts) - Definitions for the [ESLint configuration schema](https://eslint.org/docs/user-guide/configuring/language-options). + +### Built-in types + +There are many advanced types most users don't know about. + + +- [`Awaited`](https://www.typescriptlang.org/docs/handbook/utility-types.html#awaitedtype) - Extract the type of a value that a `Promise` resolves to. +
+ + Example + + + [Playground](https://www.typescriptlang.org/play/?#code/JYOwLgpgTgZghgYwgAgKoGdrIN4FgBQyyAkMACYBcyIArgLYBG0A3AUcSHHRFemFKADmrQiTiCe1ekygiiAXwJtkCADZx06NJigBBAA7AAytABuwJDmXENATxAJkMCGAQALDNAAUNHQElKKUZoAEoqAAUoAHs6YEwAHk8oAD4rUWJiAHpM5AAxF3dkMDcUXywyODA4J2i6IpLkCqqGDQgAOmssnIAVBsQwGjhVZGA6fVUIbnBK4CiQZFjBNzBkVSiogGtV4A2UYriKTuyVOb5kKAh0fVOUAF5kOAB3OGAV51c3LwAiTLhDTLKUEyABJsICAvIQnISF0TiAzk1qvcLlcbm0AFboOZeKFHHIXAZQeaI6EZAk0Ik4EaBACMABpqFxJF8AFJRNzzAAiUQgXwZ4kkAGYAAzIeSkxSiSXKMC2fQofIfCBkJLIe66Z6vZXxABKLgpIG6cogiR0BmMZgsEAA2l93u4kl8ALrJZIiZR2BxOGgOMCzeZuOAgMgTJKcypwLx-C1QcxIKhJc0mWNWhngwK0YJQEJpdj8Wy5mEIU4rQFURXuZWq+5PF4raPJuPte0eHQ+fxkXHpWG6GCQKBOApuITIQGNCMM2xRGgqIPIeWwKJQOqmOACadafr+rToGiFDSj-RNEfFUo6EbgaDwJB0vGz9wnhqImpRb2Es8QBlLhZwDYjuBkGQrz+kMyC6OEfjnBAACONCXGAm5aCAEDKsqHTpPIs4fMgXjQNE2aFhkxx4d+gbBqoQjWJKChKKIxbwqWZqGI2VpqtQECPNo0BJpaSA4tCZEhhAYYRu23HMbxn7IDSUJAA) + + ```ts + interface User { + id: number; + name: string; + age: number; + } + + class UserApiService { + async fetchUser(userId: number): Promise { + // Fetch the user data from the database. + // The actual implementation might look like this: + // const response = await fetch('/api/user/${userId}'); + // const data = response.json(); + // return data; + return { + id: 1, + name: 'John Doe', + age: 30 + }; + } + } + + type FetchedUser = Awaited>; + + async function handleUserData(apiService: UserApiService, userId: number) { + try { + const user: FetchedUser = await apiService.fetchUser(userId); + // After fetching user data, you can perform various actions such as updating the user interface, + // caching the data for future use, or making additional API requests as needed. + } catch (error) { + // Error handling + } + } + + const userApiService = new UserApiService(); + handleUserData(userApiService, 1); + ``` + +- [`Partial`](https://www.typescriptlang.org/docs/handbook/utility-types.html#partialtype) - Make all properties in `T` optional. +
+ + Example + + + [Playground](https://www.typescriptlang.org/play/#code/JYOwLgpgTgZghgYwgAgHIHsAmEDC6QzADmyA3gLABQyycADnanALYQBcyAzmFKEQNxUaddFDAcQAV2YAjaIMoBfKlQQAbOJ05osEAIIMAQpOBrsUMkOR1eANziRkCfISKSoD4Pg4ZseAsTIALyW1DS0DEysHADkvvoMMQA0VsKi4sgAzAAMuVaKClY2wPaOknSYDrguADwA0sgQAB6QIJjaANYQAJ7oMDp+LsQAfAAUXd0cdUnI9mo+uv6uANp1ALoAlKHhyGAAFsCcAHTOAW4eYF4gyxNrwbNwago0ypRWp66jH8QcAApwYmAjxq8SWIy2FDCNDA3ToKFBQyIdR69wmfQG1TOhShyBgomQX3w3GQE2Q6IA8jIAFYQBBgI4TTiEs5bTQYsFInrLTbbHZOIlgZDlSqQABqj0kKBC3yINx6a2xfOQwH6o2FVXFaklwSCIUkbQghBAEEwENSfNOlykEGefNe5uhB2O6sgS3GPRmLogmslG1tLxUOKgEDA7hAuydtteryAA) + + ```ts + interface NodeConfig { + appName: string; + port: number; + } + + class NodeAppBuilder { + private configuration: NodeConfig = { + appName: 'NodeApp', + port: 3000 + }; + + private updateConfig(key: Key, value: NodeConfig[Key]) { + this.configuration[key] = value; + } + + config(config: Partial) { + type NodeConfigKey = keyof NodeConfig; + + for (const key of Object.keys(config) as NodeConfigKey[]) { + const updateValue = config[key]; + + if (updateValue === undefined) { + continue; + } + + this.updateConfig(key, updateValue); + } + + return this; + } + } + + // `Partial`` allows us to provide only a part of the + // NodeConfig interface. + new NodeAppBuilder().config({appName: 'ToDoApp'}); + ``` + + `Partial` can be reverted with [`UnwrapPartial`](source/unwrap-partial.d.ts). +
+ +- [`Required`](https://www.typescriptlang.org/docs/handbook/utility-types.html#requiredtype) - Make all properties in `T` required. +
+ + Example + + + [Playground](https://typescript-play.js.org/?target=6#code/AQ4SwOwFwUwJwGYEMDGNgGED21VQGJZwC2wA3gFCjXAzFJgA2A-AFzADOUckA5gNxUaIYjA4ckvGG07c+g6gF8KQkAgCuEFFDA5O6gEbEwUbLm2ESwABQIixACJIoSdgCUYAR3Vg4MACYAPGYuFvYAfACU5Ko0APRxwADKMBD+wFAAFuh2Vv7OSBlYGdmc8ABu8LHKsRyGxqY4oQT21pTCIHQMjOwA5DAAHgACxAAOjDAAdChYxL0ANLHUouKSMH0AEmAAhJhY6ozpAJ77GTCMjMCiV0ToSAb7UJPPC9WRgrEJwAAqR6MwSRQPFGUFocDgRHYxnEfGAowh-zgUCOwF6KwkUl6tXqJhCeEsxDaS1AXSYfUGI3GUxmc0WSneQA) + + ```ts + interface ContactForm { + email?: string; + message?: string; + } + + function submitContactForm(formData: Required) { + // Send the form data to the server. + } + + submitContactForm({ + email: 'ex@mple.com', + message: 'Hi! Could you tell me more about…', + }); + + // TypeScript error: missing property 'message' + submitContactForm({ + email: 'ex@mple.com', + }); + ``` + + `Required` can be reverted with [`UnwrapRequired`](source/unwrap-required.d.ts). +
+ +- [`Readonly`](https://www.typescriptlang.org/docs/handbook/utility-types.html#readonlytype) - Make all properties in `T` readonly. +
+ + Example + + + [Playground](https://typescript-play.js.org/?target=6#code/AQ4UwOwVwW2AZA9gc3mAbmANsA3gKFCOAHkAzMgGkOJABEwAjKZa2kAUQCcvEu32AMQCGAF2FYBIAL4BufDRABLCKLBcywgMZgEKZOoDCiCGSXI8i4hGEwwALmABnUVxXJ57YFgzZHSVF8sT1BpBSItLGEnJz1kAy5LLy0TM2RHACUwYQATEywATwAeAITjU3MAPnkrCJMXLigtUT4AClxgGztKbyDgaX99I1TzAEokr1BRAAslJwA6FIqLAF48TtswHp9MHDla9hJGACswZvmyLjAwAC8wVpm5xZHkUZDaMKIwqyWXYCW0oN4sNlsA1h0ug5gAByACyBQAggAHJHQ7ZBIFoXbzBjMCz7OoQP5YIaJNYQMAAdziCVaALGNSIAHomcAACoFJFgADKWjcSNEwG4vC4ji0wggEEQguiTnMEGALWAV1yAFp8gVgEjeFyuKICvMrCTgVxnst5jtsGC4ljsPNhXxGaAWcAAOq6YRXYDCRg+RWIcA5JSC+kWdCepQ+v3RYCU3RInzRMCGwlpC19NYBW1Ye08R1AA) + + ```ts + enum LogLevel { + Off, + Debug, + Error, + Fatal + }; + + interface LoggerConfig { + name: string; + level: LogLevel; + } + + class Logger { + config: Readonly; + + constructor({name, level}: LoggerConfig) { + this.config = {name, level}; + Object.freeze(this.config); + } + } + + const config: LoggerConfig = { + name: 'MyApp', + level: LogLevel.Debug + }; + + const logger = new Logger(config); + + // TypeScript Error: cannot assign to read-only property. + logger.config.level = LogLevel.Error; + + // We are able to edit config variable as we please. + config.level = LogLevel.Error; + ``` +
+ +- [`Pick`](https://www.typescriptlang.org/docs/handbook/utility-types.html#picktype-keys) - From `T`, pick a set of properties whose keys are in the union `K`. +
+ + Example + + + [Playground](https://typescript-play.js.org/?target=6#code/AQ4SwOwFwUwJwGYEMDGNgEE5TCgNugN4BQoZwOUBAXMAM5RyQDmA3KeSFABYCuAtgCMISMHloMmENh04oA9tBjQJjFuzIBfYrOAB6PcADCcGElh1gEGAHcKATwAO6ebyjB5CTNlwFwSxFR0BX5HeToYABNgBDh5fm8cfBg6AHIKG3ldA2BHOOcfFNpUygJ0pAhokr4hETFUgDpswywkggAFUwA3MFtgAF5gQgowKhhVKTYKGuFRcXo1aVZgbTIoJ3RW3xhOmB6+wfbcAGsAHi3kgBpgEtGy4AAfG54BWfqAPnZm4AAlZUj4MAkMA8GAGB4vEgfMlLLw6CwPBA8PYRmMgZVgAC6CgmI4cIommQELwICh8RBgKZKvALh1ur0bHQABR5PYMui0Wk7em2ADaAF0AJS0AASABUALIAGQAogR+Mp3CROCAFBBwVC2ikBpj5CgBIqGjizLA5TAFdAmalImAuqlBRoVQh5HBgEy1eDWfs7J5cjzGYKhroVfpDEhHM4MV6GRR5NN0JrtnRg6BVirTFBeHAKYmYY6QNpdB73LmCJZBlSAXAubtvczeSmQMNSuMbmKNgBlHFgPEUNwusBIPAAQlS1xetTmxT0SDoESgdD0C4aACtHMwxytLrohawgA) + + ```ts + interface Article { + title: string; + thumbnail: string; + content: string; + } + + // Creates new type out of the `Article` interface composed + // from the Articles' two properties: `title` and `thumbnail`. + // `ArticlePreview = {title: string; thumbnail: string}` + type ArticlePreview = Pick; + + // Render a list of articles using only title and description. + function renderArticlePreviews(previews: ArticlePreview[]): HTMLElement { + const articles = document.createElement('div'); + + for (const preview of previews) { + // Append preview to the articles. + } + + return articles; + } + + const articles = renderArticlePreviews([ + { + title: 'TypeScript tutorial!', + thumbnail: '/assets/ts.jpg' + } + ]); + ``` +
+ +- [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type) - Construct a type with a set of properties `K` of type `T`. +
+ + Example + + + [Playground](https://typescript-play.js.org/?target=6#code/AQ4ejYAUHsGcCWAXBMB2dgwGbAKYC2ADgDYwCeeemCaWArgE7ADGMxAhmuQHQBQoYEnJE8wALKEARnkaxEKdMAC8wAOS0kstGuAAfdQBM8ANzxlRjXQbVaWACwC0JPB0NqA3HwGgIwAJJoWozYHCxixnAsjAhStADmwESMMJYo1Fi4HMCIaPEu+MRklHj8gpqyoeHAAKJFFFTAAN4+giDYCIxwSAByHAR4AFw5SDF5Xm2gJBzdfQPD3WPxE5PAlBxdAPLYNQAelgh4aOHDaPQEMowrIAC+3oJ+AMKMrlrAXFhSAFZ4LEhC9g4-0BmA4JBISXgiCkBQABpILrJ5MhUGhYcATGD6Bk4Hh-jNgABrPDkOBlXyQAAq9ngYmJpOAAHcEOCRjAXqwYODfoo6DhakUSph+Uh7GI4P0xER4Cj0OSQGwMP8tP1hgAlX7swwAHgRl2RvIANALSA08ABtAC6AD4VM1Wm0Kow0MMrYaHYJjGYLLJXZb3at1HYnC43Go-QHQDcvA6-JsmEJXARgCDgMYWAhjIYhDAU+YiMAAFIwex0ZmilMITCGF79TLAGRsAgJYAAZRwSEZGzEABFTOZUrJ5Yn+jwnWgeER6HB7AAKJrADpdXqS4ZqYultTG6azVfqHswPBbtauLY7fayQ7HIbAAAMwBuAEoYw9IBq2Ixs9h2eFMOQYPQObALQKJgggABeYhghCIpikkKRpOQRIknAsZUiIeCttECBEP8NSMCkjDDAARMGziuIYxHwYOjDCMBmDNnAuTxA6irdCOBB1Lh5Dqpqn66tISIykawBnOCtqqC0gbjqc9DgpGkxegOliyfJDrRkAA) + + ```ts + // Positions of employees in our company. + type MemberPosition = 'intern' | 'developer' | 'tech-lead'; + + // Interface describing properties of a single employee. + interface Employee { + firstName: string; + lastName: string; + yearsOfExperience: number; + } + + // Create an object that has all possible `MemberPosition` values set as keys. + // Those keys will store a collection of Employees of the same position. + const team: Record = { + intern: [], + developer: [], + 'tech-lead': [], + }; + + // Our team has decided to help John with his dream of becoming Software Developer. + team.intern.push({ + firstName: 'John', + lastName: 'Doe', + yearsOfExperience: 0 + }); + + // `Record` forces you to initialize all of the property keys. + // TypeScript Error: "tech-lead" property is missing + const teamEmpty: Record = { + intern: null, + developer: null, + }; + ``` +
+ +- [`Exclude`](https://www.typescriptlang.org/docs/handbook/utility-types.html#excludetype-excludedunion) - Exclude from `T` those types that are assignable to `U`. +
+ + Example + + + [Playground](https://typescript-play.js.org/?target=6#code/JYOwLgpgTgZghgYwgAgMrQG7QMIHsQzADmyA3gFDLIAOuUYAXMiAK4A2byAPsgM5hRQJHqwC2AI2gBucgF9y5MAE9qKAEoQAjiwj8AEnBAATNtGQBeZAAooWphu26wAGmS3e93bRC8IASgsAPmRDJRlyAHoI5ABRAA8ENhYjFFYOZGVVZBgoXFFkAAM0zh5+QRBhZhYJaAKAOkjogEkQZAQ4X2QAdwALCFbaemRgXmQtFjhOMFwq9K6ULuB0lk6U+HYwZAxJnQaYFhAEMGB8ZCIIMAAFOjAANR2IK0HGWISklIAedCgsKDwCYgAbQA5M9gQBdVzFQJ+JhiSRQMiUYYwayZCC4VHPCzmSzAspCYEBWxgFhQAZwKC+FpgJ43VwARgADH4ZFQSWSBjcZPJyPtDsdTvxKWBvr8rD1DCZoJ5HPopaYoK4EPhCEQmGKcKriLCtrhgEYkVQVT5Nr4fmZLLZtMBbFZgT0wGBqES6ghbHBIJqoBKFdBWQpjfh+DQbhY2tqiHVsbjLMVkAB+ZAAZiZaeQTHOVxu9ySjxNaujNwDVHNvzqbBGkBAdPoAfkQA) + + ```ts + interface ServerConfig { + port: null | string | number; + } + + type RequestHandler = (request: Request, response: Response) => void; + + // Exclude `null` type from `null | string | number`. + // In case the port is equal to `null`, we will use default value. + function getPortValue(port: Exclude): number { + if (typeof port === 'string') { + return parseInt(port, 10); + } + + return port; + } + + function startServer(handler: RequestHandler, config: ServerConfig): void { + const server = require('http').createServer(handler); + + const port = config.port === null ? 3000 : getPortValue(config.port); + server.listen(port); + } + ``` +
+ +- [`Extract`](https://www.typescriptlang.org/docs/handbook/utility-types.html#extracttype-union) - Extract from `T` those types that are assignable to `U`. +
+ + Example + + + [Playground](https://typescript-play.js.org/?target=6#code/CYUwxgNghgTiAEAzArgOzAFwJYHtXzSwEdkQBJYACgEoAueVZAWwCMQYBuAKDDwGcM8MgBF4AXngBlAJ6scESgHIRi6ty5ZUGdoihgEABXZ888AN5d48ANoiAuvUat23K6ihMQ9ATE0BzV3goPy8GZjZOLgBfLi4Aejj4AEEICBwAdz54MAALKFQQ+BxEeAAHY1NgKAwoIKy0grr4DByEUpgccpgMaXgAaxBerCzi+B9-ZulygDouFHRsU1z8kKMYE1RhaqgAHkt4AHkWACt4EAAPbVRgLLWNgBp9gGlBs8uQa6yAUUuYPQwdgNpKM7nh7mMML4CgA+R5WABqUAgpDeVxuhxO1he0jsXGh8EoOBO9COx3BQPo2PBADckaR6IjkSA6PBqTgsMBzPsicdrEC7OJWXSQNwYvFEgAVTS9JLXODpeDpKBZFg4GCoWa8VACIJykAKiQWKy2YQOAioYikCg0OEMDyhRSy4DyxS24KhAAMjyi6gS8AAwjh5OD0iBFHAkJoEOksC1mnkMJq8gUQKDNttKPlnfrwYp3J5XfBHXqoKpfYkAOI4ansTxaeDADmoRSCCBYAbxhC6TDx6rwYHIRX5bScjA4bLJwoDmDwDkfbA9JMrVMVdM1TN69LgkTgwgkchUahqIA) + + ```ts + declare function uniqueId(): number; + + const ID = Symbol('ID'); + + interface Person { + [ID]: number; + name: string; + age: number; + } + + // Allows changing the person data as long as the property key is of string type. + function changePersonData< + Obj extends Person, + Key extends Extract, + Value extends Obj[Key] + > (obj: Obj, key: Key, value: Value): void { + obj[key] = value; + } + + // Tiny Andrew was born. + const andrew = { + [ID]: uniqueId(), + name: 'Andrew', + age: 0, + }; + + // Cool, we're fine with that. + changePersonData(andrew, 'name', 'Pony'); + + // Government didn't like the fact that you wanted to change your identity. + changePersonData(andrew, ID, uniqueId()); + ``` +
+ +- [`NonNullable`](https://www.typescriptlang.org/docs/handbook/utility-types.html#nonnullabletype) - Exclude `null` and `undefined` from `T`. +
+ + Example + + Works with strictNullChecks set to true. + + [Playground](https://typescript-play.js.org/?target=6#code/C4TwDgpgBACg9gJ2AOQK4FsBGEFQLxQDOwCAlgHYDmUAPlORtrnQwDasDcAUFwPQBU-WAEMkUOADMowqAGNWwwoSgATCBIqlgpOOSjAAFsOBRSy1IQgr9cKJlSlW1mZYQA3HFH68u8xcoBlHA8EACEHJ08Aby4oKDBUTFZSWXjEFEYcAEIALihkXTR2YSSIAB54JDQsHAA+blj4xOTUsHSACkMzPKD3HHDHNQQAGjSkPMqMmoQASh7g-oihqBi4uNIpdraxPAI2VhmVxrX9AzMAOm2ppnwoAA4ABifuE4BfKAhWSyOTuK7CS7pao3AhXF5rV48E4ICDAVAIPT-cGQyG+XTEIgLMJLTx7CAAdygvRCA0iCHaMwarhJOIQjUBSHaACJHk8mYdeLwxtdcVAAOSsh58+lXdr7Dlcq7A3n3J4PEUdADMcspUE53OluAIUGVTx46oAKuAIAFZGQwCYAKIIBCILjUxaDHAMnla+iodjcIA) + + ```ts + type PortNumber = string | number | null; + + /** Part of a class definition that is used to build a server */ + class ServerBuilder { + portNumber!: NonNullable; + + port(this: ServerBuilder, port: PortNumber): ServerBuilder { + if (port == null) { + this.portNumber = 8000; + } else { + this.portNumber = port; + } + + return this; + } + } + + const serverBuilder = new ServerBuilder(); + + serverBuilder + .port('8000') // portNumber = '8000' + .port(null) // portNumber = 8000 + .port(3000); // portNumber = 3000 + + // TypeScript error + serverBuilder.portNumber = null; + ``` +
+ +- [`Parameters`](https://www.typescriptlang.org/docs/handbook/utility-types.html#parameterstype) - Obtain the parameters of a function type in a tuple. +
+ + Example + + + [Playground](https://typescript-play.js.org/?target=6#code/GYVwdgxgLglg9mABAZwBYmMANgUwBQxgAOIUAXIgIZgCeA2gLoCUFAbnDACaIDeAUIkQB6IYgCypSlBxUATrMo1ECsJzgBbLEoipqAc0J7EMKMgDkiHLnU4wp46pwAPHMgB0fAL58+oSLARECEosLAA5ABUYG2QAHgAxJGdpVWREPDdMylk9ZApqemZEAF4APipacrw-CApEgBogkKwAYThwckQwEHUAIxxZJl4BYVEImiIZKF0oZRwiWVdbeygJmThgOYgcGFYcbhqApCJsyhtpWXcR1cnEePBoeDAABVPzgbTixFeFd8uEsClADcIxGiygIFkSEOT3SmTc2VydQeRx+ZxwF2QQ34gkEwDgsnSuFmMBKiAADEDjIhYk1Qm0OlSYABqZnYka4xA1DJZHJYkGc7yCbyeRA+CAIZCzNAYbA4CIAdxg2zJwVCkWirjwMswuEaACYmCCgA) + + ```ts + function shuffle(input: any[]): void { + // Mutate array randomly changing its' elements indexes. + } + + function callNTimes any> (func: Fn, callCount: number) { + // Type that represents the type of the received function parameters. + type FunctionParameters = Parameters; + + return function (...arguments_: FunctionParameters) { + for (let i = 0; i < callCount; i++) { + func(...arguments_); + } + } + } + + const shuffleTwice = callNTimes(shuffle, 2); + ``` +
+ +- [`ConstructorParameters`](https://www.typescriptlang.org/docs/handbook/utility-types.html#constructorparameterstype) - Obtain the parameters of a constructor function type in a tuple. +
+ + Example + + + [Playground](https://typescript-play.js.org/?target=6#code/MYGwhgzhAECCBOAXAlqApgWQPYBM0mgG8AoaaFRENALmgkXmQDsBzAblOmCycTV4D8teo1YdO3JiICuwRFngAKClWENmLAJRFOZRAAtkEAHQq00ALzlklNBzIBfYk+KhIMAJJTEYJsDQAwmDA+mgAPAAq0GgAHnxMODCKTGgA7tCKxllg8CwQtL4AngDaALraFgB80EWa1SRkAA6MAG5gfNAB4FABPDJyCrQR9tDNyG0dwMGhtBhgjWEiGgA00F70vv4RhY3hEZXVVinpc42KmuJkkv3y8Bly8EPaDWTkhiZd7r3e8LK3llwGCMXGQWGhEOsfH5zJlsrl8p0+gw-goAAo5MAAW3BaHgEEilU0tEhmzQ212BJ0ry4SOg+kg+gBBiMximIGA0nAfAQLGk2N4EAAEgzYcYcnkLsRdDTvNEYkYUKwSdCme9WdM0MYwYhFPSIPpJdTkAAzDKxBUaZX+aAAQgsVmkCTQxuYaBw2ng4Ok8CYcotSu8pMur09iG9vuObxZnx6SN+AyUWTF8MN0CcZE4Ywm5jZHK5aB5fP4iCFIqT4oRRTKRLo6lYVNeAHpG50wOzOe1zHr9NLQ+HoABybsD4HOKXXRA1JCoKhBELmI5pNaB6Fz0KKBAodDYPAgSUTmqYsAALx4m5nC6nW9nGq14KtaEUA9gR9PvuNCjQ9BgACNvcwNBtAcLiAA) + + ```ts + class ArticleModel { + title: string; + content?: string; + + constructor(title: string) { + this.title = title; + } + } + + class InstanceCache any)> { + private ClassConstructor: T; + private cache: Map> = new Map(); + + constructor (ctr: T) { + this.ClassConstructor = ctr; + } + + getInstance (...arguments_: ConstructorParameters): InstanceType { + const hash = this.calculateArgumentsHash(...arguments_); + + const existingInstance = this.cache.get(hash); + if (existingInstance !== undefined) { + return existingInstance; + } + + return new this.ClassConstructor(...arguments_); + } + + private calculateArgumentsHash(...arguments_: any[]): string { + // Calculate hash. + return 'hash'; + } + } + + const articleCache = new InstanceCache(ArticleModel); + const amazonArticle = articleCache.getInstance('Amazon forests burning!'); + ``` +
+ +- [`ReturnType`](https://www.typescriptlang.org/docs/handbook/utility-types.html#returntypetype) - Obtain the return type of a function type. +
+ + Example + + + [Playground](https://typescript-play.js.org/?target=6#code/MYGwhgzhAECSAmICmBlJAnAbgS2E6A3gFDTTwD2AcuQC4AW2AdgOYAUAlAFzSbnbyEAvkWFFQkGJSQB3GMVI1sNZNwg10TZgG4S0YOUY0kh1es07d+xmvQBXYDXLpWi5UlMaWAGj0GjJ6BtNdkJdBQYIADpXZGgAXmgYpB1ScOwoq38aeN9DYxoU6GFRKzVoJjUwRjwAYXJbPPRuAFkwAAcAHgAxBodsAx9GWwBbACMMAD4cxhloVraOCyYjdAAzMDxoOut1e0d0UNIZ6WhWSPOwdGYIbiqATwBtAF0uaHudUQB6ACpv6ABpJBINqJdAbADW0Do5BOw3u5R2VTwMHIq2gAANtjZ0bkbHsnFCwJh8ONjHp0EgwEZ4JFoN9PkRVr1FAZoMwkDRYIjqkgOrosepoEgAB7+eAwAV2BxOLy6ACCVxgIrFEoMeOl6AACpcwMMORgIB1JRMiBNWKVdhruJKfOdIpdrtwFddXlzKjyACp3Nq842HaDIbL6BrZBIVGhIpB1EMYSLsmjmtWW-YhAA+qegAAYLKQLQj3ZsEsdccmnGcLor2Dn8xGedHGpEIBzEzspfsfMHDNAANTQACMVaIljV5GQkRA5DYmIpVKQAgAJARO9le33BDXIyi0YuLW2nJFGLqkOvxFB0YPdBSaLZ0IwNzyPkO8-xkGgsLh8Al427a3hWAhXwwHA8EHT5PmgAB1bAQBAANJ24adKWpft72RaBUTgRBUCAj89HAM8xCTaBjggABRQx0DuHJv25P9dCkWRZVIAAiBjoFImpmjlFBgA0NpsjadByDacgIDAEAIAAQmYpjoGYgAZSBsmGPw6DtZiiFA8CoJguDmAQmoZ2QvtUKQLdoAYmBTwgdEiCAA) + + ```ts + /** Provides every element of the iterable `iter` into the `callback` function and stores the results in an array. */ + function mapIter< + Elem, + Func extends (elem: Elem) => any, + Ret extends ReturnType + >(iter: Iterable, callback: Func): Ret[] { + const mapped: Ret[] = []; + + for (const elem of iter) { + mapped.push(callback(elem)); + } + + return mapped; + } + + const setObject: Set = new Set(); + const mapObject: Map = new Map(); + + mapIter(setObject, (value: string) => value.indexOf('Foo')); // number[] + + mapIter(mapObject, ([key, value]: [number, string]) => { + return key % 2 === 0 ? value : 'Odd'; + }); // string[] + ``` +
+ +- [`InstanceType`](https://www.typescriptlang.org/docs/handbook/utility-types.html#instancetypetype) - Obtain the instance type of a constructor function type. +
+ + Example + + + [Playground](https://typescript-play.js.org/?target=6#code/MYGwhgzhAECSAmICmBlJAnAbgS2E6A3gFDTTwD2AcuQC4AW2AdgOYAUAlAFzSbnbyEAvkWFFQkGJSQB3GMVI1sNZNwg10TZgG4S0YOUY0kh1es07d+xmvQBXYDXLpWi5UlMaWAGj0GjJ6BtNdkJdBQYIADpXZGgAXmgYpB1ScOwoq38aeN9DYxoU6GFRKzVoJjUwRjwAYXJbPPRuAFkwAAcAHgAxBodsAx9GWwBbACMMAD4cxhloVraOCyYjdAAzMDxoOut1e0d0UNIZ6WhWSPOwdGYIbiqATwBtAF0uaHudUQB6ACpv6ABpJBINqJdAbADW0Do5BOw3u5R2VTwMHIq2gAANtjZ0bkbHsnFCwJh8ONjHp0EgwEZ4JFoN9PkRVr1FAZoMwkDRYIjqkgOrosepoEgAB7+eAwAV2BxOLy6ACCVxgIrFEoMeOl6AACpcwMMORgIB1JRMiBNWKVdhruJKfOdIpdrtwFddXlzKjyACp3Nq842HaDIbL6BrZBIVGhIpB1EMYSLsmjmtWW-YhAA+qegAAYLKQLQj3ZsEsdccmnGcLor2Dn8xGedHGpEIBzEzspfsfMHDNAANTQACMVaIljV5GQkRA5DYmIpVKQAgAJARO9le33BDXIyi0YuLW2nJFGLqkOvxFB0YPdBSaLZ0IwNzyPkO8-xkGgsLh8Al427a3hWAhXwwHA8EHT5PmgAB1bAQBAANJ24adKWpft72RaBUTgRBUCAj89HAM8xCTaBjggABRQx0DuHJv25P9dCkWRZVIAAiBjoFImpmjlFBgA0NpsjadByDacgIDAEAIAAQmYpjoGYgAZSBsmGPw6DtZiiFA8CoJguDmAQmoZ2QvtUKQLdoAYmBTwgdEiCAA) + + ```ts + class IdleService { + doNothing (): void {} + } + + class News { + title: string; + content: string; + + constructor(title: string, content: string) { + this.title = title; + this.content = content; + } + } + + const instanceCounter: Map = new Map(); + + interface Constructor { + new(...arguments_: any[]): any; + } + + // Keep track how many instances of `Constr` constructor have been created. + function getInstance< + Constr extends Constructor, + Arguments extends ConstructorParameters + >(constructor: Constr, ...arguments_: Arguments): InstanceType { + let count = instanceCounter.get(constructor) || 0; + + const instance = new constructor(...arguments_); + + instanceCounter.set(constructor, count + 1); + + console.log(`Created ${count + 1} instances of ${Constr.name} class`); + + return instance; + } + + + const idleService = getInstance(IdleService); + // Will log: `Created 1 instances of IdleService class` + const newsEntry = getInstance(News, 'New ECMAScript proposals!', 'Last month...'); + // Will log: `Created 1 instances of News class` + ``` +
+ +- [`Omit`](https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys) - Constructs a type by picking all properties from T and then removing K. +
+ + Example + + + [Playground](https://typescript-play.js.org/?target=6#code/JYOwLgpgTgZghgYwgAgIImAWzgG2QbwChlks4BzCAVShwC5kBnMKUcgbmKYAcIFgIjBs1YgOXMpSFMWbANoBdTiW5woFddwAW0kfKWEAvoUIB6U8gDCUCHEiNkICAHdkYAJ69kz4GC3JcPG4oAHteKDABBxCYNAxsPFBIWEQUCAAPJG4wZABySUFcgJAAEzMLXNV1ck0dIuCw6EjBADpy5AB1FAQ4EGQAV0YUP2AHDy8wEOQbUugmBLwtEIA3OcmQnEjuZBgQqE7gAGtgZAhwKHdkHFGwNvGUdDIcAGUliIBJEF3kAF5kAHlML4ADyPBIAGjyBUYRQAPnkqho4NoYQA+TiEGD9EAISIhPozErQMG4AASK2gn2+AApek9pCSXm8wFSQooAJQMUkAFQAsgAZACiOAgmDOOSIJAQ+OYyGl4DgoDmf2QJRCCH6YvALQQNjsEGFovF1NyJWAy1y7OUyHMyE+yRAuFImG4Iq1YDswHxbRINjA-SgfXlHqVUE4xiAA) + + ```ts + interface Animal { + imageUrl: string; + species: string; + images: string[]; + paragraphs: string[]; + } + + // Creates new type with all properties of the `Animal` interface + // except 'images' and 'paragraphs' properties. We can use this + // type to render small hover tooltip for a wiki entry list. + type AnimalShortInfo = Omit; + + function renderAnimalHoverInfo (animals: AnimalShortInfo[]): HTMLElement { + const container = document.createElement('div'); + // Internal implementation. + return container; + } + ``` +
+ +- [`Uppercase`](https://www.typescriptlang.org/docs/handbook/utility-types.html#uppercasestringtype) - Transforms every character in a string into uppercase. +
+ + Example + + + ```ts + type T = Uppercase<'hello'>; // 'HELLO' + + type T2 = Uppercase<'foo' | 'bar'>; // 'FOO' | 'BAR' + + type T3 = Uppercase<`aB${S}`>; + type T4 = T3<'xYz'>; // 'ABXYZ' + + type T5 = Uppercase; // string + type T6 = Uppercase; // any + type T7 = Uppercase; // never + type T8 = Uppercase<42>; // Error, type 'number' does not satisfy the constraint 'string' + ``` +
+ +- [`Lowercase`](https://www.typescriptlang.org/docs/handbook/utility-types.html#lowercasestringtype) - Transforms every character in a string into lowercase. +
+ + Example + + + ```ts + type T = Lowercase<'HELLO'>; // 'hello' + + type T2 = Lowercase<'FOO' | 'BAR'>; // 'foo' | 'bar' + + type T3 = Lowercase<`aB${S}`>; + type T4 = T3<'xYz'>; // 'abxyz' + + type T5 = Lowercase; // string + type T6 = Lowercase; // any + type T7 = Lowercase; // never + type T8 = Lowercase<42>; // Error, type 'number' does not satisfy the constraint 'string' + ``` +
+ +- [`Capitalize`](https://www.typescriptlang.org/docs/handbook/utility-types.html#capitalizestringtype) - Transforms the first character in a string into uppercase. +
+ + Example + + + ```ts + type T = Capitalize<'hello'>; // 'Hello' + + type T2 = Capitalize<'foo' | 'bar'>; // 'Foo' | 'Bar' + + type T3 = Capitalize<`aB${S}`>; + type T4 = T3<'xYz'>; // 'ABxYz' + + type T5 = Capitalize; // string + type T6 = Capitalize; // any + type T7 = Capitalize; // never + type T8 = Capitalize<42>; // Error, type 'number' does not satisfy the constraint 'string' + ``` +
+ +- [`Uncapitalize`](https://www.typescriptlang.org/docs/handbook/utility-types.html#uncapitalizestringtype) - Transforms the first character in a string into lowercase. +
+ + Example + + + ```ts + type T = Uncapitalize<'Hello'>; // 'hello' + + type T2 = Uncapitalize<'Foo' | 'Bar'>; // 'foo' | 'bar' + + type T3 = Uncapitalize<`AB${S}`>; + type T4 = T3<'xYz'>; // 'aBxYz' + + type T5 = Uncapitalize; // string + type T6 = Uncapitalize; // any + type T7 = Uncapitalize; // never + type T8 = Uncapitalize<42>; // Error, type 'number' does not satisfy the constraint 'string' + ``` +
+ +You can find some examples in the [TypeScript docs](https://www.typescriptlang.org/docs/handbook/utility-types.html). + +## Maintainers + +- [Sindre Sorhus](https://github.com/sindresorhus) +- [Haozheng Li](https://github.com/Emiyaaaaa) +- [Som Shekhar Mukherjee](https://github.com/som-sm) +- [Jarek Radosz](https://github.com/CvX) +- [Dimitri Benin](https://github.com/BendingBender) +- [Pelle Wessman](https://github.com/voxpelli) +- [Sébastien Mischler](https://github.com/skarab42) + +## License + +- [MIT](license-mit) +- [CC0-1.0](license-cc0) + +SPDX-License-Identifier: (MIT OR CC0-1.0) diff --git a/node_modules/type-fest/source/absolute.d.ts b/node_modules/type-fest/source/absolute.d.ts new file mode 100644 index 00000000..ca38ba99 --- /dev/null +++ b/node_modules/type-fest/source/absolute.d.ts @@ -0,0 +1,52 @@ +import type {StringToNumber} from './string-to-number.d.ts'; + +/** +Returns the absolute value of the specified number or bigint. + +@example +``` +import type {Absolute} from 'type-fest'; + +type A = Absolute<-1>; +//=> 1 + +type B = Absolute<1>; +//=> 1 + +type C = Absolute<0>; +//=> 0 + +type D = Absolute<-1.025>; +//=> 1.025 + +type E = Absolute<-9999n>; +//=> 9999n +``` + +Returns back the same type if the input is not a literal type. + +@example +``` +import type {Absolute} from 'type-fest'; + +type A = Absolute; +//=> number + +type B = Absolute; +//=> bigint + +type C = Absolute; +//=> number | bigint +``` + +@category Numeric +*/ +export type Absolute = N extends bigint // Also, distributes `N` + ? `${N}` extends `-${infer Magnitude extends bigint}` + ? Magnitude + : N + : `${N}` extends `-${infer Magnitude}` // This doesn't use the `extends number` constraint approach because that fails with the `-Infinity` case + ? StringToNumber + : N; + +export {}; diff --git a/node_modules/type-fest/source/all-extend.d.ts b/node_modules/type-fest/source/all-extend.d.ts new file mode 100644 index 00000000..85212a0e --- /dev/null +++ b/node_modules/type-fest/source/all-extend.d.ts @@ -0,0 +1,123 @@ +import type {CollapseRestElement} from './internal/array.d.ts'; +import type {ApplyDefaultOptions} from './internal/object.d.ts'; +import type {IfNotAnyOrNever, Not} from './internal/type.d.ts'; +import type {IsAny} from './is-any.d.ts'; +import type {IsNever} from './is-never.d.ts'; +import type {Or} from './or.d.ts'; +import type {UnknownArray} from './unknown-array.d.ts'; + +/** +@see {@link AllExtend} +*/ +export type AllExtendOptions = { + /** + Consider `never` elements to match the target type only if the target type itself is `never` (or `any`). + + - When set to `true` (default), `never` is _not_ treated as a bottom type, instead, it is treated as a type that matches only itself (or `any`). + - When set to `false`, `never` is treated as a bottom type, and behaves as it normally would. + + @default true + + @example + ``` + import type {AllExtend} from 'type-fest'; + + type A = AllExtend<[1, 2, never], number, {strictNever: true}>; + //=> false + + type B = AllExtend<[1, 2, never], number, {strictNever: false}>; + //=> true + + type C = AllExtend<[never, never], never, {strictNever: true}>; + //=> true + + type D = AllExtend<[never, never], never, {strictNever: false}>; + //=> true + + type E = AllExtend<['a', 'b', never], any, {strictNever: true}>; + //=> true + + type F = AllExtend<['a', 'b', never], any, {strictNever: false}>; + //=> true + + type G = AllExtend<[never, 1], never, {strictNever: true}>; + //=> false + + type H = AllExtend<[never, 1], never, {strictNever: false}>; + //=> false + ``` + */ + strictNever?: boolean; +}; + +type DefaultAllExtendOptions = { + strictNever: true; +}; + +/** +Returns a boolean for whether every element in an array type extends another type. + +@example +``` +import type {AllExtend} from 'type-fest'; + +type A = AllExtend<[1, 2, 3], number>; +//=> true + +type B = AllExtend<[1, 2, '3'], number>; +//=> false + +type C = AllExtend<[number, number | string], number>; +//=> boolean + +type D = AllExtend<[true, boolean, true], true>; +//=> boolean +``` + +Note: Behaviour of optional elements depend on the `exactOptionalPropertyTypes` compiler option. When the option is disabled, the target type must include `undefined` for a successful match. + +``` +// @exactOptionalPropertyTypes: true +import type {AllExtend} from 'type-fest'; + +type A = AllExtend<[1?, 2?, 3?], number>; +//=> true +``` + +``` +// @exactOptionalPropertyTypes: false +import type {AllExtend} from 'type-fest'; + +type A = AllExtend<[1?, 2?, 3?], number>; +//=> boolean + +type B = AllExtend<[1?, 2?, 3?], number | undefined>; +//=> true +``` + +@see {@link AllExtendOptions} + +@category Utilities +@category Array +*/ +export type AllExtend = + IfNotAnyOrNever, { + ifNot: _AllExtend, Type, ApplyDefaultOptions>; + ifAny: false; + ifNever: false; + }>; + +// Kept free of `IfNotAnyOrNever` so that it stays tail-recursive, which allows it to handle long arrays. +type _AllExtend> = + TArray extends readonly [infer First, ...infer Rest] + ? IsNever extends true + ? Or, IsAny>, Not> extends true + // If target `Type` is also `never`, or is `any`, or `strictNever` is disabled, recurse further. + ? _AllExtend + : false + : First extends Type + ? _AllExtend + : false + : true; + +export {}; diff --git a/node_modules/type-fest/source/all-union-fields.d.ts b/node_modules/type-fest/source/all-union-fields.d.ts new file mode 100644 index 00000000..71e85a84 --- /dev/null +++ b/node_modules/type-fest/source/all-union-fields.d.ts @@ -0,0 +1,91 @@ +import type {NonRecursiveType, ReadonlyKeysOfUnion, ValueOfUnion} from './internal/index.d.ts'; +import type {KeysOfUnion} from './keys-of-union.d.ts'; +import type {SharedUnionFields} from './shared-union-fields.d.ts'; +import type {Simplify} from './simplify.d.ts'; +import type {UnknownArray} from './unknown-array.d.ts'; + +/** +Create a type with all fields from a union of object types. + +Use-cases: +- You want a safe object type where each key exists in the union object. + +@example +``` +import type {AllUnionFields} from 'type-fest'; + +type Cat = { + name: string; + type: 'cat'; + catType: string; +}; + +type Dog = { + name: string; + type: 'dog'; + dogType: string; +}; + +function displayPetInfo(petInfo: Cat | Dog) { + // typeof petInfo => + // { + // name: string; + // type: 'cat'; + // catType: string; + // } | { + // name: string; + // type: 'dog'; + // dogType: string; + // } + + console.log('name:', petInfo.name); + console.log('type:', petInfo.type); + + // TypeScript complains about `catType` and `dogType` not existing on type `Cat | Dog`. + // @ts-expect-error + console.log('animal type:', petInfo.catType ?? petInfo.dogType); +} + +function displayPetInfoWithAllUnionFields(petInfo: AllUnionFields) { + // typeof petInfo => + // { + // name: string; + // type: 'cat' | 'dog'; + // catType?: string; + // dogType?: string; + // } + + console.log('name:', petInfo.name); + console.log('type:', petInfo.type); + + // No TypeScript error. + console.log('animal type:', petInfo.catType ?? petInfo.dogType); +} +``` + +@see {@link SharedUnionFields} + +@category Object +@category Union +*/ +export type AllUnionFields = + Extract | ReadonlySet | UnknownArray> extends infer SkippedMembers + ? Exclude extends infer RelevantMembers + ? // eslint-disable-line @stylistic/operator-linebreak + | SkippedMembers + | Simplify< + // Include fields that are common in all union members + SharedUnionFields + // Include readonly fields present in any union member + & { + readonly [P in ReadonlyKeysOfUnion]?: ValueOfUnion> + } + // Include remaining fields that are neither common nor readonly + & { + [P in Exclude, ReadonlyKeysOfUnion | keyof RelevantMembers>]?: ValueOfUnion + } + > + : never + : never; + +export {}; diff --git a/node_modules/type-fest/source/and-all.d.ts b/node_modules/type-fest/source/and-all.d.ts new file mode 100644 index 00000000..a8eccfd2 --- /dev/null +++ b/node_modules/type-fest/source/and-all.d.ts @@ -0,0 +1,76 @@ +import type {AllExtend} from './all-extend.d.ts'; + +/** +Returns a boolean for whether all of the given elements are `true`. + +Use-cases: +- Check if all conditions in a list of booleans are met. + +@example +``` +import type {AndAll} from 'type-fest'; + +type TTT = AndAll<[true, true, true]>; +//=> true + +type TTF = AndAll<[true, true, false]>; +//=> false + +type TFT = AndAll<[true, false, true]>; +//=> false +``` + +Note: When `boolean` is passed as an element, it is distributed into separate cases, and the final result is a union of those cases. +For example, `AndAll<[true, boolean]>` expands to `AndAll<[true, true]> | AndAll<[true, false]>`, which simplifies to `true | false` (i.e., `boolean`). + +@example +``` +import type {AndAll} from 'type-fest'; + +type A = AndAll<[true, boolean]>; +//=> boolean + +type B = AndAll<[false, boolean]>; +//=> false +``` + +Note: If any of the elements is `never`, the result becomes `false`. + +@example +``` +import type {AndAll} from 'type-fest'; + +type A = AndAll<[true, true, never]>; +//=> false + +type B = AndAll<[false, never, never]>; +//=> false + +type C = AndAll<[never, never, never]>; +//=> false + +type D = AndAll<[boolean, true, never]>; +//=> false +``` + +Note: If `any` is passed as an element, it is treated as `boolean` and the result is computed accordingly. + +@example +``` +import type {AndAll} from 'type-fest'; + +type A = AndAll<[false, any]>; +//=> false + +type B = AndAll<[true, any]>; +//=> boolean +``` + +Note: `AndAll<[]>` evaluates to `true` due to the concept of [vacuous truth](https://en.wikipedia.org/wiki/Logical_conjunction#:~:text=In%20keeping%20with%20the%20concept%20of%20vacuous%20truth%2C%20when%20conjunction%20is%20defined%20as%20an%20operator%20or%20function%20of%20arbitrary%20arity%2C%20the%20empty%20conjunction%20(AND%2Ding%20over%20an%20empty%20set%20of%20operands)%20is%20often%20defined%20as%20having%20the%20result%20true.), i.e., there are no `false` elements in an empty tuple. + +@see {@link And} +@see {@link OrAll} +*/ +export type AndAll = AllExtend; + +export {}; diff --git a/node_modules/type-fest/source/and.d.ts b/node_modules/type-fest/source/and.d.ts new file mode 100644 index 00000000..f7ba676a --- /dev/null +++ b/node_modules/type-fest/source/and.d.ts @@ -0,0 +1,82 @@ +import type {AndAll} from './and-all.d.ts'; + +/** +Returns a boolean for whether two given types are both `true`. + +Use-case: Constructing complex conditional types where multiple conditions must be satisfied. + +@example +``` +import type {And} from 'type-fest'; + +type TT = And; +//=> true + +type TF = And; +//=> false + +type FT = And; +//=> false + +type FF = And; +//=> false +``` + +Note: When `boolean` is passed as an argument, it is distributed into separate cases, and the final result is a union of those cases. +For example, `And` expands to `And | And`, which simplifies to `true | false` (i.e., `boolean`). + +@example +``` +import type {And} from 'type-fest'; + +type A = And; +//=> boolean + +type B = And; +//=> boolean + +type C = And; +//=> false + +type D = And; +//=> false + +type E = And; +//=> boolean +``` + +Note: If either of the types is `never`, the result becomes `false`. + +@example +``` +import type {And} from 'type-fest'; + +type A = And; +//=> false + +type B = And; +//=> false + +type C = And; +//=> false + +type D = And; +//=> false + +type E = And; +//=> false + +type F = And; +//=> false + +type G = And; +//=> false +``` + +@see {@link AndAll} +@see {@link Or} +@see {@link Xor} +*/ +export type And = AndAll<[A, B]>; + +export {}; diff --git a/node_modules/type-fest/source/array-element.d.ts b/node_modules/type-fest/source/array-element.d.ts new file mode 100644 index 00000000..58e0ef2a --- /dev/null +++ b/node_modules/type-fest/source/array-element.d.ts @@ -0,0 +1,46 @@ +import type {UnknownArray} from './unknown-array.d.ts'; + +/** +Extracts the element type of an array or tuple. + +Use-cases: +- When you need type-safe element extraction that returns `never` for non-arrays. +- When extracting element types from generic array parameters in function signatures. +- For better readability and explicit intent over using `T[number]` directly. + +Note: Returns `never` if the type is not an array. + +@example +``` +import type {ArrayElement} from 'type-fest'; + +// Arrays +type StringArray = ArrayElement; +//=> string + +// Tuples +type Tuple = ArrayElement<[1, 2, 3]>; +//=> 1 | 2 | 3 + +// Type-safe +type NotArray = ArrayElement<{a: string}>; +//=> never + +// Practical example +declare function getRandomElement(array: T): ArrayElement; + +getRandomElement(['foo', 'bar', 'baz'] as const); +//=> 'foo' | 'bar' | 'baz' +``` + +@see {@link ArrayValues} - For directly extracting values from a constant array type. +@see {@link IterableElement} - For iterables like `Set`, `Map`, and generators (not suitable for all use cases due to different inference behavior). + +@category Array +*/ +export type ArrayElement = + T extends UnknownArray + ? T[number] + : never; + +export {}; diff --git a/node_modules/type-fest/source/array-indices.d.ts b/node_modules/type-fest/source/array-indices.d.ts new file mode 100644 index 00000000..f3c262ee --- /dev/null +++ b/node_modules/type-fest/source/array-indices.d.ts @@ -0,0 +1,25 @@ +/** +Provides valid indices for a constant array or tuple. + +Use-case: This type is useful when working with constant arrays or tuples and you want to enforce type-safety for accessing elements by their indices. + +@example +``` +import type {ArrayIndices, ArrayValues} from 'type-fest'; + +const weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] as const; + +type Weekday = ArrayIndices; +type WeekdayName = ArrayValues; + +const getWeekdayName = (day: Weekday): WeekdayName => weekdays[day]; +``` + +@see {@link ArrayValues} + +@category Array +*/ +export type ArrayIndices = + Exclude['length'], Element['length']>; + +export {}; diff --git a/node_modules/type-fest/source/array-length.d.ts b/node_modules/type-fest/source/array-length.d.ts new file mode 100644 index 00000000..97949e40 --- /dev/null +++ b/node_modules/type-fest/source/array-length.d.ts @@ -0,0 +1,36 @@ +/** +Return the length of an array. Equivalent to `T['length']` where `T` extends any array. + +Tuples resolve to numeric literals, while non-tuples resolve to the `number` type. + +@example +``` +import type {ArrayLength} from 'type-fest'; + +type TupleLength = ArrayLength<[1, 2, 3]>; +//=> 3 + +type TupleWithOptionalMembersLength = ArrayLength<[1, 2, number?]>; +//=> 2 | 3 + +type NonTupleArrayLength = ArrayLength; +//=> number + +type TupleWithRestElementLength = ArrayLength<[1, 2, ...string[]]>; +//=> number + +// Distinguish between arrays with fixed and non-fixed lengths +type IsFixedLengthArray = number extends ArrayLength ? false : true; + +type A = IsFixedLengthArray; +//=> false + +type B = IsFixedLengthArray<[1, 2, 3]>; +//=> true +``` + +@category Array +*/ +export type ArrayLength = T['length']; + +export {}; diff --git a/node_modules/type-fest/source/array-reverse.d.ts b/node_modules/type-fest/source/array-reverse.d.ts new file mode 100644 index 00000000..5d57560b --- /dev/null +++ b/node_modules/type-fest/source/array-reverse.d.ts @@ -0,0 +1,86 @@ +import type {If} from './if.d.ts'; +import type {IsArrayReadonly} from './internal/array.d.ts'; +import type {IfNotAnyOrNever, IsExactOptionalPropertyTypesEnabled} from './internal/type.d.ts'; +import type {UnknownArray} from './unknown-array.d.ts'; + +/** +Reverse the order of elements in a tuple type. + +@example +```ts +import type {ArrayReverse} from 'type-fest'; + +type A = ArrayReverse<[string, number, boolean]>; +//=> [boolean, number, string] + +type B = ArrayReverse; +//=> readonly [...boolean[], number, string] + +type C = ArrayReverse<['foo', 'bar'] | readonly [1, 2, 3]>; +//=> ['bar', 'foo'] | readonly [3, 2, 1] + +type D = ArrayReverse; +//=> string[] + +type E = ArrayReverse<[]>; +//=> [] +``` + +Note: If the tuple contains optional elements, the result will be a union of tuples, refer to the examples below: + +@example +```ts +import type {ArrayReverse} from 'type-fest'; + +type A = ArrayReverse<[string, number, boolean?]>; +//=> [number, string] | [boolean, number, string] + +type B = ArrayReverse<[string, number?, boolean?]>; +//=> [string] | [number, string] | [boolean, number, string] + +type C = ArrayReverse<[string?, number?, boolean?]>; +//=> [] | [string] | [number, string] | [boolean, number, string] + +type D = ArrayReverse<[string, number?, ...boolean[]]>; +//=> [string] | [...boolean[], number, string] + +type E = ArrayReverse<[string?, number?, ...boolean[]]>; +//=> [] | [string] | [...boolean[], number, string] +``` + +@category Array +*/ +export type ArrayReverse = IfNotAnyOrNever extends infer Result + ? If, Readonly, Result> + : never // Should never happen + : never; // Should never happen +}>; + +type _ArrayReverse< + TArray extends UnknownArray, + BeforeRestAcc extends UnknownArray = [], + AfterRestAcc extends UnknownArray = [], + Result extends UnknownArray = never, +> = + '0' extends keyof TArray + // Enters this branch, if `TArray` starts with a non-rest element (e.g., `[string, number]` or `[string, ...number[]]`). + ? TArray extends readonly [(infer First)?, ...infer Rest] + // A tuple allows fewer than one element only when its first element is optional. Written in exactly this shape because equivalent ones, such as `[] extends TArray`, are several times slower. + ? TArray extends readonly [unknown, ...unknown[]] + ? _ArrayReverse + : _ArrayReverse< + Rest, + [First | (If), ...BeforeRestAcc], // Add `| undefined` for optional elements, if `exactOptionalPropertyTypes` is disabled. + AfterRestAcc, + Result | BeforeRestAcc + > + : never // Should never happen, since `readonly [(infer First)?, ...infer Rest]` is a top-type for arrays. + // Enters this branch, if `TArray` is empty (e.g., `[]`), + // or `TArray` contains no non-rest elements preceding the rest element (e.g., `[...string[]]` or `[...string[], string]`). + : TArray extends readonly [...infer Rest, infer Last] + ? _ArrayReverse // Accumulate elements that are present after the rest element in reverse order. + : Result | [...AfterRestAcc, ...TArray, ...BeforeRestAcc]; // Add the rest element between the accumulated elements. + +export {}; diff --git a/node_modules/type-fest/source/array-slice.d.ts b/node_modules/type-fest/source/array-slice.d.ts new file mode 100644 index 00000000..8fac2be0 --- /dev/null +++ b/node_modules/type-fest/source/array-slice.d.ts @@ -0,0 +1,132 @@ +import type {Sum} from './sum.d.ts'; +import type {LessThanOrEqual} from './less-than-or-equal.d.ts'; +import type {GreaterThanOrEqual} from './greater-than-or-equal.d.ts'; +import type {GreaterThan} from './greater-than.d.ts'; +import type {IsNegative} from './numeric.d.ts'; +import type {Not, TupleMin} from './internal/index.d.ts'; +import type {IsEqual} from './is-equal.d.ts'; +import type {And} from './and.d.ts'; +import type {ArraySplice} from './array-splice.d.ts'; +import type {IsNever} from './is-never.d.ts'; + +/** +Returns an array slice of a given range, just like `Array#slice()`. + +@example +``` +import type {ArraySlice} from 'type-fest'; + +type T0 = ArraySlice<[0, 1, 2, 3, 4]>; +//=> [0, 1, 2, 3, 4] + +type T1 = ArraySlice<[0, 1, 2, 3, 4], 0, -1>; +//=> [0, 1, 2, 3] + +type T2 = ArraySlice<[0, 1, 2, 3, 4], 1, -2>; +//=> [1, 2] + +type T3 = ArraySlice<[0, 1, 2, 3, 4], -2, 4>; +//=> [3] + +type T4 = ArraySlice<[0, 1, 2, 3, 4], -2, -1>; +//=> [3] + +type T5 = ArraySlice<[0, 1, 2, 3, 4], 0, -999>; +//=> [] + +function arraySlice< + const Array_ extends readonly unknown[], + Start extends number = 0, + End extends number = Array_['length'], +>(array: Array_, start?: Start, end?: End) { + return array.slice(start, end) as ArraySlice; +} + +const slice = arraySlice([1, '2', {a: 3}, [4, 5]], 0, -1); + +type Slice = typeof slice; +//=> [1, '2', {readonly a: 3}] + +const value = slice[2].a; +//=> 3 + +// @ts-expect-error -- TS2493: Tuple type '[1, "2", {readonly a: 3}]' of length '3' has no element at index '3'. +const invalidIndexAccess = slice[3]; +``` + +@category Array +*/ +export type ArraySlice< + Array_ extends readonly unknown[], + Start extends number = never, + End extends number = never, +> = Array_ extends unknown // To distributive type + ? IsNever extends true + ? IsNever extends true + ? _ArraySlice + : End extends unknown // To distribute `End` + ? _ArraySlice + : never // Never happens + : IsNever extends true + ? Start extends unknown // To distribute `Start` + ? _ArraySlice + : never // Never happens + : Start extends unknown // To distribute `Start` + ? End extends unknown // To distribute `End` + ? _ArraySlice + : never // Never happens + : never // Never happens + : never; // Never happens + +type _ArraySlice< + Array_ extends readonly unknown[], + Start extends number = 0, + End extends number = Array_['length'], +> = And, IsEqual> extends true + ? Array_ + : number extends Array_['length'] + ? VariableLengthArraySliceHelper + : ArraySliceHelper extends true ? 0 : Start, IsEqual extends true ? Array_['length'] : End>; + +type VariableLengthArraySliceHelper< + Array_ extends readonly unknown[], + Start extends number, + End extends number, +> = And>, IsEqual> extends true + ? ArraySplice + : And< + And>, Not>>, + IsEqual, true> + > extends true + ? ArraySliceByPositiveIndex + : []; + +type ArraySliceHelper< + Array_ extends readonly unknown[], + Start extends number = 0, + End extends number = Array_['length'], + TraversedElement extends Array = [], + Result extends Array = [], + ArrayLength extends number = Array_['length'], + PositiveS extends number = IsNegative extends true + ? Sum extends infer AddResult extends number + ? number extends AddResult // (ArrayLength + Start) < 0 + ? 0 + : GreaterThan extends true ? AddResult : 0 + : never + : Start, + PositiveE extends number = IsNegative extends true ? Sum : End, +> = true extends [IsNegative, LessThanOrEqual, GreaterThanOrEqual][number] + ? [] + : ArraySliceByPositiveIndex, TupleMin<[PositiveE, ArrayLength]>>; + +type ArraySliceByPositiveIndex< + Array_ extends readonly unknown[], + Start extends number, + End extends number, + Result extends Array = [], +> = Start extends End + ? Result + : ArraySliceByPositiveIndex, End, [...Result, Array_[Start]]>; + +export {}; diff --git a/node_modules/type-fest/source/array-splice.d.ts b/node_modules/type-fest/source/array-splice.d.ts new file mode 100644 index 00000000..cb8f69ad --- /dev/null +++ b/node_modules/type-fest/source/array-splice.d.ts @@ -0,0 +1,104 @@ +import type {StaticPartOfArray, VariablePartOfArray} from './internal/index.d.ts'; +import type {GreaterThanOrEqual} from './greater-than-or-equal.d.ts'; +import type {Subtract} from './subtract.d.ts'; +import type {UnknownArray} from './unknown-array.d.ts'; +import type {TupleOf} from './tuple-of.d.ts'; + +/** +The implementation of `SplitArrayByIndex` for fixed length arrays. +*/ +type SplitFixedArrayByIndex = + SplitIndex extends 0 + ? [[], T] + : T extends readonly [...TupleOf, ...infer V] + ? T extends readonly [...infer U, ...V] + ? [U, V] + : [never, never] + : [never, never]; + +/** +The implementation of `SplitArrayByIndex` for variable length arrays. +*/ +type SplitVariableArrayByIndex['length']>, + T2 = T1 extends number + ? TupleOf extends true ? T1 : number, VariablePartOfArray[number]> + : [], +> = + SplitIndex extends 0 + ? [[], T] + : GreaterThanOrEqual['length'], SplitIndex> extends true + ? [ + SplitFixedArrayByIndex, SplitIndex>[0], + [ + ...SplitFixedArrayByIndex, SplitIndex>[1], + ...VariablePartOfArray, + ], + ] + : [ + [ + ...StaticPartOfArray, + ...(T2 extends UnknownArray ? T2 : []), + ], + VariablePartOfArray, + ]; + +/** +Split the given array `T` by the given `SplitIndex`. + +@example +``` +type A = SplitArrayByIndex<[1, 2, 3, 4], 2>; +//=> [[1, 2], [3, 4]]; + +type B = SplitArrayByIndex<[1, 2, 3, 4], 0>; +//=> [[], [1, 2, 3, 4]]; +``` +*/ +type SplitArrayByIndex = + SplitIndex extends 0 + ? [[], T] + : number extends T['length'] + ? SplitVariableArrayByIndex + : SplitFixedArrayByIndex; + +/** +Create a new array type by adding or removing elements at a specified index range in the original array. + +Use-case: Replace or insert items in an array type. + +Like [`Array#splice()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) but for types. + +@example +``` +import type {ArraySplice} from 'type-fest'; + +type SomeMonths0 = ['January', 'April', 'June']; +type Months0 = ArraySplice; +//=> ['January', 'Feb', 'March', 'April', 'June'] + +type SomeMonths1 = ['January', 'April', 'June']; +type Months1 = ArraySplice; +//=> ['January', 'June'] + +type SomeMonths2 = ['January', 'Foo', 'April']; +type Months2 = ArraySplice; +//=> ['January', 'Feb', 'March', 'April'] +``` + +@category Array +*/ +export type ArraySplice< + T extends UnknownArray, + Start extends number, + DeleteCount extends number, + Items extends UnknownArray = [], +> = + SplitArrayByIndex extends [infer U extends UnknownArray, infer V extends UnknownArray] + ? SplitArrayByIndex extends [infer _Deleted extends UnknownArray, infer X extends UnknownArray] + ? [...U, ...Items, ...X] + : never // Should never happen + : never; // Should never happen + +export {}; diff --git a/node_modules/type-fest/source/array-tail.d.ts b/node_modules/type-fest/source/array-tail.d.ts new file mode 100644 index 00000000..4ab970cf --- /dev/null +++ b/node_modules/type-fest/source/array-tail.d.ts @@ -0,0 +1,70 @@ +import type {If} from './if.d.ts'; +import type {IfNotAnyOrNever, IsArrayReadonly} from './internal/index.d.ts'; +import type {UnknownArray} from './unknown-array.d.ts'; + +/** +Extract the type of an array or tuple minus the first element. + +@example +``` +import type {ArrayTail} from 'type-fest'; + +type A = ArrayTail<[1, 2, 3]>; +//=> [2, 3] + +type B = ArrayTail; +//=> readonly [2, 3] + +type C = ArrayTail<[1, 2, 3?, ...string[]]>; +//=> [2, 3?, ...string[]] + +type D = ArrayTail; +//=> readonly [] + +type E = ArrayTail<[]>; +//=> [] + +type F = ArrayTail; +//=> string[] + +type G = ArrayTail; +//=> readonly [...string[], 1, 2] +``` + +@example +``` +import type {ArrayTail} from 'type-fest'; + +type Curry = Func extends (...agruments_: infer Arguments) => infer Return + ? Arguments extends readonly [] + ? Return + : (agrument: Arguments[0]) => Curry<(...agruments_: ArrayTail) => Return> + : never; + +declare function curry(fn: Func): Curry; + +declare function searchBooks(genre: string, minRating: number, available: boolean): string[]; + +const availableTopSciFi = curry(searchBooks)('sci-fi')(4.5)(true); +//=> string[] +``` + +@category Array +*/ +export type ArrayTail = IfNotAnyOrNever extends infer Result + ? If, Readonly, Result> + : never // Should never happen + : never; +}>; + +type _ArrayTail = TArray extends readonly [unknown?, ...infer Tail] + ? '0' extends keyof TArray + ? Tail + : TArray extends readonly [] + ? [] + : TArray // Happens when `TArray` is a non-tuple array (e.g., `string[]`) or has a leading rest element (e.g., `[...string[], number]`) + : []; + +export {}; diff --git a/node_modules/type-fest/source/array-values.d.ts b/node_modules/type-fest/source/array-values.d.ts new file mode 100644 index 00000000..9cde345e --- /dev/null +++ b/node_modules/type-fest/source/array-values.d.ts @@ -0,0 +1,24 @@ +/** +Provides all values for a constant array or tuple. + +Use-case: This type is useful when working with constant arrays or tuples and you want to enforce type-safety with their values. + +@example +``` +import type {ArrayValues, ArrayIndices} from 'type-fest'; + +const weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] as const; + +type WeekdayName = ArrayValues; +type Weekday = ArrayIndices; + +const getWeekdayName = (day: Weekday): WeekdayName => weekdays[day]; +``` + +@see {@link ArrayIndices} + +@category Array +*/ +export type ArrayValues = T[number]; + +export {}; diff --git a/node_modules/type-fest/source/arrayable.d.ts b/node_modules/type-fest/source/arrayable.d.ts new file mode 100644 index 00000000..985392b5 --- /dev/null +++ b/node_modules/type-fest/source/arrayable.d.ts @@ -0,0 +1,31 @@ +/** +Create a type that represents either the value or an array of the value. + +@see {@link Promisable} + +@example +``` +import type {Arrayable} from 'type-fest'; + +function bundle(input: string, output: Arrayable) { + const outputList = Array.isArray(output) ? output : [output]; + + // … + + for (const output of outputList) { + console.log(`write ${input} to: ${output}`); + } +} + +bundle('src/index.js', 'dist/index.js'); +bundle('src/index.js', ['dist/index.cjs', 'dist/index.mjs']); +``` + +@category Array +*/ +export type Arrayable = + T +// TODO: Use `readonly T[]` when this issue is resolved: https://github.com/microsoft/TypeScript/issues/17002 + | T[]; + +export {}; diff --git a/node_modules/type-fest/source/async-return-type.d.ts b/node_modules/type-fest/source/async-return-type.d.ts new file mode 100644 index 00000000..63600edf --- /dev/null +++ b/node_modules/type-fest/source/async-return-type.d.ts @@ -0,0 +1,28 @@ +type AsyncFunction = (...arguments_: any[]) => PromiseLike; + +/** +Unwrap the return type of a function that returns a `Promise`. + +There has been [discussion](https://github.com/microsoft/TypeScript/pull/35998) about implementing this type in TypeScript. + +@example +```ts +import type {AsyncReturnType} from 'type-fest'; + +declare function asyncFunction(): Promise<{foo: string}>; + +// This type resolves to the unwrapped return type of `asyncFunction`. +type Value = AsyncReturnType; +//=> {foo: string} + +declare function doSomething(value: Value): void; + +const value = await asyncFunction(); +doSomething(value); +``` + +@category Async +*/ +export type AsyncReturnType = Awaited>; + +export {}; diff --git a/node_modules/type-fest/source/asyncify.d.ts b/node_modules/type-fest/source/asyncify.d.ts new file mode 100644 index 00000000..7a91a13e --- /dev/null +++ b/node_modules/type-fest/source/asyncify.d.ts @@ -0,0 +1,25 @@ +import type {SetReturnType} from './set-return-type.d.ts'; + +/** +Create an async version of the given function type, by boxing the return type in `Promise` while keeping the same parameter types. + +Use-case: You have two functions, one synchronous and one asynchronous that do the same thing. Instead of having to duplicate the type definition, you can use `Asyncify` to reuse the synchronous type. + +@example +``` +import type {Asyncify} from 'type-fest'; + +// Synchronous function +type Config = {featureFlags: Record}; + +declare function loadConfigSync(path: string): Config; + +type LoadConfigAsync = Asyncify; +//=> (path: string) => Promise +``` + +@category Async +*/ +export type Asyncify any> = SetReturnType>>>; + +export {}; diff --git a/node_modules/type-fest/source/basic.d.ts b/node_modules/type-fest/source/basic.d.ts new file mode 100644 index 00000000..30cab3ae --- /dev/null +++ b/node_modules/type-fest/source/basic.d.ts @@ -0,0 +1,38 @@ +/** +Matches a [`class`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes). + +@category Class +*/ +export type Class = { + prototype: Pick; + new(...arguments_: Arguments): T; +}; + +/** +Matches a [`class` constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes). + +@category Class +*/ +export type Constructor = new(...arguments_: Arguments) => T; + +/** +Matches an [`abstract class`](https://www.typescriptlang.org/docs/handbook/2/classes.html#abstract-classes-and-members). + +@category Class + +@privateRemarks +We cannot use a `type` here because TypeScript throws: 'abstract' modifier cannot appear on a type member. (1070) +*/ +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions +export interface AbstractClass extends AbstractConstructor { + prototype: Pick; +} + +/** +Matches an [`abstract class`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-2.html#abstract-construct-signatures) constructor. + +@category Class +*/ +export type AbstractConstructor = abstract new(...arguments_: Arguments) => T; + +export {}; diff --git a/node_modules/type-fest/source/camel-case.d.ts b/node_modules/type-fest/source/camel-case.d.ts new file mode 100644 index 00000000..92633c62 --- /dev/null +++ b/node_modules/type-fest/source/camel-case.d.ts @@ -0,0 +1,125 @@ +import type {ApplyDefaultOptions} from './internal/index.d.ts'; +import type {_DefaultWordsOptions, Words, WordsOptions} from './words.d.ts'; + +/** +CamelCase options. + +@see {@link CamelCase} +*/ +export type CamelCaseOptions = WordsOptions & { + /** + Whether to preserved consecutive uppercase letter. + + @default false + */ + preserveConsecutiveUppercase?: boolean; + + /** + Whether to preserve leading underscores. + + This matches the behavior of the [`camelcase`](https://github.com/sindresorhus/camelcase) package v9+. + + @default false + */ + preserveLeadingUnderscores?: boolean; +}; + +export type _DefaultCamelCaseOptions = _DefaultWordsOptions & { + preserveConsecutiveUppercase: false; + preserveLeadingUnderscores: false; +}; + +/** +Extract leading underscores from a string. + +@example +``` +type A = LeadingUnderscores<'__foo_bar'>; +//=> '__' + +type B = LeadingUnderscores<'foo_bar'>; +//=> '' +``` +*/ +type LeadingUnderscores = + Type extends `_${infer Rest}` + ? LeadingUnderscores + : Underscores; + +/** +Convert an array of words to camel-case. +*/ +type CamelCaseFromArray< + Words extends string[], + Options extends Required, + OutputString extends string = '', +> = Words extends [ + infer FirstWord extends string, + ...infer RemainingWords extends string[], +] + ? Options['preserveConsecutiveUppercase'] extends true + ? `${Capitalize}${CamelCaseFromArray}` + : `${Capitalize>}${CamelCaseFromArray}` + : OutputString; + +/** +Convert a string literal to camel-case. + +This can be useful when, for example, converting some kebab-cased command-line flags or a snake-cased database result. + +By default, consecutive uppercase letter are preserved. See {@link CamelCaseOptions.preserveConsecutiveUppercase preserveConsecutiveUppercase} option to change this behaviour. + +Use the `preserveLeadingUnderscores` option to retain leading underscores, matching the runtime behavior of [`camelcase`](https://github.com/sindresorhus/camelcase) v9+. + +@example +``` +import type {CamelCase} from 'type-fest'; + +// Simple + +const someVariable: CamelCase<'foo-bar'> = 'fooBar'; +const preserveConsecutiveUppercase: CamelCase<'foo-BAR-baz', {preserveConsecutiveUppercase: true}> = 'fooBARBaz'; +const splitOnPunctuation: CamelCase<'foo-bar:BAZ', {splitOnPunctuation: true}> = 'fooBarBaz'; +const preserveLeadingUnderscores: CamelCase<'_foo_bar', {preserveLeadingUnderscores: true}> = '_fooBar'; + +// Advanced + +type CamelCasedProperties = { + [K in keyof T as CamelCase]: T[K] +}; + +type RawOptions = { + 'dry-run': boolean; + 'full_family_name': string; + foo: number; + BAR: string; + QUZ_QUX: number; + 'OTHER-FIELD': boolean; +}; + +const dbResult: CamelCasedProperties = { + dryRun: true, + fullFamilyName: 'bar.js', + foo: 123, + bar: 'foo', + quzQux: 6, + otherField: false, +}; +``` + +@category Change case +@category Template literal +*/ +export type CamelCase = Type extends string + ? string extends Type + ? Type + : `${Options['preserveLeadingUnderscores'] extends true + ? LeadingUnderscores + : '' + }${Uncapitalize ? Lowercase : Type, Options>, + ApplyDefaultOptions + >>}` + : Type; + +export {}; diff --git a/node_modules/type-fest/source/camel-cased-properties-deep.d.ts b/node_modules/type-fest/source/camel-cased-properties-deep.d.ts new file mode 100644 index 00000000..8af790cc --- /dev/null +++ b/node_modules/type-fest/source/camel-cased-properties-deep.d.ts @@ -0,0 +1,106 @@ +import type {CamelCase, CamelCaseOptions, _DefaultCamelCaseOptions} from './camel-case.d.ts'; +import type {ApplyDefaultOptions, NonRecursiveType} from './internal/index.d.ts'; +import type {UnknownArray} from './unknown-array.d.ts'; + +/** +Convert object properties to camel case recursively. + +This can be useful when, for example, converting some API types from a different style. + +@see {@link CamelCasedProperties} +@see {@link CamelCase} + +@example +``` +import type {CamelCasedPropertiesDeep} from 'type-fest'; + +type User = { + UserId: number; + UserName: string; +}; + +type UserWithFriends = { + UserInfo: User; + UserFriends: User[]; +}; + +const result: CamelCasedPropertiesDeep = { + userInfo: { + userId: 1, + userName: 'Tom', + }, + userFriends: [ + { + userId: 2, + userName: 'Jerry', + }, + { + userId: 3, + userName: 'Spike', + }, + ], +}; + +const preserveConsecutiveUppercase: CamelCasedPropertiesDeep<{fooBAR: {fooBARBiz: [{fooBARBaz: string}]}}, {preserveConsecutiveUppercase: true}> = { + fooBAR: { + fooBARBiz: [{ + fooBARBaz: 'string', + }], + }, +}; + +const splitOnPunctuation: CamelCasedPropertiesDeep<{'user@info': {'user::id': number; 'user::name': string}}, {splitOnPunctuation: true}> = { + userInfo: { + userId: 1, + userName: 'Tom', + }, +}; +``` + +@category Change case +@category Template literal +@category Object +*/ +export type CamelCasedPropertiesDeep< + Value, + Options extends CamelCaseOptions = {}, +> = _CamelCasedPropertiesDeep>; + +type _CamelCasedPropertiesDeep< + Value, + Options extends Required, +> = Value extends NonRecursiveType + ? Value + : Value extends UnknownArray + ? CamelCasedPropertiesArrayDeep + : Value extends Set + ? Set<_CamelCasedPropertiesDeep> + : Value extends object + ? { + [K in keyof Value as CamelCase]: _CamelCasedPropertiesDeep; + } + : Value; + +// This is a copy of DelimiterCasedPropertiesArrayDeep (see: delimiter-cased-properties-deep.d.ts). +// These types should be kept in sync. +type CamelCasedPropertiesArrayDeep< + Value extends UnknownArray, + Options extends Required, +> = Value extends [] + ? [] + // Trailing spread array + : Value extends [infer U, ...infer V] + ? [_CamelCasedPropertiesDeep, ..._CamelCasedPropertiesDeep] + : Value extends readonly [infer U, ...infer V] + ? readonly [_CamelCasedPropertiesDeep, ..._CamelCasedPropertiesDeep] + // Leading spread array + : Value extends readonly [...infer U, infer V] + ? [..._CamelCasedPropertiesDeep, _CamelCasedPropertiesDeep] + // Array + : Value extends Array + ? Array<_CamelCasedPropertiesDeep> + : Value extends ReadonlyArray + ? ReadonlyArray<_CamelCasedPropertiesDeep> + : never; + +export {}; diff --git a/node_modules/type-fest/source/camel-cased-properties.d.ts b/node_modules/type-fest/source/camel-cased-properties.d.ts new file mode 100644 index 00000000..16593a64 --- /dev/null +++ b/node_modules/type-fest/source/camel-cased-properties.d.ts @@ -0,0 +1,49 @@ +import type {CamelCase, CamelCaseOptions, _DefaultCamelCaseOptions} from './camel-case.d.ts'; +import type {ApplyDefaultOptions} from './internal/index.d.ts'; + +/** +Convert top-level object properties to camel case. + +This can be useful when, for example, converting some API types from a different style. + +@see {@link CamelCasedPropertiesDeep} +@see {@link CamelCase} + +@example +``` +import type {CamelCasedProperties} from 'type-fest'; + +type User = { + UserId: number; + UserName: string; +}; + +const result: CamelCasedProperties = { + userId: 1, + userName: 'Tom', +}; + +const preserveConsecutiveUppercase: CamelCasedProperties<{fooBAR: string}, {preserveConsecutiveUppercase: true}> = { + fooBAR: 'string', +}; + +const splitOnPunctuation: CamelCasedProperties<{'foo::bar': string}, {splitOnPunctuation: true}> = { + fooBar: 'string', +}; +``` + +@category Change case +@category Template literal +@category Object +*/ +export type CamelCasedProperties = Value extends Function + ? Value + : Value extends Array + ? Value + : { + [K in keyof Value as + CamelCase> + ]: Value[K]; + }; + +export {}; diff --git a/node_modules/type-fest/source/characters.d.ts b/node_modules/type-fest/source/characters.d.ts new file mode 100644 index 00000000..5d9bf5a3 --- /dev/null +++ b/node_modules/type-fest/source/characters.d.ts @@ -0,0 +1,67 @@ +/** +Matches any uppercase letter in the basic Latin alphabet (A-Z). + +@example +``` +import type {UppercaseLetter} from 'type-fest'; + +const a: UppercaseLetter = 'A'; // Valid +// @ts-expect-error +const b: UppercaseLetter = 'a'; // Invalid +// @ts-expect-error +const c: UppercaseLetter = 'AB'; // Invalid +``` + +@category Type +*/ +export type UppercaseLetter = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z'; + +/** +Matches any lowercase letter in the basic Latin alphabet (a-z). + +@example +``` +import type {LowercaseLetter} from 'type-fest'; + +const a: LowercaseLetter = 'a'; // Valid +// @ts-expect-error +const b: LowercaseLetter = 'A'; // Invalid +``` + +@category Type +*/ +export type LowercaseLetter = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z'; + +/** +Matches any digit as a string ('0'-'9'). + +@example +``` +import type {DigitCharacter} from 'type-fest'; + +const a: DigitCharacter = '0'; // Valid +// @ts-expect-error +const b: DigitCharacter = 0; // Invalid +``` + +@category Type +*/ +export type DigitCharacter = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'; + +/** +Matches any lowercase letter (a-z), uppercase letter (A-Z), or digit ('0'-'9') in the basic Latin alphabet. + +@example +``` +import type {Alphanumeric} from 'type-fest'; + +const a: Alphanumeric = 'A'; // Valid +// @ts-expect-error +const b: Alphanumeric = '#'; // Invalid +``` + +@category Type +*/ +export type Alphanumeric = LowercaseLetter | UppercaseLetter | DigitCharacter; + +export {}; diff --git a/node_modules/type-fest/source/conditional-except.d.ts b/node_modules/type-fest/source/conditional-except.d.ts new file mode 100644 index 00000000..d8012c7b --- /dev/null +++ b/node_modules/type-fest/source/conditional-except.d.ts @@ -0,0 +1,47 @@ +import type {Except} from './except.d.ts'; +import type {ConditionalKeys} from './conditional-keys.d.ts'; + +/** +Exclude keys from a shape that matches the given `Condition`. + +This is useful when you want to create a new type with a specific set of keys from a shape. For example, you might want to exclude all the primitive properties from a class and form a new shape containing everything but the primitive properties. + +@example +``` +import type {Primitive, ConditionalExcept} from 'type-fest'; + +class Awesome { + constructor(public name: string, public successes: number, public failures: bigint) {} + + run() { + // do something + } +} + +type ExceptPrimitivesFromAwesome = ConditionalExcept; +//=> {run: () => void} +``` + +@example +``` +import type {ConditionalExcept} from 'type-fest'; + +type Example = { + a: string; + b: string | number; + c: () => void; + d: {}; +}; + +type NonStringKeysOnly = ConditionalExcept; +//=> {b: string | number; c: () => void; d: {}} +``` + +@category Object +*/ +export type ConditionalExcept = Except< + Base, + ConditionalKeys +>; + +export {}; diff --git a/node_modules/type-fest/source/conditional-keys.d.ts b/node_modules/type-fest/source/conditional-keys.d.ts new file mode 100644 index 00000000..da959191 --- /dev/null +++ b/node_modules/type-fest/source/conditional-keys.d.ts @@ -0,0 +1,63 @@ +import type {ExtendsStrict} from './extends-strict.d.ts'; +import type {IfNotAnyOrNever} from './internal/type.d.ts'; +import type {TupleToObject} from './tuple-to-object.d.ts'; +import type {UnknownArray} from './unknown-array.d.ts'; + +/** +Extract the keys from a type where the value type of the key extends the given `Condition`. + +Internally this is used for the `ConditionalPick` and `ConditionalExcept` types. + +@example +``` +import type {ConditionalKeys} from 'type-fest'; + +type Example = { + a: string; + b: string | number; + c?: string; + d: {}; +}; + +type StringKeysOnly = ConditionalKeys; +//=> 'a' +``` + +Note: To extract optional keys, make sure your `Condition` is a union of `undefined` (for example, `string | undefined`) as demonstrated below. + +@example +``` +import type {ConditionalKeys} from 'type-fest'; + +type StringKeysAndUndefined = ConditionalKeys<{a?: string}, string | undefined>; +//=> 'a' + +type NoMatchingKeys = ConditionalKeys<{a?: string}, string>; +//=> never +``` + +You can also extract array indices whose value match the specified condition, as shown below: +``` +import type {ConditionalKeys} from 'type-fest'; + +type StringValueIndices = ConditionalKeys<[string, number, string], string>; +//=> '0' | '2' + +type NumberValueIndices = ConditionalKeys<[string, number?, string?], number | undefined>; +//=> '1' +``` + +@category Object +*/ +export type ConditionalKeys = (Base extends UnknownArray ? TupleToObject : Base) extends infer _Base // Remove non-numeric keys from arrays + ? IfNotAnyOrNever<_Base, {ifNot: _ConditionalKeys<_Base, Condition>; ifAny: keyof _Base}> + : never; + +type _ConditionalKeys = keyof { + [ + Key in (keyof Base & {}) as // `& {}` prevents homomorphism + ExtendsStrict extends true ? Key : never + ]: never +}; + +export {}; diff --git a/node_modules/type-fest/source/conditional-pick-deep.d.ts b/node_modules/type-fest/source/conditional-pick-deep.d.ts new file mode 100644 index 00000000..dbc2a7da --- /dev/null +++ b/node_modules/type-fest/source/conditional-pick-deep.d.ts @@ -0,0 +1,122 @@ +import type {IsEqual} from './is-equal.d.ts'; +import type {ConditionalExcept} from './conditional-except.d.ts'; +import type {ConditionalSimplifyDeep} from './conditional-simplify-deep.d.ts'; +import type {UnknownRecord} from './unknown-record.d.ts'; +import type {EmptyObject} from './empty-object.d.ts'; +import type {ApplyDefaultOptions, IsPlainObject} from './internal/index.d.ts'; + +/** +Used to mark properties that should be excluded. +*/ +declare const conditionalPickDeepSymbol: unique symbol; + +/** +Assert the condition according to the {@link ConditionalPickDeepOptions.condition|condition} option. +*/ +type AssertCondition = Options['condition'] extends 'equality' + ? IsEqual + : Type extends Condition + ? true + : false; + +/** +ConditionalPickDeep options. + +@see {@link ConditionalPickDeep} +*/ +export type ConditionalPickDeepOptions = { + /** + The condition assertion mode. + + @default 'extends' + */ + condition?: 'extends' | 'equality'; +}; + +type DefaultConditionalPickDeepOptions = { + condition: 'extends'; +}; + +/** +Pick keys recursively from the shape that matches the given condition. + +@see {@link ConditionalPick} + +@example +``` +import type {ConditionalPickDeep} from 'type-fest'; + +type Example = { + a: string; + b: string | boolean; + c: { + d: string; + e: { + f?: string; + g?: boolean; + h: string | boolean; + i: boolean | bigint; + }; + j: boolean; + }; +}; + +type StringPick = ConditionalPickDeep; +//=> {a: string; c: {d: string}} + +type StringPickOptional = ConditionalPickDeep; +//=> {a: string; c: {d: string; e: {f?: string}}} + +type StringPickOptionalOnly = ConditionalPickDeep; +//=> {c: {e: {f?: string}}} + +type BooleanPick = ConditionalPickDeep; +//=> {c: {e: {g?: boolean}; j: boolean}} + +type NumberPick = ConditionalPickDeep; +//=> never + +type StringOrBooleanPick = ConditionalPickDeep; +//=> { +// a: string; +// b: string | boolean; +// c: { +// d: string; +// e: { +// h: string | boolean; +// }; +// j: boolean; +// }; +// } + +type StringOrBooleanPickOnly = ConditionalPickDeep; +//=> {b: string | boolean; c: {e: {h: string | boolean}}} +``` + +@category Object +*/ +export type ConditionalPickDeep< + Type, + Condition, + Options extends ConditionalPickDeepOptions = {}, +> = _NeverIfEmpty<_ConditionalPickDeep< + Type, + Condition, + ApplyDefaultOptions +>>; + +type _NeverIfEmpty = Type extends EmptyObject ? never : Type; + +type _ConditionalPickDeep< + Type, + Condition, + Options extends Required, +> = ConditionalSimplifyDeep extends true + ? Type[Key] + : IsPlainObject extends true + ? _ConditionalPickDeep + : typeof conditionalPickDeepSymbol; +}, (typeof conditionalPickDeepSymbol | undefined) | EmptyObject>, never, UnknownRecord>; + +export {}; diff --git a/node_modules/type-fest/source/conditional-pick.d.ts b/node_modules/type-fest/source/conditional-pick.d.ts new file mode 100644 index 00000000..e7db8f6e --- /dev/null +++ b/node_modules/type-fest/source/conditional-pick.d.ts @@ -0,0 +1,48 @@ +import type {ConditionalKeys} from './conditional-keys.d.ts'; +import type {IsNever} from './is-never.d.ts'; + +/** +Pick keys from the shape that matches the given `Condition`. + +This is useful when you want to create a new type from a specific subset of an existing type. For example, you might want to pick all the primitive properties from a class and form a new automatically derived type. + +@example +``` +import type {Primitive, ConditionalPick} from 'type-fest'; + +class Awesome { + constructor(public name: string, public successes: number, public failures: bigint) {} + + run() { + // do something + } +} + +type PickPrimitivesFromAwesome = ConditionalPick; +//=> {name: string; successes: number; failures: bigint} +``` + +@example +``` +import type {ConditionalPick} from 'type-fest'; + +type Example = { + a: string; + b: string | number; + c: () => void; + d: {}; +}; + +type StringKeysOnly = ConditionalPick; +//=> {a: string} +``` + +@category Object +*/ +export type ConditionalPick = ConditionalKeys extends infer Keys + ? IsNever extends true + ? never + : Pick + : never; + +export {}; diff --git a/node_modules/type-fest/source/conditional-simplify-deep.d.ts b/node_modules/type-fest/source/conditional-simplify-deep.d.ts new file mode 100644 index 00000000..d87cd0a7 --- /dev/null +++ b/node_modules/type-fest/source/conditional-simplify-deep.d.ts @@ -0,0 +1,73 @@ +/** +Recursively simplifies a type while including and/or excluding certain types from being simplified. + +@example +``` +import type {ConditionalSimplifyDeep} from 'type-fest'; + +type TypeA = { + foo: { + a: string; + }; +}; + +type TypeB = { + foo: { + b: string; + }; +}; + +type SimplifyDeepTypeAB = ConditionalSimplifyDeep; +//=> {foo: {a: string; b: string}} +``` + +@example +``` +import type {ConditionalSimplifyDeep} from 'type-fest'; + +type SomeComplexType1 = { + a1: string; + b1: number; + c1: boolean; +}; + +type SomeComplexType2 = { + a2: string; + b2: number; + c2: boolean; +}; + +type TypeA = { + foo: { + a: string; + complexType: SomeComplexType1; + }; +}; + +type TypeB = { + foo: { + b: string; + complexType: SomeComplexType2; + }; +}; + +type SimplifyDeepTypeAB = ConditionalSimplifyDeep; +//=> { +// foo: { +// a: string; +// complexType: SomeComplexType1 & SomeComplexType2; +// b: string; +// }; +// } +``` + +@see {@link SimplifyDeep} +@category Object +*/ +export type ConditionalSimplifyDeep = Type extends ExcludeType + ? Type + : Type extends IncludeType + ? {[TypeKey in keyof Type]: ConditionalSimplifyDeep} + : Type; + +export {}; diff --git a/node_modules/type-fest/source/conditional-simplify.d.ts b/node_modules/type-fest/source/conditional-simplify.d.ts new file mode 100644 index 00000000..56667d2f --- /dev/null +++ b/node_modules/type-fest/source/conditional-simplify.d.ts @@ -0,0 +1,50 @@ +/** +Simplifies a type while including and/or excluding certain types from being simplified. + +Useful to improve type hints shown in editors. And also to transform an `interface` into a `type` to aid with assignability. + +@example +``` +import type {ConditionalSimplify} from 'type-fest'; + +type TypeA = { + a: string; +}; + +type TypeB = { + b: string; +}; + +type TypeAB = TypeA & TypeB; +//=> TypeA & TypeB + +type SimplifyTypeAB = ConditionalSimplify; +//=> {a: string; b: string} +``` + +@example +``` +import type {ConditionalSimplify} from 'type-fest'; + +type Simplify = ConditionalSimplify | Map | unknown[], object>; + +type A = Simplify & Set>; +//=> Set & Set + +type B = Simplify & Map>; +//=> Map & Map + +type C = Simplify<{a: number} & {b: string}>; +//=> {a: number; b: string} +``` + +@see {@link ConditionalSimplifyDeep} +@category Object +*/ +export type ConditionalSimplify = Type extends ExcludeType + ? Type + : Type extends IncludeType + ? {[TypeKey in keyof Type]: Type[TypeKey]} + : Type; + +export {}; diff --git a/node_modules/type-fest/source/delimiter-case.d.ts b/node_modules/type-fest/source/delimiter-case.d.ts new file mode 100644 index 00000000..1b4fb4e8 --- /dev/null +++ b/node_modules/type-fest/source/delimiter-case.d.ts @@ -0,0 +1,79 @@ +import type {ApplyDefaultOptions, AsciiPunctuation, StartsWith} from './internal/index.d.ts'; +import type {IsStringLiteral} from './is-string-literal.d.ts'; +import type {Merge} from './merge.d.ts'; +import type {_DefaultWordsOptions, Words, WordsOptions} from './words.d.ts'; + +export type _DefaultDelimiterCaseOptions = Merge<_DefaultWordsOptions, {splitOnNumbers: false}>; + +/** +Convert an array of words to delimiter case starting with a delimiter with input capitalization. +*/ +type DelimiterCaseFromArray< + Words extends string[], + Delimiter extends string, + OutputString extends string = '', +> = Words extends [ + infer FirstWord extends string, + ...infer RemainingWords extends string[], +] + ? DelimiterCaseFromArray extends true ? '' : Delimiter + }${FirstWord}`> + : OutputString; + +/** +Convert a string literal to a custom string delimiter casing. + +This can be useful when, for example, converting a camel-cased object property to an oddly cased one. + +@see {@link KebabCase} +@see {@link SnakeCase} + +@example +``` +import type {DelimiterCase} from 'type-fest'; + +// Simple + +const someVariable: DelimiterCase<'fooBar', '#'> = 'foo#bar'; +const someVariableNoSplitOnNumbers: DelimiterCase<'p2pNetwork', '#', {splitOnNumbers: false}> = 'p2p#network'; +const someVariableWithPunctuation: DelimiterCase<'div.card::after', '#', {splitOnPunctuation: true}> = 'div#card#after'; + +// Advanced + +type OddlyCasedProperties = { + [K in keyof T as DelimiterCase]: T[K] +}; + +type SomeOptions = { + dryRun: boolean; + includeFile: string; + foo: number; +}; + +const rawCliOptions: OddlyCasedProperties = { + 'dry#run': true, + 'include#file': 'bar.js', + foo: 123, +}; +``` + +@category Change case +@category Template literal + */ +export type DelimiterCase< + Value, + Delimiter extends string, + Options extends WordsOptions = {}, +> = Value extends string + ? Delimiter extends string // For distributing `Delimiter` + ? IsStringLiteral extends false + ? Value + : Lowercase>, + Delimiter + >> + : never + : Value; + +export {}; diff --git a/node_modules/type-fest/source/delimiter-cased-properties-deep.d.ts b/node_modules/type-fest/source/delimiter-cased-properties-deep.d.ts new file mode 100644 index 00000000..c1be4738 --- /dev/null +++ b/node_modules/type-fest/source/delimiter-cased-properties-deep.d.ts @@ -0,0 +1,115 @@ +import type {_DefaultDelimiterCaseOptions, DelimiterCase} from './delimiter-case.d.ts'; +import type {ApplyDefaultOptions, NonRecursiveType} from './internal/index.d.ts'; +import type {UnknownArray} from './unknown-array.d.ts'; +import type {WordsOptions} from './words.d.ts'; + +/** +Convert object properties to a custom string delimiter casing recursively. + +This can be useful when, for example, converting some API types from a different style. + +@see {@link DelimiterCase} +@see {@link DelimiterCasedProperties} + +@example +``` +import type {DelimiterCasedPropertiesDeep} from 'type-fest'; + +type User = { + userId: number; + userName: string; +}; + +type UserWithFriends = { + userInfo: User; + userFriends: User[]; +}; + +const result: DelimiterCasedPropertiesDeep = { + 'user-info': { + 'user-id': 1, + 'user-name': 'Tom', + }, + 'user-friends': [ + { + 'user-id': 2, + 'user-name': 'Jerry', + }, + { + 'user-id': 3, + 'user-name': 'Spike', + }, + ], +}; + +const splitOnNumbers: DelimiterCasedPropertiesDeep<{line1: {line2: [{line3: string}]}}, '-', {splitOnNumbers: true}> = { + 'line-1': { + 'line-2': [ + { + 'line-3': 'string', + }, + ], + }, +}; + +const splitOnPunctuation: DelimiterCasedPropertiesDeep<{'user@info': {'user::id': number; 'user::name': string}}, '-', {splitOnPunctuation: true}> = { + 'user-info': { + 'user-id': 1, + 'user-name': 'Tom', + }, +}; +``` + +@category Change case +@category Template literal +@category Object +*/ +export type DelimiterCasedPropertiesDeep< + Value, + Delimiter extends string, + Options extends WordsOptions = {}, +> = _DelimiterCasedPropertiesDeep>; + +type _DelimiterCasedPropertiesDeep< + Value, + Delimiter extends string, + Options extends Required, +> = Value extends NonRecursiveType + ? Value + : Value extends UnknownArray + ? DelimiterCasedPropertiesArrayDeep + : Value extends Set + ? Set<_DelimiterCasedPropertiesDeep> + : Value extends object + ? { + [K in keyof Value as DelimiterCase]: + _DelimiterCasedPropertiesDeep + } + : Value; + +// This is a copy of CamelCasedPropertiesArrayDeep (see: camel-cased-properties-deep.d.ts). +// These types should be kept in sync. +type DelimiterCasedPropertiesArrayDeep< + Value extends UnknownArray, + Delimiter extends string, + Options extends Required, +> = Value extends [] + ? [] + // Trailing spread array + : Value extends [infer U, ...infer V] + ? [_DelimiterCasedPropertiesDeep, ..._DelimiterCasedPropertiesDeep] + : Value extends readonly [infer U, ...infer V] + ? readonly [_DelimiterCasedPropertiesDeep, ..._DelimiterCasedPropertiesDeep] + // Leading spread array + : Value extends [...infer U, infer V] + ? [..._DelimiterCasedPropertiesDeep, _DelimiterCasedPropertiesDeep] + : Value extends readonly [...infer U, infer V] + ? readonly [..._DelimiterCasedPropertiesDeep, _DelimiterCasedPropertiesDeep] + // Array + : Value extends Array + ? Array<_DelimiterCasedPropertiesDeep> + : Value extends ReadonlyArray + ? ReadonlyArray<_DelimiterCasedPropertiesDeep> + : never; + +export {}; diff --git a/node_modules/type-fest/source/delimiter-cased-properties.d.ts b/node_modules/type-fest/source/delimiter-cased-properties.d.ts new file mode 100644 index 00000000..d4d97815 --- /dev/null +++ b/node_modules/type-fest/source/delimiter-cased-properties.d.ts @@ -0,0 +1,52 @@ +import type {_DefaultDelimiterCaseOptions, DelimiterCase} from './delimiter-case.d.ts'; +import type {ApplyDefaultOptions} from './internal/index.d.ts'; +import type {WordsOptions} from './words.d.ts'; + +/** +Convert object properties to a custom string delimiter casing. + +This can be useful when, for example, converting some API types from a different style. + +@see {@link DelimiterCase} +@see {@link DelimiterCasedPropertiesDeep} + +@example +``` +import type {DelimiterCasedProperties} from 'type-fest'; + +type User = { + userId: number; + userName: string; +}; + +const result: DelimiterCasedProperties = { + 'user-id': 1, + 'user-name': 'Tom', +}; + +const splitOnNumbers: DelimiterCasedProperties<{line1: string}, '-', {splitOnNumbers: true}> = { + 'line-1': 'string', +}; + +const splitOnPunctuation: DelimiterCasedProperties<{'foo::bar': string}, '-', {splitOnPunctuation: true}> = { + 'foo-bar': 'string', +}; +``` + +@category Change case +@category Template literal +@category Object +*/ +export type DelimiterCasedProperties< + Value, + Delimiter extends string, + Options extends WordsOptions = {}, +> = Value extends Function + ? Value + : Value extends Array + ? Value + : {[K in keyof Value as + DelimiterCase> + ]: Value[K]}; + +export {}; diff --git a/node_modules/type-fest/source/distributed-omit.d.ts b/node_modules/type-fest/source/distributed-omit.d.ts new file mode 100644 index 00000000..08d68621 --- /dev/null +++ b/node_modules/type-fest/source/distributed-omit.d.ts @@ -0,0 +1,96 @@ +import type {KeysOfUnion} from './keys-of-union.d.ts'; + +/** +Omits keys from a type, distributing the operation over a union. + +TypeScript's `Omit` doesn't distribute over unions, leading to the erasure of unique properties from union members when omitting keys. This creates a type that only retains properties common to all union members, making it impossible to access member-specific properties after the Omit. Essentially, using `Omit` on a union type merges the types into a less specific one, hindering type narrowing and property access based on discriminants. This type solves that. + +Example: + +``` +type A = { + discriminant: 'A'; + foo: string; + a: number; +}; + +type B = { + discriminant: 'B'; + foo: string; + b: string; +}; + +type Union = A | B; + +type OmittedUnion = Omit; +//=> {discriminant: 'A' | 'B'} + +declare const omittedUnion: OmittedUnion; + +if (omittedUnion.discriminant === 'A') { + // We would like to narrow `omittedUnion`'s type + // to `A` here, but we can't because `Omit` + // doesn't distribute over unions. + + // @ts-expect-error + const aValue = omittedUnion.a; + // Error: `a` is not a property of `{discriminant: 'A' | 'B'}` +} +``` + +While `Except` solves this problem, it restricts the keys you can omit to the ones that are present in **ALL** union members, where `DistributedOmit` allows you to omit keys that are present in **ANY** union member. + +@example +``` +import type {DistributedOmit} from 'type-fest'; + +type A = { + discriminant: 'A'; + foo: string; + a: number; +}; + +type B = { + discriminant: 'B'; + foo: string; + bar: string; + b: string; +}; + +type C = { + discriminant: 'C'; + bar: string; + c: boolean; +}; + +// Notice that `foo` exists in `A` and `B`, but not in `C`, and +// `bar` exists in `B` and `C`, but not in `A`. + +type Union = A | B | C; + +type OmittedUnion = DistributedOmit; + +declare const omittedUnion: OmittedUnion; + +if (omittedUnion.discriminant === 'A') { + const aValue = omittedUnion.a; + // OK + + // @ts-expect-error + const fooValue = omittedUnion.foo; + // Error: `foo` is not a property of `{discriminant: 'A'; a: string}` + + // @ts-expect-error + const barValue = omittedUnion.bar; + // Error: `bar` is not a property of `{discriminant: 'A'; a: string}` +} +``` + +@category Object +*/ +export type DistributedOmit> = + ObjectType extends unknown + ? Omit + : never; + +export {}; diff --git a/node_modules/type-fest/source/distributed-pick.d.ts b/node_modules/type-fest/source/distributed-pick.d.ts new file mode 100644 index 00000000..e40a19eb --- /dev/null +++ b/node_modules/type-fest/source/distributed-pick.d.ts @@ -0,0 +1,92 @@ +import type {KeysOfUnion} from './keys-of-union.d.ts'; + +/** +Pick keys from a type, distributing the operation over a union. + +TypeScript's `Pick` doesn't distribute over unions, leading to the erasure of unique properties from union members when picking keys. This creates a type that only retains properties common to all union members, making it impossible to access member-specific properties after the Pick. Essentially, using `Pick` on a union type merges the types into a less specific one, hindering type narrowing and property access based on discriminants. This type solves that. + +Example: + +``` +type A = { + discriminant: 'A'; + foo: { + bar: string; + }; +}; + +type B = { + discriminant: 'B'; + foo: { + baz: string; + }; +}; + +type Union = A | B; + +type PickedUnion = Pick; +//=> {discriminant: 'A' | 'B'; foo: {bar: string} | {baz: string}} + +declare const pickedUnion: PickedUnion; + +if (pickedUnion.discriminant === 'A') { + // We would like to narrow `pickedUnion`'s type + // to `A` here, but we can't because `Pick` + // doesn't distribute over unions. + + // @ts-expect-error + const barValue = pickedUnion.foo.bar; + // Error: Property 'bar' does not exist on type '{bar: string} | {baz: string}'. +} +``` + +@example +``` +import type {DistributedPick} from 'type-fest'; + +type A = { + discriminant: 'A'; + foo: { + bar: string; + }; + extraneous: boolean; +}; + +type B = { + discriminant: 'B'; + foo: { + baz: string; + }; + extraneous: boolean; +}; + +// Notice that `foo.bar` exists in `A` but not in `B`. + +type Union = A | B; + +type PickedUnion = DistributedPick; + +declare const pickedUnion: PickedUnion; + +if (pickedUnion.discriminant === 'A') { + const barValue = pickedUnion.foo.bar; + // OK + + // @ts-expect-error + const extraneousValue = pickedUnion.extraneous; + // Error: Property `extraneous` does not exist on type `Pick`. + + // @ts-expect-error + const bazValue = pickedUnion.foo.baz; + // Error: `bar` is not a property of `{discriminant: 'A'; a: string}`. +} +``` + +@category Object +*/ +export type DistributedPick> = + ObjectType extends unknown + ? Pick> + : never; + +export {}; diff --git a/node_modules/type-fest/source/empty-object.d.ts b/node_modules/type-fest/source/empty-object.d.ts new file mode 100644 index 00000000..7fabd819 --- /dev/null +++ b/node_modules/type-fest/source/empty-object.d.ts @@ -0,0 +1,51 @@ +declare const emptyObjectSymbol: unique symbol; + +/** +Represents a strictly empty plain object, the `{}` value. + +When you annotate something as the type `{}`, it can be anything except `null` and `undefined`. This means that you cannot use `{}` to represent an empty plain object ([read more](https://stackoverflow.com/questions/47339869/typescript-empty-object-and-any-difference/52193484#52193484)). + +@example +``` +import type {EmptyObject} from 'type-fest'; + +// The following illustrates the problem with `{}`. +const foo1: {} = {}; // Pass +const foo2: {} = []; // Pass +const foo3: {} = 42; // Pass +const foo4: {} = {a: 1}; // Pass + +// With `EmptyObject` only the first case is valid. +const bar1: EmptyObject = {}; // Pass +// @ts-expect-error +const bar2: EmptyObject = []; // Fail +// @ts-expect-error +const bar3: EmptyObject = 42; // Fail +// @ts-expect-error +const bar4: EmptyObject = {a: 1}; // Fail +``` + +Unfortunately, `Record`, `Record` and `Record` do not work. See {@link https://github.com/sindresorhus/type-fest/issues/395 #395}. + +@category Object +*/ +export type EmptyObject = {[emptyObjectSymbol]?: never}; + +/** +Returns a boolean for whether the type is strictly equal to an empty plain object, the `{}` value. + +@example +``` +import type {IsEmptyObject} from 'type-fest'; + +type Pass = IsEmptyObject<{}>; //=> true +type Fail1 = IsEmptyObject<[]>; //=> false +type Fail2 = IsEmptyObject; //=> false +``` + +@see {@link EmptyObject} +@category Object +*/ +export type IsEmptyObject = T extends EmptyObject ? true : false; + +export {}; diff --git a/node_modules/type-fest/source/entries.d.ts b/node_modules/type-fest/source/entries.d.ts new file mode 100644 index 00000000..42d1f2ed --- /dev/null +++ b/node_modules/type-fest/source/entries.d.ts @@ -0,0 +1,64 @@ +import type {_ArrayEntry, _MapEntry, _ObjectEntry, _SetEntry} from './entry.d.ts'; + +type ArrayEntries = Array<_ArrayEntry>; +type MapEntries = Array<_MapEntry>; +type ObjectEntries = Array<_ObjectEntry>; +type SetEntries> = Array<_SetEntry>; + +/** +Create a type that describes the key-value pairs produced when calling a collection’s `entries` method. + +For example the {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries|`Object`}, {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries|`Map`}, {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/entries|`Array`}, and {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/entries|`Set`} collections all have this method. Note that `WeakMap` and `WeakSet` do not have this method since their entries are not enumerable. + +@see `Entry` if you want to just access the type of a single entry. + +@example +``` +import type {Entries} from 'type-fest'; + +type Example = { + someKey: number; +}; + +const manipulatesEntries = (examples: Entries) => examples.map(example => [ + // Does some arbitrary processing on the key (with type information available) + example[0].toUpperCase(), + + // Does some arbitrary processing on the value (with type information available) + example[1].toFixed(0), +]); + +const example: Example = {someKey: 1}; +const entries = Object.entries(example) as Entries; +const output = manipulatesEntries(entries); + +// Objects +const objectExample = {a: 1}; +const objectEntries: Entries = [['a', 1]]; + +// Arrays +const arrayExample = ['a', 1]; +const arrayEntries: Entries = [[0, 'a'], [1, 1]]; + +// Maps +const mapExample = new Map([['a', 1]]); +const mapEntries: Entries = [['a', 1]]; + +// Sets +const setExample = new Set(['a', 1]); +const setEntries: Entries = [['a', 'a'], [1, 1]]; +``` + +@category Object +@category Map +@category Set +@category Array +*/ +export type Entries = + BaseType extends Map ? MapEntries + : BaseType extends Set ? SetEntries + : BaseType extends readonly unknown[] ? ArrayEntries + : BaseType extends object ? ObjectEntries + : never; + +export {}; diff --git a/node_modules/type-fest/source/entry.d.ts b/node_modules/type-fest/source/entry.d.ts new file mode 100644 index 00000000..719f012e --- /dev/null +++ b/node_modules/type-fest/source/entry.d.ts @@ -0,0 +1,67 @@ +type MapKey = BaseType extends Map ? KeyType : never; +type MapValue = BaseType extends Map ? ValueType : never; + +export type _ArrayEntry = [number, BaseType[number]]; +export type _MapEntry = [MapKey, MapValue]; +export type _ObjectEntry = [keyof BaseType, BaseType[keyof BaseType]]; +export type _SetEntry = BaseType extends Set ? [ItemType, ItemType] : never; + +/** +Create a type that describes a single key-value pair produced when calling a collection’s `entries` method. + +For example the {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries|`Object`}, {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries|`Map`}, {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/entries|`Array`}, and {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/entries|`Set`} collections all have this method. Note that `WeakMap` and `WeakSet` do not have this method since their entries are not enumerable. + +@see `Entries` if you want to just access the type of the array of entries (which is the return of the `.entries()` method). + +@example +``` +import type {Entry} from 'type-fest'; + +type Example = { + someKey: number; +}; + +const manipulatesEntry = (example: Entry) => [ + // Does some arbitrary processing on the key (with type information available) + example[0].toUpperCase(), + + // Does some arbitrary processing on the value (with type information available) + example[1].toFixed(0), +]; + +const example: Example = {someKey: 1}; +const entry = Object.entries(example)[0] as Entry; +const output = manipulatesEntry(entry); + +// Objects +const objectExample = {a: 1}; +const objectEntry: Entry = ['a', 1]; + +// Arrays +const arrayExample = ['a', 1]; +const arrayEntryString: Entry = [0, 'a']; +const arrayEntryNumber: Entry = [1, 1]; + +// Maps +const mapExample = new Map([['a', 1]]); +const mapEntry: Entry = ['a', 1]; + +// Sets +const setExample = new Set(['a', 1]); +const setEntryString: Entry = ['a', 'a']; +const setEntryNumber: Entry = [1, 1]; +``` + +@category Object +@category Map +@category Array +@category Set +*/ +export type Entry = + BaseType extends Map ? _MapEntry + : BaseType extends Set ? _SetEntry + : BaseType extends readonly unknown[] ? _ArrayEntry + : BaseType extends object ? _ObjectEntry + : never; + +export {}; diff --git a/node_modules/type-fest/source/exact.d.ts b/node_modules/type-fest/source/exact.d.ts new file mode 100644 index 00000000..46d01b76 --- /dev/null +++ b/node_modules/type-fest/source/exact.d.ts @@ -0,0 +1,73 @@ +import type {ObjectValue} from './internal/index.d.ts'; +import type {ArrayElement} from './array-element.d.ts'; +import type {IsEqual} from './is-equal.d.ts'; +import type {KeysOfUnion} from './keys-of-union.d.ts'; +import type {IsUnknown} from './is-unknown.d.ts'; +import type {Primitive} from './primitive.d.ts'; + +/** +Create a type from `ParameterType` and `InputType` and change keys exclusive to `InputType` to `never`. +- Generate a list of keys that exists in `InputType` but not in `ParameterType`. +- Mark these excess keys as `never`. +*/ +type ExactObject = {[Key in keyof ParameterType]: Exact>} + & Record>, never>; + +/** +Create a type that does not allow extra properties, meaning it only allows properties that are explicitly declared. + +This is useful for function type-guarding to reject arguments with excess properties. Due to the nature of TypeScript, it does not complain if excess properties are provided unless the provided value is an object literal. + +*Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/12936) if you want to have this type as a built-in in TypeScript.* + +@example +``` +type OnlyAcceptName = {name: string}; + +declare function onlyAcceptName(arguments_: OnlyAcceptName): void; + +// TypeScript complains about excess properties when an object literal is provided. +// @ts-expect-error +onlyAcceptName({name: 'name', id: 1}); +// `id` is excess + +// TypeScript does not complain about excess properties when the provided value is a variable (not an object literal). +const invalidInput = {name: 'name', id: 1}; +onlyAcceptName(invalidInput); // No errors +``` + +Having `Exact` allows TypeScript to reject excess properties. + +@example +``` +import type {Exact} from 'type-fest'; + +type OnlyAcceptName = {name: string}; + +declare function onlyAcceptNameImproved>(arguments_: T): void; + +const invalidInput = {name: 'name', id: 1}; +// @ts-expect-error +onlyAcceptNameImproved(invalidInput); // Compilation error +``` + +[Read more](https://stackoverflow.com/questions/49580725/is-it-possible-to-restrict-typescript-object-to-contain-only-properties-defined) + +@category Utilities +*/ +export type Exact = + // Before distributing, check if the two types are equal and if so, return the parameter type immediately + IsEqual extends true ? ParameterType + // If the parameter is a primitive, return it as is immediately to avoid it being converted to a complex type + : ParameterType extends Primitive ? ParameterType + // If the parameter is an unknown, return it as is immediately to avoid it being converted to a complex type + : IsUnknown extends true ? unknown + // If the parameter is a Function, return it as is because this type is not capable of handling function, leave it to TypeScript + : ParameterType extends Function ? ParameterType + // Convert union of array to array of union: A[] & B[] => (A & B)[] + : ParameterType extends unknown[] ? Array, ArrayElement>> + // In TypeScript, Array is a subtype of ReadonlyArray, so always test Array before ReadonlyArray. + : ParameterType extends readonly unknown[] ? ReadonlyArray, ArrayElement>> + : ExactObject; + +export {}; diff --git a/node_modules/type-fest/source/except.d.ts b/node_modules/type-fest/source/except.d.ts new file mode 100644 index 00000000..e89092b7 --- /dev/null +++ b/node_modules/type-fest/source/except.d.ts @@ -0,0 +1,112 @@ +import type {ApplyDefaultOptions} from './internal/index.d.ts'; +import type {IsEqual} from './is-equal.d.ts'; + +/** +Filter out keys from an object. + +Returns `never` if `Exclude` is strictly equal to `Key`. +Returns `never` if `Key` extends `Exclude`. +Returns `Key` otherwise. + +@example +``` +type Filtered = Filter<'foo', 'foo'>; +//=> never +``` + +@example +``` +type Filtered = Filter<'bar', string>; +//=> never +``` + +@example +``` +type Filtered = Filter<'bar', 'foo'>; +//=> 'bar' +``` + +@see {Except} +*/ +type Filter = IsEqual extends true ? never : (KeyType extends ExcludeType ? never : KeyType); + +export type ExceptOptions = { + /** + Disallow assigning non-specified properties. + + Note that any omitted properties in the resulting type will be present in autocomplete as `undefined`. + + @default false + */ + requireExactProps?: boolean; +}; + +type DefaultExceptOptions = { + requireExactProps: false; +}; + +/** +Create a type from an object type without certain keys. + +We recommend setting the `requireExactProps` option to `true`. + +This type is a stricter version of [`Omit`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-5.html#the-omit-helper-type). The `Omit` type does not restrict the omitted keys to be keys present on the given type, while `Except` does. The benefits of a stricter type are avoiding typos and allowing the compiler to pick up on rename refactors automatically. + +This type was proposed to the TypeScript team, which declined it, saying they prefer that libraries implement stricter versions of the built-in types ([microsoft/TypeScript#30825](https://github.com/microsoft/TypeScript/issues/30825#issuecomment-523668235)). + +@example +``` +import type {Except} from 'type-fest'; + +type Foo = { + a: number; + b: string; +}; + +type FooWithoutA = Except; +//=> {b: string} + +// @ts-expect-error +const fooWithoutA: FooWithoutA = {a: 1, b: '2'}; +// errors: 'a' does not exist in type '{ b: string; }' + +type FooWithoutB = Except; +//=> {a: number} & Partial> + +// @ts-expect-error +const fooWithoutB: FooWithoutB = {a: 1, b: '2'}; +// errors at 'b': Type 'string' is not assignable to type 'undefined'. + +// The `Omit` utility type doesn't work when omitting specific keys from objects containing index signatures. + +// Consider the following example: + +type UserData = { + [metadata: string]: string; + email: string; + name: string; + role: 'admin' | 'user'; +}; + +// `Omit` clearly doesn't behave as expected in this case: +type PostPayload = Omit; +//=> {[x: string]: string; [x: number]: string} + +// In situations like this, `Except` works better. +// It simply removes the `email` key while preserving all the other keys. +type PostPayloadFixed = Except; +//=> {[x: string]: string; name: string; role: 'admin' | 'user'} +``` + +@category Object +*/ +export type Except = + _Except>; + +type _Except> = { + [KeyType in keyof ObjectType as Filter]: ObjectType[KeyType]; +} & (Options['requireExactProps'] extends true + ? Partial> + : {}); + +export {}; diff --git a/node_modules/type-fest/source/exclude-exactly.d.ts b/node_modules/type-fest/source/exclude-exactly.d.ts new file mode 100644 index 00000000..a30d8e8b --- /dev/null +++ b/node_modules/type-fest/source/exclude-exactly.d.ts @@ -0,0 +1,57 @@ +import type {IsNever} from './is-never.d.ts'; +import type {IsAny} from './is-any.d.ts'; +import type {If} from './if.d.ts'; +import type {IsEqual} from './is-equal.d.ts'; +import type {IfNotAnyOrNever} from './internal/type.d.ts'; + +/** +A stricter version of `Exclude` that excludes types only when they are exactly identical. + +@example +``` +import type {ExcludeExactly} from 'type-fest'; + +type TestExclude1 = Exclude<'a' | 'b' | 'c' | 1 | 2 | 3, string>; +//=> 1 | 2 | 3 + +type TestExcludeExactly1 = ExcludeExactly<'a' | 'b' | 'c' | 1 | 2 | 3, string>; +//=> 'a' | 'b' | 'c' | 1 | 2 | 3 + +type TestExclude2 = Exclude<'a' | 'b' | 'c' | 1 | 2 | 3, any>; +//=> never + +type TestExcludeExactly2 = ExcludeExactly<'a' | 'b' | 'c' | 1 | 2 | 3, any>; +//=> 'a' | 'b' | 'c' | 1 | 2 | 3 + +type TestExclude3 = Exclude<{a: string} | {a: string; b: string}, {a: string}>; +//=> never + +type TestExcludeExactly3 = ExcludeExactly<{a: string} | {a: string; b: string}, {a: string}>; +//=> {a: string; b: string} +``` + +@category Improved Built-in +*/ +export type ExcludeExactly = + IfNotAnyOrNever; + // If `Union` is `any`, then if `Delete` is `any`, return `never`, else return `Union`. + ifAny: If, never, Union>; + // If `Union` is `never`, then if `Delete` is `never`, return `never`, else return `Union`. + ifNever: If, never, Union>; + }>; + +type _ExcludeExactly = + IfNotAnyOrNever, true, never> + : never] extends [never] ? Union : never + : never; + // If `Delete` is `any` or `never`, then return `Union`, + // because `Union` cannot be `any` or `never` here. + ifAny: Union; + ifNever: Union; + }>; + +export {}; diff --git a/node_modules/type-fest/source/exclude-rest-element.d.ts b/node_modules/type-fest/source/exclude-rest-element.d.ts new file mode 100644 index 00000000..1f89fea1 --- /dev/null +++ b/node_modules/type-fest/source/exclude-rest-element.d.ts @@ -0,0 +1,40 @@ +import type {SplitOnRestElement} from './split-on-rest-element.d.ts'; +import type {IsArrayReadonly} from './internal/array.d.ts'; +import type {UnknownArray} from './unknown-array.d.ts'; +import type {IfNotAnyOrNever} from './internal/type.d.ts'; + +/** +Create a tuple with the [`rest`](https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types) element removed. + +@example +``` +import type {ExcludeRestElement} from 'type-fest'; + +type T1 = ExcludeRestElement<[number, ...string[], string, 'foo']>; +//=> [number, string, 'foo'] + +type T2 = ExcludeRestElement<[...boolean[], string]>; +//=> [string] + +type T3 = ExcludeRestElement<[...Array<'foo'>, true]>; +//=> [true] + +type T4 = ExcludeRestElement<[number, string]>; +//=> [number, string] +``` + +@see {@link ExtractRestElement} +@see {@link SplitOnRestElement} +@category Array +*/ +export type ExcludeRestElement = IfNotAnyOrNever extends infer Result + ? Result extends readonly UnknownArray[] + ? IsArrayReadonly extends true + ? Readonly<[...Result[0], ...Result[2]]> + : [...Result[0], ...Result[2]] + : never + : never; +}>; + +export {}; diff --git a/node_modules/type-fest/source/exclude-strict.d.ts b/node_modules/type-fest/source/exclude-strict.d.ts new file mode 100644 index 00000000..dc23322d --- /dev/null +++ b/node_modules/type-fest/source/exclude-strict.d.ts @@ -0,0 +1,51 @@ +/** +A stricter version of {@link Exclude} that ensures every member of `U` can successfully exclude something from `T`. + +For example, `ExcludeStrict` will error because `bigint` cannot exclude anything from `string | number | boolean`. + +@example +``` +// Valid Examples +import type {ExcludeStrict} from 'type-fest'; + +type Example1 = ExcludeStrict<{status: 'success'; data: string[]} | {status: 'error'; error: string}, {status: 'success'}>; +//=> {status: 'error'; error: string} + +type Example2 = ExcludeStrict<'xs' | 's' | 'm' | 'l' | 'xl', 'xs' | 's'>; +//=> 'm' | 'l' | 'xl' + +type Example3 = ExcludeStrict<{x: number; y: number} | [number, number], unknown[]>; +//=> {x: number; y: number} +``` + +@example +``` +// Invalid Examples +import type {ExcludeStrict} from 'type-fest'; + +// `'xxl'` cannot exclude anything from `'xs' | 's' | 'm' | 'l' | 'xl'` +// @ts-expect-error +type Example1 = ExcludeStrict<'xs' | 's' | 'm' | 'l' | 'xl', 'xl' | 'xxl'>; +// ~~~~~~~~~~~~ +// Error: Type "'xl' | 'xxl'" does not satisfy the constraint 'never'. + +// `unknown[]` cannot exclude anything from `{x: number; y: number} | {x: string; y: string}` +// @ts-expect-error +type Example2 = ExcludeStrict<{x: number; y: number} | {x: string; y: string}, unknown[]>; +// ~~~~~~~~~ +// Error: Type 'unknown[]' does not satisfy the constraint 'never'. +``` + +@category Improved Built-in +*/ +export type ExcludeStrict< + T, + U extends [U] extends [ + // Ensure every member of `U` excludes something from `T` + U extends unknown ? ([T] extends [Exclude] ? never : U) : never, + ] + ? unknown + : never, +> = Exclude; + +export {}; diff --git a/node_modules/type-fest/source/exclusify-union.d.ts b/node_modules/type-fest/source/exclusify-union.d.ts new file mode 100644 index 00000000..41430545 --- /dev/null +++ b/node_modules/type-fest/source/exclusify-union.d.ts @@ -0,0 +1,147 @@ +import type {If} from './if.d.ts'; +import type {IfNotAnyOrNever, MapsSetsOrArrays, NonRecursiveType} from './internal/type.d.ts'; +import type {IsUnknown} from './is-unknown.d.ts'; +import type {KeysOfUnion} from './keys-of-union.d.ts'; +import type {Simplify} from './simplify.d.ts'; + +/** +Ensure mutual exclusivity in object unions by adding other members’ keys as `?: never`. + +Use-cases: +- You want each union member to be exclusive, preventing overlapping object shapes. +- You want to safely access any property defined across the union without additional type guards. + +@example +``` +import type {ExclusifyUnion} from 'type-fest'; + +type FileConfig = { + filePath: string; +}; + +type InlineConfig = { + content: string; +}; + +declare function loadConfig1(options: FileConfig | InlineConfig): void; + +// Someone could mistakenly provide both `filePath` and `content`. +loadConfig1({filePath: './config.json', content: '{ "name": "app" }'}); // No errors + +// Use `ExclusifyUnion` to prevent that mistake. +type Config = ExclusifyUnion; +//=> { +// filePath: string; +// content?: never; +// } | { +// content: string; +// filePath?: never; +// } + +declare function loadConfig2(options: Config): void; + +// @ts-expect-error +loadConfig2({filePath: './config.json', content: '{ "name": "app" }'}); +// Error: Argument of type '{ filePath: string; content: string; }' is not assignable to parameter of type '{ filePath: string; content?: never; } | { content: string; filePath?: never; }'. + +loadConfig2({filePath: './config.json'}); // Ok + +loadConfig2({content: '{ "name": "app" }'}); // Ok +``` + +@example +``` +import type {ExclusifyUnion} from 'type-fest'; + +type CardPayment = { + amount: number; + cardNumber: string; +}; + +type PaypalPayment = { + amount: number; + paypalId: string; +}; + +function processPayment1(payment: CardPayment | PaypalPayment) { + // @ts-expect-error + const details = payment.cardNumber ?? payment.paypalId; // Cannot access `cardNumber` or `paypalId` directly +} + +type Payment = ExclusifyUnion; +//=> { +// amount: number; +// cardNumber: string; +// paypalId?: never; +// } | { +// amount: number; +// paypalId: string; +// cardNumber?: never; +// } + +function processPayment2(payment: Payment) { + const details = payment.cardNumber ?? payment.paypalId; // Ok + //=> string +} +``` + +@example +``` +import type {ExclusifyUnion} from 'type-fest'; + +type A = ExclusifyUnion<{a: string} | {b: number}>; +//=> {a: string; b?: never} | {b: number; a?: never} + +type B = ExclusifyUnion<{a: string} | {b: number} | {c: boolean}>; +//=> { +// a: string; +// b?: never; +// c?: never; +// } | { +// b: number; +// a?: never; +// c?: never; +// } | { +// c: boolean; +// a?: never; +// b?: never; +// } + +type C = ExclusifyUnion<{a: string; b: number} | {b: string; c: number}>; +//=> { +// a: string; +// b: number; +// c?: never; +// } | { +// b: string; +// c: number; +// a?: never; +// } + +type D = ExclusifyUnion<{a?: 1; readonly b: 2} | {d: 4}>; +//=> {a?: 1; readonly b: 2; d?: never} | {d: 4; a?: never; b?: never} +``` + +@category Object +@category Union +*/ +export type ExclusifyUnion = IfNotAnyOrNever, Union, + Extract extends infer SkippedMembers + ? SkippedMembers | _ExclusifyUnion> + : never + >; +}>; + +type _ExclusifyUnion = Union extends unknown // For distributing `Union` + ? Simplify< + Union & Partial< + Record< + Exclude, keyof Union>, + never + > + > + > + : never; // Should never happen + +export {}; diff --git a/node_modules/type-fest/source/extends-strict.d.ts b/node_modules/type-fest/source/extends-strict.d.ts new file mode 100644 index 00000000..6353bffb --- /dev/null +++ b/node_modules/type-fest/source/extends-strict.d.ts @@ -0,0 +1,151 @@ +import type {IsNever} from './is-never.d.ts'; +import type {IsAny} from './is-any.d.ts'; +import type {ApplyDefaultOptions} from './internal/object.d.ts'; +import type {And} from './and.d.ts'; +import type {Or} from './or.d.ts'; +import type {IsUnknown} from './is-unknown.d.ts'; +import type {OrAll} from './or-all.d.ts'; + +export type ExtendsStrictOptions = { + /** + Whether to distribute over unions. + + @default false + + @example + ``` + import type {ExtendsStrict} from 'type-fest'; + + type T1 = ExtendsStrict; + //=> boolean + + type T2 = ExtendsStrict; + //=> false + ``` + */ + distributiveUnions?: boolean; + + /** + Whether `never` extends every other type. + + When enabled, `never` is not treated as a bottom type and only extends itself (or `any` / `unknown`). + + @default true + + @example + ``` + import type {ExtendsStrict} from 'type-fest'; + + type T1 = ExtendsStrict; + //=> false + + type T2 = ExtendsStrict; + //=> true + + type T3 = ExtendsStrict; + //=> true + + type T4 = ExtendsStrict; + //=> true + + type T5 = ExtendsStrict; + //=> true + ``` + + Note: This option only has an effect when checking assignability from `never` (`ExtendsStrict`), and not when checking assignability to `never` (`ExtendsStrict<..., never>`). + */ + strictNever?: boolean; + + /** + Whether `any` extends every other type. + + When enabled, `any` does not extend every other type, it only extends itself (or `unknown`). + + @default false + + @example + ``` + import type {ExtendsStrict} from 'type-fest'; + + type T1 = ExtendsStrict; + //=> false + + type T2 = ExtendsStrict; + //=> true + + type T3 = ExtendsStrict; + //=> true + + type T4 = ExtendsStrict; + //=> true + ``` + + Note: If `strictAny` is `false` and `distributiveUnions` is `true`, then `any` would distribute and the result would be the `boolean` type, except when checking assignability to `any` or `unknown`. + + @example + ``` + import type {ExtendsStrict} from 'type-fest'; + + type T1 = ExtendsStrict; + //=> boolean + + type T2 = ExtendsStrict; + //=> true + + type T3 = ExtendsStrict; + //=> true + ``` + + Note: This option only has an effect when checking assignability from `any` (`ExtendsStrict`), and not when checking assignability to `any` (`ExtendsStrict<..., any>`). + */ + strictAny?: boolean; +}; + +type DefaultExtendsStrictOptions = { + distributiveUnions: false; + strictNever: true; + strictAny: false; +}; + +/** +A customizable version of `extends` for checking whether one type is assignable to another. + +Refer {@link ExtendsStrictOptions} for the different ways you can customize the behavior of this type. + +@example +``` +import type {ExtendsStrict} from 'type-fest'; + +type T1 = ExtendsStrict; +//=> false + +type T2 = ExtendsStrict; +//=> false + +type T3 = ExtendsStrict; +//=> false +``` + +@see {@link ExtendsStrictOptions} + +@category Improved Built-in +*/ +export type ExtendsStrict = + _ExtendsStrict>; + +type _ExtendsStrict> = + And, Options['strictAny']> extends true + ? Or, IsUnknown> + : IsNever extends true + ? Options['strictNever'] extends true + ? OrAll<[IsNever, IsAny, IsUnknown]> + : true + : Options['distributiveUnions'] extends true + ? Left extends Right + ? true + : false + : [Left] extends [Right] + ? true + : false; + +export {}; diff --git a/node_modules/type-fest/source/extract-exactly.d.ts b/node_modules/type-fest/source/extract-exactly.d.ts new file mode 100644 index 00000000..df5be80c --- /dev/null +++ b/node_modules/type-fest/source/extract-exactly.d.ts @@ -0,0 +1,56 @@ +import type {IsAny} from './is-any.d.ts'; +import type {If} from './if.d.ts'; +import type {IsEqual} from './is-equal.d.ts'; +import type {IfNotAnyOrNever} from './internal/type.d.ts'; + +/** +A stricter version of `Extract` that extracts types only when they are exactly identical. + +@example +``` +import type {ExtractExactly} from 'type-fest'; + +type TestExtract1 = Extract<'a' | 'b' | 'c' | 1 | 2 | 3, string>; +//=> 'a' | 'b' | 'c' + +type TestExtractExactly1 = ExtractExactly<'a' | 'b' | 'c' | 1 | 2 | 3, string>; +//=> never + +type TestExtract2 = Extract<'a' | 'b' | 'c' | 1 | 2 | 3, any>; +//=> 'a' | 'b' | 'c' | 1 | 2 | 3 + +type TestExtractExactly2 = ExtractExactly<'a' | 'b' | 'c' | 1 | 2 | 3, any>; +//=> never + +type TestExtract3 = Extract<{a: string} | {a: string; b: string}, {a: string}>; +//=> {a: string} | {a: string; b: string} + +type TestExtractExactly3 = ExtractExactly<{a: string} | {a: string; b: string}, {a: string}>; +//=> {a: string} +``` + +@category Improved Built-in +*/ +export type ExtractExactly = + IfNotAnyOrNever; + // If `Union` is `any`, then if `Match` is `any`, return `any`, else return `never`. + ifAny: If, Union, never>; + // If `Union` is `never`, return `never`, doesn't matter what `Match` is. + ifNever: never; + }>; + +type _ExtractExactly = + IfNotAnyOrNever, true, never> + : never] extends [never] ? never : Union + : never; + // If `Match` is `any` or `never`, then return `never`, + // because `Union` cannot be `any` or `never` here. + ifAny: never; + ifNever: never; + }>; + +export {}; diff --git a/node_modules/type-fest/source/extract-rest-element.d.ts b/node_modules/type-fest/source/extract-rest-element.d.ts new file mode 100644 index 00000000..c84eb240 --- /dev/null +++ b/node_modules/type-fest/source/extract-rest-element.d.ts @@ -0,0 +1,30 @@ +import type {SplitOnRestElement} from './split-on-rest-element.d.ts'; +import type {UnknownArray} from './unknown-array.d.ts'; + +/** +Extract the [`rest`](https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types) element type from an array. + +@example +``` +import type {ExtractRestElement} from 'type-fest'; + +type T1 = ExtractRestElement<[number, ...string[], string, 'foo']>; +//=> string + +type T2 = ExtractRestElement<[...boolean[], string]>; +//=> boolean + +type T3 = ExtractRestElement<[...Array<'foo'>, true]>; +//=> 'foo' + +type T4 = ExtractRestElement<[number, string]>; +//=> never +``` + +@see {@link ExcludeRestElement} +@see {@link SplitOnRestElement} +@category Array +*/ +export type ExtractRestElement = SplitOnRestElement[1][number]; + +export {}; diff --git a/node_modules/type-fest/source/extract-strict.d.ts b/node_modules/type-fest/source/extract-strict.d.ts new file mode 100644 index 00000000..1279f039 --- /dev/null +++ b/node_modules/type-fest/source/extract-strict.d.ts @@ -0,0 +1,51 @@ +/** +A stricter version of {@link Extract} that ensures every member of `U` can successfully extract something from `T`. + +For example, `ExtractStrict` will error because `bigint` cannot extract anything from `string | number | boolean`. + +@example +``` +// Valid Examples +import type {ExtractStrict} from 'type-fest'; + +type Example1 = ExtractStrict<{status: 'success'; data: string[]} | {status: 'error'; error: string}, {status: 'success'}>; +//=> {status: 'success'; data: string[]} + +type Example2 = ExtractStrict<'xs' | 's' | 'm' | 'l' | 'xl', 'xs' | 's'>; +//=> 'xs' | 's' + +type Example3 = ExtractStrict<{x: number; y: number} | [number, number], unknown[]>; +//=> [number, number] +``` + +@example +``` +// Invalid Examples +import type {ExtractStrict} from 'type-fest'; + +// `'xxl'` cannot extract anything from `'xs' | 's' | 'm' | 'l' | 'xl'` +// @ts-expect-error +type Example1 = ExtractStrict<'xs' | 's' | 'm' | 'l' | 'xl', 'xl' | 'xxl'>; +// ~~~~~~~~~~~~ +// Error: Type "'xl' | 'xxl'" does not satisfy the constraint 'never'. + +// `unknown[]` cannot extract anything from `{x: number; y: number} | {x: string; y: string}` +// @ts-expect-error +type Example2 = ExtractStrict<{x: number; y: number} | {x: string; y: string}, unknown[]>; +// ~~~~~~~~~ +// Error: Type 'unknown[]' does not satisfy the constraint 'never'. +``` + +@category Improved Built-in +*/ +export type ExtractStrict< + T, + U extends [U] extends [ + // Ensure every member of `U` extracts something from `T` + U extends unknown ? (Extract extends never ? never : U) : never, + ] + ? unknown + : never, +> = Extract; + +export {}; diff --git a/node_modules/type-fest/source/find-global-type.d.ts b/node_modules/type-fest/source/find-global-type.d.ts new file mode 100644 index 00000000..5e62fae6 --- /dev/null +++ b/node_modules/type-fest/source/find-global-type.d.ts @@ -0,0 +1,68 @@ +/** +Tries to find the type of a global with the given name. + +Limitations: Due to peculiarities with the behavior of `globalThis`, "globally defined" only includes `var` declarations in `declare global` blocks, not `let` or `const` declarations. + +@example +``` +import type {FindGlobalType} from 'type-fest'; + +declare global { + const foo: number; // let and const don't work + var bar: string; // var works +} + +type FooType = FindGlobalType<'foo'>; //=> never (let/const don't work) +type BarType = FindGlobalType<'bar'>; //=> string +type OtherType = FindGlobalType<'other'>; //=> never (no global named 'other') +``` + +@category Utilities +*/ +export type FindGlobalType = typeof globalThis extends Record ? T : never; + +/** +Tries to find one or more types from their globally-defined constructors. + +Use-case: Conditionally referencing DOM types only when the DOM library present. + +*Limitations:* Due to peculiarities with the behavior of `globalThis`, "globally defined" has a narrow definition in this case. Declaring a class in a `declare global` block won't work, instead you must declare its type using an interface and declare its constructor as a `var` (*not* `let`/`const`) inside the `declare global` block. + +@example +``` +import type {FindGlobalInstanceType} from 'type-fest'; + +class Point { + constructor(public x: number, public y: number) {} +} + +type PointLike = Point | FindGlobalInstanceType<'DOMPoint'>; +``` + +@example +``` +import type {FindGlobalInstanceType} from 'type-fest'; + +declare global { + // Class syntax won't add the key to `globalThis` + class Foo {} + + // interface + constructor style works + interface Bar { + bar: string; + } + var Bar: new () => Bar; // Not let or const +} + +type FindFoo = FindGlobalInstanceType<'Foo'>; // Doesn't work +type FindBar = FindGlobalInstanceType<'Bar'>; // Works +``` + +@category Utilities +*/ +export type FindGlobalInstanceType = + Name extends string + ? typeof globalThis extends Record infer T> ? T : never + : never; + +export {}; diff --git a/node_modules/type-fest/source/fixed-length-array.d.ts b/node_modules/type-fest/source/fixed-length-array.d.ts new file mode 100644 index 00000000..eaa0d728 --- /dev/null +++ b/node_modules/type-fest/source/fixed-length-array.d.ts @@ -0,0 +1,97 @@ +import type {Except} from './except.d.ts'; +import type {TupleOf} from './tuple-of.d.ts'; + +/** +Methods to exclude. +*/ +type ArrayLengthMutationKeys = 'splice' | 'push' | 'pop' | 'shift' | 'unshift'; + +/** +Create a type that represents an array of the given type and length. The `Array` prototype methods that manipulate its length are excluded from the resulting type. + +The problem with the built-in tuple type is that it allows mutating methods like `push`, `pop` etc, which can cause issues, like in the following example: + +@example +``` +const color: [number, number, number] = [255, 128, 64]; + +function toHex([r, g, b]: readonly [number, number, number]) { + return `#${r.toString(16)}${g.toString(16)}${b.toString(16)}`; +} + +color.pop(); // Allowed + +console.log(toHex(color)); // Compiles fine, but fails at runtime since index `2` no longer contains a `number`. +``` + +`ArrayLengthMutationKeys` solves this problem by excluding methods like `push`, `pop` etc from the resulting type. + +@example +``` +import type {FixedLengthArray} from 'type-fest'; + +const color: FixedLengthArray = [255, 128, 64]; + +// @ts-expect-error +color.pop(); +// Error: Property 'pop' does not exist on type 'FixedLengthArray'. +``` + +Use-cases: +- Declaring fixed-length tuples or arrays with a large number of items. +- Creating an array of coordinates with a static length, for example, length of 3 for a 3D vector. + +@example +``` +import type {FixedLengthArray} from 'type-fest'; + +let color: FixedLengthArray = [255, 128, 64]; + +const red = color[0]; +//=> number +const green = color[1]; +//=> number +const blue = color[2]; +//=> number + +// @ts-expect-error +const alpha = color[3]; +// Error: Property '3' does not exist on type 'FixedLengthArray'. + +// You can write to valid indices. +color[0] = 128; +color[1] = 64; +color[2] = 32; + +// But you cannot write to out-of-bounds indices. +// @ts-expect-error +color[3] = 0.5; +// Error: Property '3' does not exist on type 'FixedLengthArray'. + +// @ts-expect-error +color.push(0.5); +// Error: Property 'push' does not exist on type 'FixedLengthArray'. + +// @ts-expect-error +color = [0, 128, 255, 0.5]; +// Error: Type '[number, number, number, number]' is not assignable to type 'FixedLengthArray'. Types of property 'length' are incompatible. + +// @ts-expect-error +color.length = 4; +// Error: Cannot assign to 'length' because it is a read-only property. + +function toHex([r, g, b]: readonly [number, number, number]) { + return `#${r.toString(16)}${g.toString(16)}${b.toString(16)}`; +} + +console.log(toHex(color)); // `FixedLengthArray` is assignable to `readonly [number, number, number]`. +``` + +@category Array +*/ +export type FixedLengthArray = + Except, ArrayLengthMutationKeys | number | 'length'> + & {readonly length: Length} + & (number extends Length ? {[n: number]: Element} : {}); // Add `number` index signature only for non-tuple arrays. + +export {}; diff --git a/node_modules/type-fest/source/get.d.ts b/node_modules/type-fest/source/get.d.ts new file mode 100644 index 00000000..eb79e90a --- /dev/null +++ b/node_modules/type-fest/source/get.d.ts @@ -0,0 +1,227 @@ +import type {ApplyDefaultOptions, ToString} from './internal/index.d.ts'; +import type {_LiteralStringUnion} from './literal-union.d.ts'; +import type {Paths} from './paths.d.ts'; +import type {Split} from './split.d.ts'; +import type {KeyAsString} from './key-as-string.d.ts'; +import type {DigitCharacter} from './characters.d.ts'; + +export type GetOptions = { + /** + Include `undefined` in the return type when accessing properties. + + Setting this to `false` is not recommended. + + @default true + */ + strict?: boolean; +}; + +type DefaultGetOptions = { + strict: true; +}; + +/** +Like the `Get` type but receives an array of strings as a path parameter. +*/ +type GetWithPath> = + Keys extends readonly [] + ? BaseType + : Keys extends readonly [infer Head, ...infer Tail] + ? GetWithPath< + PropertyOf, Options>, + Extract, + Options + > + : never; + +/** +Adds `undefined` to `Type` if `strict` is enabled. +*/ +type Strictify> = + Options['strict'] extends false ? Type : (Type | undefined); + +/** +If `Options['strict']` is `true`, includes `undefined` in the returned type when accessing properties on `Record`. + +Known limitations: +- Does not include `undefined` in the type on object types with an index signature (for example, `{a: string; [key: string]: string}`). +*/ +type StrictPropertyOf> = + Record extends BaseType + ? string extends keyof BaseType + ? Strictify // Record + : BaseType[Key] // Record<'a' | 'b', any> (Records with a string union as keys have required properties) + : BaseType[Key]; + +/** +Splits a dot-prop style path into a tuple comprised of the properties in the path. Handles square-bracket notation. + +@example +``` +type A = ToPath<'foo.bar.baz'>; +//=> ['foo', 'bar', 'baz'] + +type B = ToPath<'foo[0].bar.baz'>; +//=> ['foo', '0', 'bar', 'baz'] +``` +*/ +type ToPath = Split, '.', {strictLiteralChecks: false}>; + +/** +Replaces square-bracketed dot notation with dots, for example, `foo[0].bar` -> `foo.0.bar`. +*/ +type FixPathSquareBrackets = + Path extends `[${infer Head}]${infer Tail}` + ? Tail extends `[${string}` + ? `${Head}.${FixPathSquareBrackets}` + : `${Head}${FixPathSquareBrackets}` + : Path extends `${infer Head}[${infer Middle}]${infer Tail}` + ? `${Head}.${FixPathSquareBrackets<`[${Middle}]${Tail}`>}` + : Path; + +/** +Returns true if `LongString` is made up out of `Substring` repeated 0 or more times. + +@example +``` +type A = ConsistsOnlyOf<'aaa', 'a'>; //=> true +type B = ConsistsOnlyOf<'ababab', 'ab'>; //=> true +type C = ConsistsOnlyOf<'aBa', 'a'>; //=> false +type D = ConsistsOnlyOf<'', 'a'>; //=> true +``` +*/ +type ConsistsOnlyOf = + LongString extends '' + ? true + : LongString extends `${Substring}${infer Tail}` + ? ConsistsOnlyOf + : false; + +/** +Convert a type which may have number keys to one with string keys, making it possible to index using strings retrieved from template types. + +@example +``` +type WithNumbers = {foo: string; 0: boolean}; +type WithStrings = WithStringKeys; + +type WithNumbersKeys = keyof WithNumbers; +//=> 'foo' | 0 +type WithStringsKeys = keyof WithStrings; +//=> 'foo' | '0' +``` +*/ +type WithStringKeys = { + [Key in KeyAsString]: UncheckedIndex +}; + +/** +Perform a `T[U]` operation if `T` supports indexing. +*/ +type UncheckedIndex = [T] extends [Record] ? T[U] : never; + +/** +Get a property of an object or array. Works when indexing arrays using number-literal-strings, for example, `PropertyOf = number`, and when indexing objects with number keys. + +Note: +- Returns `unknown` if `Key` is not a property of `BaseType`, since TypeScript uses structural typing, and it cannot be guaranteed that extra properties unknown to the type system will exist at runtime. +- Returns `undefined` from nullish values, to match the behaviour of most deep-key libraries like `lodash`, `dot-prop`, etc. +*/ +type PropertyOf> = + BaseType extends null | undefined + ? undefined + : Key extends keyof BaseType + ? StrictPropertyOf + // Handle arrays and tuples + : BaseType extends readonly unknown[] + ? Key extends `${number}` + // For arrays with unknown length (regular arrays) + ? number extends BaseType['length'] + ? Strictify + // For tuples: check if the index is valid + : Key extends keyof BaseType + ? Strictify + // Out-of-bounds access for tuples + : unknown + // Non-numeric string key for arrays/tuples + : unknown + // Handle array-like objects + : BaseType extends { + [n: number]: infer Item; + length: number; // Note: This is needed to avoid being too lax with records types using number keys like `{0: string; 1: boolean}`. + } + ? ( + ConsistsOnlyOf extends true + ? Strictify + : unknown + ) + : Key extends keyof WithStringKeys + ? StrictPropertyOf, Key, Options> + : unknown; + +// This works by first splitting the path based on `.` and `[...]` characters into a tuple of string keys. Then it recursively uses the head key to get the next property of the current object, until there are no keys left. Number keys extract the item type from arrays, or are converted to strings to extract types from tuples and dictionaries with number keys. +/** +Get a deeply-nested property from an object using a key path, like [Lodash's `.get()`](https://lodash.com/docs#get) function. + +Use-case: Retrieve a property from deep inside an API response or some other complex object. + +@example +``` +import type {Get} from 'type-fest'; + +declare function get(object: BaseType, path: Path): Get; + +type ApiResponse = { + hits: { + hits: Array<{ + _id: string; + _source: { + name: Array<{ + given: string[]; + family: string; + }>; + birthDate: string; + }; + }>; + }; +}; + +const getName = (apiResponse: ApiResponse) => get(apiResponse, 'hits.hits[0]._source.name'); +//=> (apiResponse: ApiResponse) => { +// given: string[]; +// family: string; +// }[] | undefined + +// Path also supports a readonly array of strings +const getNameWithPathArray = (apiResponse: ApiResponse) => get(apiResponse, ['hits', 'hits', '0', '_source', 'name']); +//=> (apiResponse: ApiResponse) => { +// given: string[]; +// family: string; +// }[] | undefined + +// Non-strict mode: +type A = Get; +//=> string + +type B = Get, 'foo', {strict: true}>; +//=> string | undefined +``` + +@category Object +@category Array +@category Template literal +*/ +export type Get< + BaseType, + Path extends + | readonly string[] + | _LiteralStringUnion | Paths>>, + Options extends GetOptions = {}, +> = + GetWithPath< + BaseType, + Path extends string ? ToPath : Path, + ApplyDefaultOptions + >; + +export {}; diff --git a/node_modules/type-fest/source/global-this.d.ts b/node_modules/type-fest/source/global-this.d.ts new file mode 100644 index 00000000..bf363392 --- /dev/null +++ b/node_modules/type-fest/source/global-this.d.ts @@ -0,0 +1,24 @@ +/** +Declare locally scoped properties on `globalThis`. + +When defining a global variable in a declaration file is inappropriate, it can be helpful to define a `type` or `interface` (say `ExtraGlobals`) with the global variable and then cast `globalThis` via code like `globalThis as unknown as ExtraGlobals`. + +Instead of casting through `unknown`, you can update your `type` or `interface` to extend `GlobalThis` and then directly cast `globalThis`. + +@example +``` +import type {GlobalThis} from 'type-fest'; + +type ExtraGlobals = GlobalThis & { + readonly GLOBAL_TOKEN: string; +}; + +const globalToken = (globalThis as ExtraGlobals).GLOBAL_TOKEN; +//=> string +``` + +@category Type +*/ +export type GlobalThis = typeof globalThis; + +export {}; diff --git a/node_modules/type-fest/source/globals/index.d.ts b/node_modules/type-fest/source/globals/index.d.ts new file mode 100644 index 00000000..b55c8ae2 --- /dev/null +++ b/node_modules/type-fest/source/globals/index.d.ts @@ -0,0 +1,3 @@ +export type * from './observable-like.d.ts'; + +export {}; diff --git a/node_modules/type-fest/source/globals/observable-like.d.ts b/node_modules/type-fest/source/globals/observable-like.d.ts new file mode 100644 index 00000000..b6367f26 --- /dev/null +++ b/node_modules/type-fest/source/globals/observable-like.d.ts @@ -0,0 +1,78 @@ +declare global { + // eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- It has to be an `interface` so that it can be merged. + interface SymbolConstructor { + readonly observable: symbol; + } +} + +/** +@remarks +The TC39 observable proposal defines a `closed` property, but some implementations (such as xstream) do not as of 10/08/2021. +As well, some guidance on making an `Observable` to not include `closed` property. + +@see https://github.com/tc39/proposal-observable/blob/master/src/Observable.js#L129-L130 +@see https://github.com/staltz/xstream/blob/6c22580c1d84d69773ee4b0905df44ad464955b3/src/index.ts#L79-L85 +@see https://github.com/benlesh/symbol-observable#making-an-object-observable + +@category Observable +*/ +// eslint-disable-next-line type-fest/require-exported-types +export type Unsubscribable = { + unsubscribe(): void; +}; + +/** +@category Observable +*/ +type OnNext = (value: ValueType) => void; + +/** +@category Observable +*/ +type OnError = (error: unknown) => void; + +/** +@category Observable +*/ +type OnComplete = () => void; + +/** +@category Observable +*/ +// eslint-disable-next-line type-fest/require-exported-types +export type Observer = { + next: OnNext; + error: OnError; + complete: OnComplete; +}; + +/** +Matches a value that is like an [Observable](https://github.com/tc39/proposal-observable). + +You must import it as a sub-import: + +@example +``` +import type {ObservableLike} from 'type-fest/globals'; +``` + +@remarks +The TC39 Observable proposal defines 2 forms of `subscribe()`: +1. Three callback arguments: `subscribe(observer: OnNext, onError?: OnError, onComplete?: OnComplete): Unsubscribable;` +2. A single `observer` argument: (as defined below) + +But `Observable` implementations have evolved to preferring case 2 and some implementations choose not to implement case 1. Therefore, an `ObservableLike` cannot be trusted to implement the first case. (xstream and hand built observerables often do not implement case 1) + +@see https://github.com/tc39/proposal-observable#observable +@see https://github.com/tc39/proposal-observable/blob/master/src/Observable.js#L246-L259 +@see https://benlesh.com/posts/learning-observable-by-building-observable/ + +@category Observable +*/ +// eslint-disable-next-line type-fest/require-exported-types +export type ObservableLike = { + subscribe(observer?: Partial>): Unsubscribable; + [Symbol.observable](): ObservableLike; +}; + +export {}; diff --git a/node_modules/type-fest/source/greater-than-or-equal.d.ts b/node_modules/type-fest/source/greater-than-or-equal.d.ts new file mode 100644 index 00000000..d43d23ac --- /dev/null +++ b/node_modules/type-fest/source/greater-than-or-equal.d.ts @@ -0,0 +1,63 @@ +import type {GreaterThan} from './greater-than.d.ts'; + +/** +Returns a boolean for whether a given number is greater than or equal to another number. + +@example +``` +import type {GreaterThanOrEqual} from 'type-fest'; + +type A = GreaterThanOrEqual<1, -5>; +//=> true + +type B = GreaterThanOrEqual<1, 1>; +//=> true + +type C = GreaterThanOrEqual<1, 5>; +//=> false +``` + +Note: If either argument is the non-literal `number` type, the result is `boolean`. + +@example +``` +import type {GreaterThanOrEqual} from 'type-fest'; + +type A = GreaterThanOrEqual; +//=> boolean + +type B = GreaterThanOrEqual<1, number>; +//=> boolean + +type C = GreaterThanOrEqual; +//=> boolean +``` + +@example +``` +import type {GreaterThanOrEqual} from 'type-fest'; + +// Use `GreaterThanOrEqual` to constrain a function parameter to non-negative numbers. +declare function setNonNegative(value: GreaterThanOrEqual extends true ? N : never): void; + +setNonNegative(0); // ✅ Allowed +setNonNegative(1); // ✅ Allowed + +// @ts-expect-error +setNonNegative(-1); + +// @ts-expect-error +setNonNegative(-2); +``` +*/ +export type GreaterThanOrEqual = number extends A | B + ? boolean + : A extends number // For distributing `A` + ? B extends number // For distributing `B` + ? A extends B + ? true + : GreaterThan + : never // Should never happen + : never; // Should never happen + +export {}; diff --git a/node_modules/type-fest/source/greater-than.d.ts b/node_modules/type-fest/source/greater-than.d.ts new file mode 100644 index 00000000..2c2b7a7e --- /dev/null +++ b/node_modules/type-fest/source/greater-than.d.ts @@ -0,0 +1,92 @@ +import type {PositiveNumericStringGt} from './internal/index.d.ts'; +import type {IsEqual} from './is-equal.d.ts'; +import type {PositiveInfinity, NegativeInfinity, IsNegative} from './numeric.d.ts'; +import type {And} from './and.d.ts'; +import type {Or} from './or.d.ts'; +import type {Absolute} from './absolute.d.ts'; + +/** +Returns a boolean for whether a given number is greater than another number. + +@example +``` +import type {GreaterThan} from 'type-fest'; + +type A = GreaterThan<1, -5>; +//=> true + +type B = GreaterThan<1, 1>; +//=> false + +type C = GreaterThan<1, 5>; +//=> false +``` + +Note: If either argument is the non-literal `number` type, the result is `boolean`. + +@example +``` +import type {GreaterThan} from 'type-fest'; + +type A = GreaterThan; +//=> boolean + +type B = GreaterThan<1, number>; +//=> boolean + +type C = GreaterThan; +//=> boolean +``` + +@example +``` +import type {GreaterThan} from 'type-fest'; + +// Use `GreaterThan` to constrain a function parameter to positive numbers. +declare function setPositive(value: GreaterThan extends true ? N : never): void; + +setPositive(1); // ✅ Allowed +setPositive(2); // ✅ Allowed + +// @ts-expect-error +setPositive(0); + +// @ts-expect-error +setPositive(-1); +``` +*/ +export type GreaterThan = + A extends number // For distributing `A` + ? B extends number // For distributing `B` + ? number extends A | B + ? boolean + : [ + IsEqual, IsEqual, + IsEqual, IsEqual, + ] extends infer R extends [boolean, boolean, boolean, boolean] + ? Or< + And, IsEqual>, + And, IsEqual> + > extends true + ? true + : Or< + And, IsEqual>, + And, IsEqual> + > extends true + ? false + : true extends R[number] + ? false + : [IsNegative, IsNegative] extends infer R extends [boolean, boolean] + ? [true, false] extends R + ? false + : [false, true] extends R + ? true + : [false, false] extends R + ? PositiveNumericStringGt<`${A}`, `${B}`> + : PositiveNumericStringGt<`${Absolute}`, `${Absolute}`> + : never + : never + : never // Should never happen + : never; // Should never happen + +export {}; diff --git a/node_modules/type-fest/source/has-optional-keys.d.ts b/node_modules/type-fest/source/has-optional-keys.d.ts new file mode 100644 index 00000000..fa5dfe7a --- /dev/null +++ b/node_modules/type-fest/source/has-optional-keys.d.ts @@ -0,0 +1,23 @@ +import type {OptionalKeysOf} from './optional-keys-of.d.ts'; + +/** +Returns a boolean for whether the given type has any optional fields. + +This is useful when you want to create an API whose behavior depends on the presence or absence of optional fields. + +@example +``` +import type {HasOptionalKeys, OptionalKeysOf} from 'type-fest'; + +type UpdateService = { + removeField: HasOptionalKeys extends true + ? (field: OptionalKeysOf) => Promise + : never; +}; +``` + +@category Utilities +*/ +export type HasOptionalKeys = OptionalKeysOf extends never ? false : true; + +export {}; diff --git a/node_modules/type-fest/source/has-readonly-keys.d.ts b/node_modules/type-fest/source/has-readonly-keys.d.ts new file mode 100644 index 00000000..dd9b58fd --- /dev/null +++ b/node_modules/type-fest/source/has-readonly-keys.d.ts @@ -0,0 +1,23 @@ +import type {ReadonlyKeysOf} from './readonly-keys-of.d.ts'; + +/** +Returns a boolean for whether the given type has any readonly fields. + +This is useful when you want to create an API whose behavior depends on the presence or absence of readonly fields. + +@example +``` +import type {HasReadonlyKeys, ReadonlyKeysOf} from 'type-fest'; + +type UpdateService = { + removeField: HasReadonlyKeys extends true + ? (field: ReadonlyKeysOf) => Promise + : never; +}; +``` + +@category Utilities +*/ +export type HasReadonlyKeys = ReadonlyKeysOf extends never ? false : true; + +export {}; diff --git a/node_modules/type-fest/source/has-required-keys.d.ts b/node_modules/type-fest/source/has-required-keys.d.ts new file mode 100644 index 00000000..ed7c5ce4 --- /dev/null +++ b/node_modules/type-fest/source/has-required-keys.d.ts @@ -0,0 +1,61 @@ +import type {RequiredKeysOf} from './required-keys-of.d.ts'; + +/** +Returns a boolean for whether the given type has any required fields. + +This is useful when you want to create an API whose behavior depends on the presence or absence of required fields. + +@example +``` +import type {HasRequiredKeys} from 'type-fest'; + +type GeneratorOptions