get-or-throw 2.0.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +33 -0
- package/.github/workflows/{ci.yml → checks.yml} +12 -9
- package/.github/workflows/docs.yml +74 -0
- package/.github/workflows/publish.yml +157 -0
- package/.oxfmtignore +2 -0
- package/.oxfmtrc.jsonc +12 -0
- package/.oxlintrc.json +18 -0
- package/README.md +17 -48
- package/dist/{index.d.ts → index-CLvtl5bd.d.ts} +5 -1
- package/dist/{index.d.cts → index-CRoiksIS.d.cts} +5 -1
- package/dist/index.cjs +22 -67
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +20 -39
- package/dist/index.js.map +1 -0
- package/docs/.vitepress/config.mts +47 -0
- package/docs/.vitepress/theme/CustomLayout.vue +31 -0
- package/docs/.vitepress/theme/custom.css +3 -0
- package/docs/.vitepress/theme/index.mts +8 -0
- package/docs/api.md +65 -0
- package/docs/getting-started.md +53 -0
- package/docs/index.md +46 -0
- package/docs/reasoning.md +144 -0
- package/docs/usage.md +85 -0
- package/package.json +45 -32
- package/src/get-or-throw.ts +1 -1
- package/tsconfig.json +1 -4
- package/tsdown.config.ts +10 -0
- package/.prettierignore +0 -1
- package/.prettierrc.json +0 -4
- package/dist/index.mjs +0 -21
- package/eslint.config.js +0 -28
- package/tsup.config.ts +0 -8
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { defineConfig } from "vitepress";
|
|
2
|
+
|
|
3
|
+
const hostname = "https://get-or-throw.codecompose.dev";
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
title: "Get-Or-Throw",
|
|
7
|
+
description:
|
|
8
|
+
"Safe indexed access for TypeScript with noUncheckedIndexedAccess",
|
|
9
|
+
base: "/",
|
|
10
|
+
cleanUrls: true,
|
|
11
|
+
|
|
12
|
+
sitemap: {
|
|
13
|
+
hostname,
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
transformHead({ pageData }) {
|
|
17
|
+
const canonicalUrl = `${hostname}/${pageData.relativePath}`
|
|
18
|
+
.replace(/index\.md$/, "")
|
|
19
|
+
.replace(/\.md$/, "");
|
|
20
|
+
|
|
21
|
+
return [["link", { rel: "canonical", href: canonicalUrl }]];
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
themeConfig: {
|
|
25
|
+
sidebar: [
|
|
26
|
+
{
|
|
27
|
+
text: "Guide",
|
|
28
|
+
items: [
|
|
29
|
+
{ text: "Introduction", link: "/" },
|
|
30
|
+
{ text: "Getting Started", link: "/getting-started" },
|
|
31
|
+
{ text: "Usage", link: "/usage" },
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
text: "Reference",
|
|
36
|
+
items: [
|
|
37
|
+
{ text: "API", link: "/api" },
|
|
38
|
+
{ text: "Why Get-Or-Throw?", link: "/reasoning" },
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
|
|
43
|
+
socialLinks: [
|
|
44
|
+
{ icon: "github", link: "https://github.com/0x80/get-or-throw" },
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import DefaultTheme from "vitepress/theme";
|
|
3
|
+
|
|
4
|
+
const { Layout } = DefaultTheme;
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<template>
|
|
8
|
+
<Layout>
|
|
9
|
+
<template #layout-bottom>
|
|
10
|
+
<footer class="custom-footer">
|
|
11
|
+
<p class="message">Released under the MIT License.</p>
|
|
12
|
+
<p class="copyright">Copyright © Thijs Koerselman</p>
|
|
13
|
+
</footer>
|
|
14
|
+
</template>
|
|
15
|
+
</Layout>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<style scoped>
|
|
19
|
+
.custom-footer {
|
|
20
|
+
border-top: 1px solid var(--vp-c-divider);
|
|
21
|
+
padding: 26px 32px;
|
|
22
|
+
text-align: center;
|
|
23
|
+
font-size: 14px;
|
|
24
|
+
color: var(--vp-c-text-2);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.custom-footer p {
|
|
28
|
+
margin: 0;
|
|
29
|
+
line-height: 24px;
|
|
30
|
+
}
|
|
31
|
+
</style>
|
package/docs/api.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# API Reference
|
|
2
|
+
|
|
3
|
+
## `getOrThrow`
|
|
4
|
+
|
|
5
|
+
Get a value from an object or array, throwing an error if the key or index does
|
|
6
|
+
not exist or if the resulting value is `undefined`.
|
|
7
|
+
|
|
8
|
+
### Signatures
|
|
9
|
+
|
|
10
|
+
#### Array Access
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
function getOrThrow<T>(array: T[], index: number, errorMessage?: string): T;
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
#### Object Access
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
function getOrThrow<T extends object, K extends keyof T>(
|
|
20
|
+
object: T,
|
|
21
|
+
key: K,
|
|
22
|
+
errorMessage?: string,
|
|
23
|
+
): NonNullable<T[K]>;
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Parameters
|
|
27
|
+
|
|
28
|
+
| Parameter | Type | Description |
|
|
29
|
+
| ------------------ | ------------- | ------------------------------------------------------ |
|
|
30
|
+
| `array` / `object` | `T[] \| T` | The array or object to access. |
|
|
31
|
+
| `index` / `key` | `number \| K` | The index (for arrays) or key (for objects) to access. |
|
|
32
|
+
| `errorMessage` | `string` | Optional custom error message. |
|
|
33
|
+
|
|
34
|
+
### Returns
|
|
35
|
+
|
|
36
|
+
The value at the given key or index, guaranteed to be defined. For objects, the
|
|
37
|
+
return type is `NonNullable<T[K]>`.
|
|
38
|
+
|
|
39
|
+
### Throws
|
|
40
|
+
|
|
41
|
+
- If the index is out of bounds: `"Index {n} is out of bounds."`
|
|
42
|
+
- If the key does not exist: `'Key "{key}" does not exist in the object.'`
|
|
43
|
+
- If the value is `undefined`: `"Value at index {n} is undefined."` or
|
|
44
|
+
`'Value at key "{key}" is undefined.'`
|
|
45
|
+
|
|
46
|
+
When a custom `errorMessage` is provided, it is used instead of the default
|
|
47
|
+
messages.
|
|
48
|
+
|
|
49
|
+
### Behavior
|
|
50
|
+
|
|
51
|
+
- **Negative indexing**: Negative indices count from the end of the array.
|
|
52
|
+
`got(arr, -1)` returns the last element.
|
|
53
|
+
- **Null values**: `null` is treated as a valid value and does not trigger an
|
|
54
|
+
error. Only `undefined` causes a throw.
|
|
55
|
+
|
|
56
|
+
## `got`
|
|
57
|
+
|
|
58
|
+
An alias for `getOrThrow`. Both functions are identical — use whichever you
|
|
59
|
+
prefer.
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import { got } from "get-or-throw";
|
|
63
|
+
// is equivalent to
|
|
64
|
+
import { getOrThrow } from "get-or-throw";
|
|
65
|
+
```
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Getting Started
|
|
2
|
+
|
|
3
|
+
## Installation
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pnpm add get-or-throw
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Or use the equivalent for your package manager:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install get-or-throw
|
|
13
|
+
yarn add get-or-throw
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Prerequisites
|
|
17
|
+
|
|
18
|
+
Get-Or-Throw is designed to work with TypeScript's
|
|
19
|
+
[noUncheckedIndexedAccess](https://www.typescriptlang.org/tsconfig/#noUncheckedIndexedAccess)
|
|
20
|
+
compiler option. While it works without it, the library is most useful when this
|
|
21
|
+
option is enabled:
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"compilerOptions": {
|
|
26
|
+
"noUncheckedIndexedAccess": true
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
With this setting, TypeScript treats every indexed access as potentially
|
|
32
|
+
`undefined`, which is correct but can make code verbose. Get-Or-Throw provides a
|
|
33
|
+
clean way to handle this.
|
|
34
|
+
|
|
35
|
+
## Basic Usage
|
|
36
|
+
|
|
37
|
+
The library exports two identical functions: `getOrThrow` and its shorter alias
|
|
38
|
+
`got`.
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import { got } from "get-or-throw";
|
|
42
|
+
// or
|
|
43
|
+
import { getOrThrow } from "get-or-throw";
|
|
44
|
+
|
|
45
|
+
const arr = [1, 2, 3];
|
|
46
|
+
const arrValue = got(arr, 1); // 2
|
|
47
|
+
|
|
48
|
+
const obj = { a: 1, b: 2, c: 3 };
|
|
49
|
+
const objValue = got(obj, "b"); // 2
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Both functions behave identically — use whichever you prefer. The `got` alias is
|
|
53
|
+
convenient for keeping code concise.
|
package/docs/index.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: home
|
|
3
|
+
|
|
4
|
+
hero:
|
|
5
|
+
name: Get-Or-Throw
|
|
6
|
+
tagline: Safe indexed access for TypeScript with noUncheckedIndexedAccess
|
|
7
|
+
actions:
|
|
8
|
+
- theme: brand
|
|
9
|
+
text: Get Started
|
|
10
|
+
link: /getting-started
|
|
11
|
+
- theme: alt
|
|
12
|
+
text: Why Get-Or-Throw?
|
|
13
|
+
link: /reasoning
|
|
14
|
+
|
|
15
|
+
features:
|
|
16
|
+
- title: Type-Safe Access
|
|
17
|
+
details: TypeScript assertions for type narrowing — the returned value is guaranteed to be defined.
|
|
18
|
+
- title: Arrays & Objects
|
|
19
|
+
details: Works with both objects and arrays, including support for negative indexing.
|
|
20
|
+
- title: Zero Dependencies
|
|
21
|
+
details: Tiny footprint with no external dependencies. Just the utility you need, nothing more.
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## What is Get-Or-Throw?
|
|
25
|
+
|
|
26
|
+
Get-Or-Throw provides a convenience function for safely accessing values in
|
|
27
|
+
dynamic objects and arrays. It gets the value at a specified key or index, and
|
|
28
|
+
throws an error if the resulting value is `undefined`.
|
|
29
|
+
|
|
30
|
+
This was created to make it easy to adhere to TypeScript's
|
|
31
|
+
[noUncheckedIndexedAccess](https://www.typescriptlang.org/tsconfig/#noUncheckedIndexedAccess)
|
|
32
|
+
setting, which is recommended for strict type checking.
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { got } from "get-or-throw";
|
|
36
|
+
|
|
37
|
+
const arr = [1, 2, 3];
|
|
38
|
+
const arrValue = got(arr, 1); // 2 — type is `number`, not `number | undefined`
|
|
39
|
+
|
|
40
|
+
const obj = { a: 1, b: 2, c: 3 };
|
|
41
|
+
const objValue = got(obj, "b"); // 2
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Instead of writing repetitive guard clauses or non-null assertions throughout
|
|
45
|
+
your code, `got()` gives you a single, expressive call that either returns a
|
|
46
|
+
defined value or throws a descriptive error.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Why Get-Or-Throw?
|
|
2
|
+
|
|
3
|
+
## The Core Question
|
|
4
|
+
|
|
5
|
+
When you access an array element or object property by a dynamic key, the value
|
|
6
|
+
might not be there. TypeScript's `noUncheckedIndexedAccess` makes this explicit
|
|
7
|
+
by adding `| undefined` to every indexed access. But how should you handle that
|
|
8
|
+
`undefined`?
|
|
9
|
+
|
|
10
|
+
There are two fundamental approaches:
|
|
11
|
+
|
|
12
|
+
1. **Defensive programming** — check for `undefined` and handle the absence
|
|
13
|
+
gracefully
|
|
14
|
+
2. **Fail-fast** — assert the value exists and throw immediately if it doesn't
|
|
15
|
+
|
|
16
|
+
Get-Or-Throw is for the second case: when absence is a bug, not a valid state.
|
|
17
|
+
|
|
18
|
+
## When to Use `got()`
|
|
19
|
+
|
|
20
|
+
Use `got()` when a missing value means something has gone wrong — a business
|
|
21
|
+
invariant has been violated, data is corrupt, or an earlier operation failed
|
|
22
|
+
silently:
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
// The config must have a "database" section
|
|
26
|
+
const dbConfig = got(config, "database");
|
|
27
|
+
|
|
28
|
+
// There must be at least one item after filtering
|
|
29
|
+
const first = got(filtered, 0, "Filter returned no results");
|
|
30
|
+
|
|
31
|
+
// Parallel arrays must have the same length
|
|
32
|
+
const label = got(labels, index);
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
In these cases, continuing with `undefined` would cause confusing downstream
|
|
36
|
+
errors. Failing immediately with a clear message is better.
|
|
37
|
+
|
|
38
|
+
## When NOT to Use `got()`
|
|
39
|
+
|
|
40
|
+
When absence is a legitimate possibility, use native patterns instead:
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
// User might not exist — that's fine
|
|
44
|
+
const user = users.find((u) => u.id === id);
|
|
45
|
+
if (!user) {
|
|
46
|
+
return notFound();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Optional configuration
|
|
50
|
+
const timeout = config.timeout ?? 5000;
|
|
51
|
+
|
|
52
|
+
// Array might be empty
|
|
53
|
+
const first = items[0];
|
|
54
|
+
if (first === undefined) {
|
|
55
|
+
showEmptyState();
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
If the code after the access handles the `undefined` case meaningfully, you
|
|
60
|
+
don't need `got()`.
|
|
61
|
+
|
|
62
|
+
## When to Use Tuple Types Instead
|
|
63
|
+
|
|
64
|
+
If the length of an array is statically known, TypeScript can track individual
|
|
65
|
+
element types without `| undefined`. In those cases, prefer a tuple type over
|
|
66
|
+
`got()`:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
// TypeScript knows this has exactly 3 elements
|
|
70
|
+
const rgb: [number, number, number] = [255, 128, 0];
|
|
71
|
+
const red = rgb[0]; // number, not number | undefined
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Problems with Defensive Patterns
|
|
75
|
+
|
|
76
|
+
### Silent Failures
|
|
77
|
+
|
|
78
|
+
The most dangerous pattern is silently swallowing `undefined`:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
// Bug: if arr[i] is undefined, localeCompare is called on undefined
|
|
82
|
+
arr.sort((a, b) => {
|
|
83
|
+
const valA = mapping[a]; // possibly undefined
|
|
84
|
+
const valB = mapping[b]; // possibly undefined
|
|
85
|
+
return valA.localeCompare(valB); // runtime crash, no clear message
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
With `got()`, the failure is immediate and descriptive:
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
arr.sort((a, b) => {
|
|
93
|
+
const valA = got(mapping, a);
|
|
94
|
+
const valB = got(mapping, b);
|
|
95
|
+
return valA.localeCompare(valB); // safe — both are guaranteed strings
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Verbose Guard Clauses
|
|
100
|
+
|
|
101
|
+
Without `got()`, you end up with repetitive null checks:
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
const value = obj[key];
|
|
105
|
+
if (value === undefined) {
|
|
106
|
+
throw new Error(`Expected key "${key}" to exist`);
|
|
107
|
+
}
|
|
108
|
+
// now use value
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
This pattern repeated across a codebase adds significant noise. `got()` reduces
|
|
112
|
+
it to a single expression:
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
const value = got(obj, key);
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Inconsistency
|
|
119
|
+
|
|
120
|
+
Different developers write different error messages, check in different ways
|
|
121
|
+
(`=== undefined`, `!= null`, `in` operator), or sometimes forget to check at
|
|
122
|
+
all. `got()` provides a single consistent pattern.
|
|
123
|
+
|
|
124
|
+
## Addressing Objections
|
|
125
|
+
|
|
126
|
+
### "It's a dependency for something trivial"
|
|
127
|
+
|
|
128
|
+
Get-Or-Throw has zero dependencies and is only a few lines of code. The value
|
|
129
|
+
isn't in the implementation complexity — it's in the consistency and
|
|
130
|
+
expressiveness it brings to a codebase. A shared convention is worth more than
|
|
131
|
+
any individual helper function.
|
|
132
|
+
|
|
133
|
+
### "Throwing crashes the app"
|
|
134
|
+
|
|
135
|
+
That's the point. If a business invariant is violated, you _want_ to know
|
|
136
|
+
immediately. The alternative — continuing with `undefined` — leads to corrupted
|
|
137
|
+
data, confusing errors far from the source, and bugs that are hard to reproduce.
|
|
138
|
+
|
|
139
|
+
### "I can just use the non-null assertion (`!`)"
|
|
140
|
+
|
|
141
|
+
The non-null assertion (`value!`) tells TypeScript to trust you, but provides no
|
|
142
|
+
runtime safety. If you're wrong, you get a confusing `undefined` error
|
|
143
|
+
somewhere downstream. `got()` gives you both the type narrowing _and_ a clear
|
|
144
|
+
runtime error at the point of access.
|
package/docs/usage.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Usage
|
|
2
|
+
|
|
3
|
+
The examples below use the `got` alias, but `getOrThrow` works identically.
|
|
4
|
+
|
|
5
|
+
## Array Access
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
const arr = [1, 2, 3];
|
|
9
|
+
const value = got(arr, 1); // 2
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
### Negative Indexing
|
|
13
|
+
|
|
14
|
+
Negative indices count from the end of the array, similar to `Array.at()`:
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
const arr = [1, 2, 3];
|
|
18
|
+
got(arr, -1); // 3
|
|
19
|
+
got(arr, -2); // 2
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Out of Bounds
|
|
23
|
+
|
|
24
|
+
Accessing an index outside the array bounds throws an error:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
const arr = [1, 2, 3];
|
|
28
|
+
got(arr, 3); // throws: "Index 3 is out of bounds."
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Object Access
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
const obj = { a: 1, b: 2, c: 3 };
|
|
35
|
+
const value = got(obj, "b"); // 2
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Missing Keys
|
|
39
|
+
|
|
40
|
+
Accessing a key that doesn't exist throws an error:
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
const obj = { a: 1, b: 2, c: 3 };
|
|
44
|
+
got(obj, "d"); // throws: 'Key "d" does not exist in the object.'
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Null vs Undefined
|
|
48
|
+
|
|
49
|
+
`null` is treated as a valid value and will not cause an error. Only `undefined`
|
|
50
|
+
triggers a throw:
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
// null is valid
|
|
54
|
+
const arr = [1, null, 3];
|
|
55
|
+
got(arr, 1); // null
|
|
56
|
+
|
|
57
|
+
const obj = { a: 1, b: null, c: 3 };
|
|
58
|
+
got(obj, "b"); // null
|
|
59
|
+
|
|
60
|
+
// undefined throws
|
|
61
|
+
const arr2 = [1, undefined, 3];
|
|
62
|
+
got(arr2, 1); // throws: "Value at index 1 is undefined."
|
|
63
|
+
|
|
64
|
+
const obj2 = { a: 1, b: undefined, c: 3 };
|
|
65
|
+
got(obj2, "b"); // throws: 'Value at key "b" is undefined.'
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Custom Error Messages
|
|
69
|
+
|
|
70
|
+
You can provide a custom error message as the third argument:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
const obj = { a: 1, b: 2, c: 3 };
|
|
74
|
+
const key = "d";
|
|
75
|
+
got(obj, key, `Failed to find ${key}`);
|
|
76
|
+
// throws: "Failed to find d"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
This is useful when you want to provide more context about why the value was
|
|
80
|
+
expected to exist:
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
const users = [{ name: "Alice" }, { name: "Bob" }];
|
|
84
|
+
const user = got(users, userIndex, `User at index ${userIndex} not found`);
|
|
85
|
+
```
|
package/package.json
CHANGED
|
@@ -1,7 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "get-or-throw",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "A convenience function for safely getting values from dynamic objects and arrays",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"indexed",
|
|
7
|
+
"noUncheckedIndexedAccess",
|
|
8
|
+
"typescript",
|
|
9
|
+
"unchecked"
|
|
10
|
+
],
|
|
11
|
+
"homepage": "https://get-or-throw.codecompose.dev",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/0x80/get-or-throw/issues"
|
|
14
|
+
},
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"author": "Thijs Koerselman",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/0x80/get-or-throw.git"
|
|
20
|
+
},
|
|
5
21
|
"type": "module",
|
|
6
22
|
"main": "dist/index.cjs",
|
|
7
23
|
"types": "dist/index.d.ts",
|
|
@@ -11,40 +27,37 @@
|
|
|
11
27
|
"require": "./dist/index.cjs"
|
|
12
28
|
}
|
|
13
29
|
},
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"url": "git+https://github.com/0x80/get-or-throw.git"
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
17
32
|
},
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "tsdown",
|
|
35
|
+
"dev": "tsdown --watch",
|
|
36
|
+
"clean": "del dist tsconfig.tsbuildinfo",
|
|
37
|
+
"prepare": "pnpm build",
|
|
38
|
+
"check-lint": "oxlint -c .oxlintrc.json --type-aware",
|
|
39
|
+
"format": "oxfmt .",
|
|
40
|
+
"check-format": "oxfmt --check .",
|
|
41
|
+
"check-types": "tsc --noEmit",
|
|
42
|
+
"test": "vitest run",
|
|
43
|
+
"docs:dev": "vitepress dev docs",
|
|
44
|
+
"docs:build": "vitepress build docs",
|
|
45
|
+
"docs:preview": "vitepress preview docs"
|
|
28
46
|
},
|
|
29
|
-
"homepage": "https://github.com/0x80/get-or-throw#readme",
|
|
30
47
|
"devDependencies": {
|
|
31
|
-
"@codecompose/typescript-config": "^
|
|
32
|
-
"@eslint/js": "^9.22.0",
|
|
48
|
+
"@codecompose/typescript-config": "^3.0.0",
|
|
33
49
|
"del-cli": "^5.1.0",
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"typescript": "
|
|
39
|
-
"
|
|
50
|
+
"oxfmt": "^0.33.0",
|
|
51
|
+
"oxlint": "^1.48.0",
|
|
52
|
+
"oxlint-tsgolint": "^0.15.0",
|
|
53
|
+
"tsdown": "^0.12.0",
|
|
54
|
+
"typescript": "6.0.0-beta",
|
|
55
|
+
"vite": "^6.0.0",
|
|
56
|
+
"vitepress": "^1.6.0",
|
|
40
57
|
"vitest": "^3.0.8"
|
|
41
58
|
},
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"test": "vitest",
|
|
48
|
-
"format": "prettier --write ."
|
|
49
|
-
}
|
|
50
|
-
}
|
|
59
|
+
"engines": {
|
|
60
|
+
"node": ">=22.12.0"
|
|
61
|
+
},
|
|
62
|
+
"packageManager": "pnpm@9.8.0+sha256.56a9e76b51796ca7f73b85e44cf83712862091f4d498c0ce4d5b7ecdc6ba18f7"
|
|
63
|
+
}
|
package/src/get-or-throw.ts
CHANGED
package/tsconfig.json
CHANGED
package/tsdown.config.ts
ADDED
package/.prettierignore
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
*.yml
|
package/.prettierrc.json
DELETED
package/dist/index.mjs
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// src/get-or-throw.ts
|
|
2
|
-
function getOrThrow(objOrArr, keyOrIndex) {
|
|
3
|
-
if (Array.isArray(objOrArr)) {
|
|
4
|
-
if (keyOrIndex in objOrArr) {
|
|
5
|
-
return objOrArr[keyOrIndex];
|
|
6
|
-
} else {
|
|
7
|
-
throw new Error(`Index ${String(keyOrIndex)} is out of bounds.`);
|
|
8
|
-
}
|
|
9
|
-
} else {
|
|
10
|
-
if (keyOrIndex in objOrArr) {
|
|
11
|
-
return objOrArr[keyOrIndex];
|
|
12
|
-
} else {
|
|
13
|
-
throw new Error(
|
|
14
|
-
`Key "${String(keyOrIndex)}" does not exist in the object.`
|
|
15
|
-
);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
export {
|
|
20
|
-
getOrThrow
|
|
21
|
-
};
|
package/eslint.config.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import eslint from "@eslint/js";
|
|
2
|
-
import tseslint from "typescript-eslint";
|
|
3
|
-
|
|
4
|
-
export default tseslint.config(
|
|
5
|
-
{
|
|
6
|
-
ignores: [
|
|
7
|
-
"dist/**",
|
|
8
|
-
"node_modules/**",
|
|
9
|
-
/**
|
|
10
|
-
* Ignore all config files int the root. We should instead solve this with
|
|
11
|
-
* projectService setting so that these files can also be linted, but
|
|
12
|
-
* let's get this to work first
|
|
13
|
-
*/
|
|
14
|
-
"*.{js,ts}",
|
|
15
|
-
],
|
|
16
|
-
},
|
|
17
|
-
eslint.configs.recommended,
|
|
18
|
-
tseslint.configs.strictTypeChecked,
|
|
19
|
-
tseslint.configs.stylisticTypeChecked,
|
|
20
|
-
{
|
|
21
|
-
languageOptions: {
|
|
22
|
-
parserOptions: {
|
|
23
|
-
projectService: true,
|
|
24
|
-
tsconfigRootDir: import.meta.dirname,
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
);
|