@iflow-mcp/kdcokenny-lsbible 0.3.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/README.md +529 -0
- package/dist/index.cjs +2269 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +81 -0
- package/dist/index.d.ts +81 -0
- package/dist/index.js +2254 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/index.cjs +2716 -0
- package/dist/mcp/index.cjs.map +1 -0
- package/dist/mcp/index.d.cts +230 -0
- package/dist/mcp/index.d.ts +230 -0
- package/dist/mcp/index.js +2707 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/stdio.cjs +2709 -0
- package/dist/mcp/stdio.cjs.map +1 -0
- package/dist/mcp/stdio.d.cts +1 -0
- package/dist/mcp/stdio.d.ts +1 -0
- package/dist/mcp/stdio.js +2707 -0
- package/dist/mcp/stdio.js.map +1 -0
- package/dist/noop-B62cxzKZ.d.cts +1157 -0
- package/dist/noop-B62cxzKZ.d.ts +1157 -0
- package/package.json +1 -0
package/README.md
ADDED
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
# LSBible SDK for TypeScript
|
|
2
|
+
|
|
3
|
+
Structured, type-safe Bible API client for the Legacy Standard Bible (LSB).
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **100% Type-Safe** - Full TypeScript support with Zod validation
|
|
8
|
+
- **Structured Parameters** - No string parsing! Use `client.getVerse(BookName.JOHN, 3, 16)`
|
|
9
|
+
- **Complete Validation** - All 66 books with chapter/verse validation
|
|
10
|
+
- **Rich Formatting** - Preserves red-letter text, italics, bold, small-caps
|
|
11
|
+
- **Built-in Caching** - Configurable TTL-based response cache
|
|
12
|
+
- **Modern Runtime Support** - Works with Node.js 18+, Bun, and Deno
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# Using npm
|
|
18
|
+
npm install lsbible
|
|
19
|
+
|
|
20
|
+
# Using pnpm
|
|
21
|
+
pnpm add lsbible
|
|
22
|
+
|
|
23
|
+
# Using bun
|
|
24
|
+
bun add lsbible
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## MCP Server
|
|
28
|
+
|
|
29
|
+
This SDK also includes a **Model Context Protocol (MCP) server** for integration with AI coding assistants like Cursor, Claude Code, VS Code, and more.
|
|
30
|
+
|
|
31
|
+
> **🤖 For MCP Server Installation:** To use LSBible with AI coding tools, see the **[MCP Installation Guide →](./mcp/README.md)** with step-by-step instructions for 20+ supported clients.
|
|
32
|
+
|
|
33
|
+
**Quick Install Examples:**
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
# Claude Code (remote)
|
|
37
|
+
claude mcp add --transport http lsbible https://lsbible.kdco.dev/mcp
|
|
38
|
+
|
|
39
|
+
# Claude Code (local)
|
|
40
|
+
claude mcp add lsbible -- npx -y lsbible-mcp
|
|
41
|
+
|
|
42
|
+
# Cursor/VS Code/etc. (see full guide)
|
|
43
|
+
# Add to your MCP config file - see mcp/README.md for details
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Quick Start
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import { LSBibleClient, BookName } from "lsbible";
|
|
50
|
+
|
|
51
|
+
const client = new LSBibleClient();
|
|
52
|
+
|
|
53
|
+
// Get a single verse (type-safe with enum)
|
|
54
|
+
const verse = await client.getVerse(BookName.JOHN, 3, 16);
|
|
55
|
+
console.log(verse.verses[0].plainText);
|
|
56
|
+
// Output: "For God so loved the world, that He gave His only Son..."
|
|
57
|
+
|
|
58
|
+
// Get a passage range
|
|
59
|
+
const passage = await client.getPassage(
|
|
60
|
+
BookName.JOHN, 3, 16,
|
|
61
|
+
BookName.JOHN, 3, 18
|
|
62
|
+
);
|
|
63
|
+
console.log(`Got ${passage.verseCount} verses`);
|
|
64
|
+
|
|
65
|
+
// Get an entire chapter
|
|
66
|
+
const chapter = await client.getChapter(BookName.PSALMS, 23);
|
|
67
|
+
console.log(`Psalm 23 has ${chapter.verseCount} verses`);
|
|
68
|
+
|
|
69
|
+
// Search for text
|
|
70
|
+
const results = await client.search("love");
|
|
71
|
+
console.log(`Found ${results.matchCount} matches in ${results.passageCount} passages`);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Design Philosophy
|
|
75
|
+
|
|
76
|
+
### Structured Parameters Over String Parsing
|
|
77
|
+
|
|
78
|
+
This SDK prioritizes explicit, structured parameters over string-based references:
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
// ✅ GOOD - Structured, type-safe, validated
|
|
82
|
+
client.getVerse(BookName.JOHN, 3, 16);
|
|
83
|
+
|
|
84
|
+
// ❌ AVOID - String parsing (error-prone, less type-safe)
|
|
85
|
+
client.getVerse("John 3:16"); // NOT SUPPORTED
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Why Structured Parameters?**
|
|
89
|
+
|
|
90
|
+
1. **Type Safety** - IDE autocomplete for all 66 books
|
|
91
|
+
2. **Early Validation** - Catch errors before API calls
|
|
92
|
+
3. **No Parsing Ambiguity** - Clear, explicit parameters
|
|
93
|
+
4. **Better Testing** - Easy to generate test cases programmatically
|
|
94
|
+
5. **Language Agnostic** - Works consistently across all SDKs
|
|
95
|
+
|
|
96
|
+
## API Reference
|
|
97
|
+
|
|
98
|
+
### LSBibleClient
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
import { LSBibleClient, MemoryCacheProvider } from "lsbible";
|
|
102
|
+
|
|
103
|
+
const client = new LSBibleClient({
|
|
104
|
+
cache: {
|
|
105
|
+
provider: new MemoryCacheProvider(), // Optional cache provider
|
|
106
|
+
ttl: {
|
|
107
|
+
verse: 2592000, // 30 days (default)
|
|
108
|
+
passage: 2592000, // 30 days (default)
|
|
109
|
+
chapter: 2592000, // 30 days (default)
|
|
110
|
+
search: 604800, // 7 days (default)
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
timeout: 30, // Request timeout in seconds (default: 30)
|
|
114
|
+
buildId: undefined, // Optional build ID (auto-detected if not provided)
|
|
115
|
+
headers: {}, // Optional custom headers
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Methods
|
|
120
|
+
|
|
121
|
+
#### `getVerse(book, chapter, verse)`
|
|
122
|
+
|
|
123
|
+
Get a specific verse with validated parameters.
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
// Using enum (recommended)
|
|
127
|
+
const verse = await client.getVerse(BookName.JOHN, 3, 16);
|
|
128
|
+
|
|
129
|
+
// Using string (validated at runtime)
|
|
130
|
+
const verse = await client.getVerse("John", 3, 16);
|
|
131
|
+
|
|
132
|
+
// Access structured data
|
|
133
|
+
for (const v of verse.verses) {
|
|
134
|
+
console.log(`${v.reference.toString()}: ${v.plainText}`);
|
|
135
|
+
|
|
136
|
+
// Access formatting
|
|
137
|
+
for (const segment of v.segments) {
|
|
138
|
+
if (segment.isRedLetter) {
|
|
139
|
+
console.log(`Jesus said: "${segment.text}"`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
#### `getPassage(fromBook, fromChapter, fromVerse, toBook, toChapter, toVerse)`
|
|
146
|
+
|
|
147
|
+
Get a passage spanning multiple verses.
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
// Get John 3:16-18
|
|
151
|
+
const passage = await client.getPassage(
|
|
152
|
+
BookName.JOHN, 3, 16,
|
|
153
|
+
BookName.JOHN, 3, 18
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
console.log(`Title: ${passage.title}`);
|
|
157
|
+
console.log(`Verses: ${passage.verseCount}`);
|
|
158
|
+
console.log(`Single verse? ${passage.isSingleVerse}`);
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
#### `getChapter(book, chapter)`
|
|
162
|
+
|
|
163
|
+
Get an entire chapter.
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
// Get all of Psalm 23
|
|
167
|
+
const chapter = await client.getChapter(BookName.PSALMS, 23);
|
|
168
|
+
|
|
169
|
+
console.log(`Psalm 23 has ${chapter.verseCount} verses`);
|
|
170
|
+
|
|
171
|
+
for (const verse of chapter.verses) {
|
|
172
|
+
console.log(` ${verse.verseNumber}. ${verse.plainText}`);
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
#### `search(query)`
|
|
177
|
+
|
|
178
|
+
Search for passages containing text.
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
const results = await client.search("love");
|
|
182
|
+
|
|
183
|
+
console.log(`Found ${results.matchCount} matches`);
|
|
184
|
+
console.log(`Passages: ${results.passageCount}`);
|
|
185
|
+
console.log(`Total verses: ${results.totalVerses}`);
|
|
186
|
+
|
|
187
|
+
// Search results include metadata (for text searches)
|
|
188
|
+
if (results.hasSearchMetadata) {
|
|
189
|
+
console.log(`Total results: ${results.totalCount}`);
|
|
190
|
+
console.log(`Filtered: ${results.filteredCount}`);
|
|
191
|
+
console.log(`By book:`, results.countsByBook);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Iterate through results
|
|
195
|
+
for (const passage of results.passages) {
|
|
196
|
+
console.log(`\n${passage.title}`);
|
|
197
|
+
for (const verse of passage.verses) {
|
|
198
|
+
console.log(` ${verse.plainText}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
#### `clearCache()`
|
|
204
|
+
|
|
205
|
+
Clear the response cache (only available with `MemoryCacheProvider`).
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
client.clearCache();
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Caching
|
|
212
|
+
|
|
213
|
+
The SDK supports pluggable caching through the `CacheProvider` interface, allowing you to choose the right caching strategy for your deployment environment.
|
|
214
|
+
|
|
215
|
+
### Built-in Cache Providers
|
|
216
|
+
|
|
217
|
+
**MemoryCacheProvider** - In-memory caching with TTL support
|
|
218
|
+
- ✅ Local development, testing, single-process apps
|
|
219
|
+
- ❌ Multi-process apps, Cloudflare Workers, high-traffic production
|
|
220
|
+
|
|
221
|
+
**NoopCacheProvider** - Disables caching entirely
|
|
222
|
+
- Useful for debugging or when caching isn't beneficial
|
|
223
|
+
|
|
224
|
+
**CloudflareCacheProvider** - Edge caching for Cloudflare Workers
|
|
225
|
+
- Available in the [MCP Server implementation](../../apps/mcp-server/src/cache/cloudflare.ts)
|
|
226
|
+
|
|
227
|
+
### Cache Configuration
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
import { LSBibleClient, MemoryCacheProvider, CacheTTL } from "lsbible";
|
|
231
|
+
|
|
232
|
+
const client = new LSBibleClient({
|
|
233
|
+
cache: {
|
|
234
|
+
provider: new MemoryCacheProvider(),
|
|
235
|
+
ttl: {
|
|
236
|
+
verse: CacheTTL.BIBLE_CONTENT, // 30 days
|
|
237
|
+
passage: CacheTTL.BIBLE_CONTENT, // 30 days
|
|
238
|
+
chapter: CacheTTL.BIBLE_CONTENT, // 30 days
|
|
239
|
+
search: CacheTTL.SEARCH_RESULTS, // 7 days
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**Recommended TTL constants:**
|
|
246
|
+
- `CacheTTL.BIBLE_CONTENT` (30 days) - Bible text is immutable
|
|
247
|
+
- `CacheTTL.SEARCH_RESULTS` (7 days) - May change with API updates
|
|
248
|
+
- `CacheTTL.STATIC` (1 year) - Never changes
|
|
249
|
+
|
|
250
|
+
### Custom Cache Providers
|
|
251
|
+
|
|
252
|
+
Implement the `CacheProvider` interface for custom backends like Redis, Memcached, or DynamoDB:
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
interface CacheProvider {
|
|
256
|
+
get<T>(key: string): Promise<T | undefined>;
|
|
257
|
+
set<T>(key: string, value: T, ttl: number): Promise<void>;
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**Complete examples:**
|
|
262
|
+
- [Memory Cache](./examples/cache-memory.ts) - Demonstrates cache hits/misses and manual clearing
|
|
263
|
+
- [Redis Cache](./examples/cache-redis.ts) - Full Redis implementation with ioredis
|
|
264
|
+
- [Custom Cache](./examples/cache-custom.ts) - Template for building your own cache provider
|
|
265
|
+
|
|
266
|
+
### Cache Keys
|
|
267
|
+
|
|
268
|
+
The SDK uses these cache key patterns:
|
|
269
|
+
- `verse:{book} {chapter}:{verse}` - Single verses
|
|
270
|
+
- `passage:{normalized query}` - Passage ranges
|
|
271
|
+
- `chapter:{book} {chapter}` - Full chapters
|
|
272
|
+
- `search:{query}` - Text searches
|
|
273
|
+
|
|
274
|
+
## Type System
|
|
275
|
+
|
|
276
|
+
### BookName Enum
|
|
277
|
+
|
|
278
|
+
All 66 Bible books available as enum values:
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
import { BookName } from "lsbible";
|
|
282
|
+
|
|
283
|
+
// Old Testament
|
|
284
|
+
BookName.GENESIS
|
|
285
|
+
BookName.EXODUS
|
|
286
|
+
// ... through ...
|
|
287
|
+
BookName.MALACHI
|
|
288
|
+
|
|
289
|
+
// New Testament
|
|
290
|
+
BookName.MATTHEW
|
|
291
|
+
BookName.MARK
|
|
292
|
+
// ... through ...
|
|
293
|
+
BookName.REVELATION
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### VerseReference
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
interface VerseReference {
|
|
300
|
+
bookNumber: number; // 1-66
|
|
301
|
+
chapter: number; // Validated against book
|
|
302
|
+
verse: number; // Validated against chapter
|
|
303
|
+
readonly bookName: BookName; // Computed property
|
|
304
|
+
toString(): string; // e.g., "John 3:16"
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### TextSegment
|
|
309
|
+
|
|
310
|
+
```typescript
|
|
311
|
+
interface TextSegment {
|
|
312
|
+
text: string;
|
|
313
|
+
isRedLetter: boolean; // Words of Jesus
|
|
314
|
+
isItalic: boolean; // Italicized clarifications
|
|
315
|
+
isBold: boolean; // Bold text
|
|
316
|
+
isSmallCaps: boolean; // LORD (Yahweh)
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### VerseContent
|
|
321
|
+
|
|
322
|
+
```typescript
|
|
323
|
+
interface VerseContent {
|
|
324
|
+
reference: VerseReference;
|
|
325
|
+
verseNumber: number;
|
|
326
|
+
segments: TextSegment[];
|
|
327
|
+
hasSubheading: boolean;
|
|
328
|
+
subheadingText: string | null;
|
|
329
|
+
isPoetry: boolean;
|
|
330
|
+
isProse: boolean;
|
|
331
|
+
chapterStart: boolean;
|
|
332
|
+
readonly plainText: string; // Computed property
|
|
333
|
+
readonly formattedText: string; // Computed property
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Passage
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
interface Passage {
|
|
341
|
+
fromRef: VerseReference;
|
|
342
|
+
toRef: VerseReference;
|
|
343
|
+
title: string;
|
|
344
|
+
verses: VerseContent[];
|
|
345
|
+
readonly isSingleVerse: boolean; // Computed property
|
|
346
|
+
readonly verseCount: number; // Computed property
|
|
347
|
+
}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### SearchResponse
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
interface SearchResponse {
|
|
354
|
+
query: string;
|
|
355
|
+
matchCount: number;
|
|
356
|
+
passages: Passage[];
|
|
357
|
+
durationMs: number;
|
|
358
|
+
timestamp: number;
|
|
359
|
+
|
|
360
|
+
// Optional (for text searches only)
|
|
361
|
+
totalCount?: number;
|
|
362
|
+
filteredCount?: number;
|
|
363
|
+
countsByBook?: Record<string, number>;
|
|
364
|
+
countsBySection?: Record<string, number>;
|
|
365
|
+
|
|
366
|
+
// Computed properties
|
|
367
|
+
readonly passageCount: number;
|
|
368
|
+
readonly totalVerses: number;
|
|
369
|
+
readonly hasSearchMetadata: boolean;
|
|
370
|
+
}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
## Error Handling
|
|
374
|
+
|
|
375
|
+
```typescript
|
|
376
|
+
import { LSBibleClient, BookName, InvalidReferenceError, APIError } from "lsbible";
|
|
377
|
+
|
|
378
|
+
const client = new LSBibleClient();
|
|
379
|
+
|
|
380
|
+
try {
|
|
381
|
+
// Invalid chapter (John only has 21 chapters)
|
|
382
|
+
await client.getVerse(BookName.JOHN, 99, 1);
|
|
383
|
+
} catch (error) {
|
|
384
|
+
if (error instanceof InvalidReferenceError) {
|
|
385
|
+
console.error(`Invalid reference: ${error.message}`);
|
|
386
|
+
// Output: "John only has 21 chapters, but chapter 99 was requested"
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
try {
|
|
391
|
+
// Invalid verse (John 3 only has 36 verses)
|
|
392
|
+
await client.getVerse(BookName.JOHN, 3, 999);
|
|
393
|
+
} catch (error) {
|
|
394
|
+
if (error instanceof InvalidReferenceError) {
|
|
395
|
+
console.error(`Invalid reference: ${error.message}`);
|
|
396
|
+
// Output: "John 3 only has 36 verses, but verse 999 was requested"
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
try {
|
|
401
|
+
// Invalid book name
|
|
402
|
+
await client.getVerse("NotABook", 1, 1);
|
|
403
|
+
} catch (error) {
|
|
404
|
+
if (error instanceof InvalidReferenceError) {
|
|
405
|
+
console.error(`Invalid reference: ${error.message}`);
|
|
406
|
+
// Output: "Unknown book: NotABook"
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
try {
|
|
411
|
+
// API failure
|
|
412
|
+
await client.search("something");
|
|
413
|
+
} catch (error) {
|
|
414
|
+
if (error instanceof APIError) {
|
|
415
|
+
console.error(`API error: ${error.message}`);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
## Bible Structure Data
|
|
421
|
+
|
|
422
|
+
The SDK includes complete validation data for all 66 books:
|
|
423
|
+
|
|
424
|
+
- **Old Testament:** 39 books (Genesis through Malachi)
|
|
425
|
+
- **New Testament:** 27 books (Matthew through Revelation)
|
|
426
|
+
- **Total:** 1,189 chapters, 31,102 verses
|
|
427
|
+
|
|
428
|
+
```typescript
|
|
429
|
+
import { BIBLE_STRUCTURE, BOOK_NAMES, BOOK_NUMBERS } from "lsbible";
|
|
430
|
+
|
|
431
|
+
// Get book info
|
|
432
|
+
const johnInfo = BIBLE_STRUCTURE[43];
|
|
433
|
+
console.log(johnInfo.name); // "John"
|
|
434
|
+
console.log(johnInfo.chapters); // 21
|
|
435
|
+
console.log(johnInfo.verses[2]); // Chapter 3 has 36 verses
|
|
436
|
+
|
|
437
|
+
// Lookup book number
|
|
438
|
+
const bookNum = BOOK_NUMBERS["john"]; // 43
|
|
439
|
+
|
|
440
|
+
// Lookup book name
|
|
441
|
+
const bookName = BOOK_NAMES[43]; // "John"
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
## Runtime Support
|
|
445
|
+
|
|
446
|
+
The SDK is designed to work across modern JavaScript runtimes:
|
|
447
|
+
|
|
448
|
+
- **Node.js** 18.0.0 or higher (native fetch support)
|
|
449
|
+
- **Bun** (optimized build performance)
|
|
450
|
+
- **Deno** (works out of the box)
|
|
451
|
+
|
|
452
|
+
## Examples
|
|
453
|
+
|
|
454
|
+
### Example 1: Display a Verse with Formatting
|
|
455
|
+
|
|
456
|
+
```typescript
|
|
457
|
+
import { LSBibleClient, BookName } from "lsbible";
|
|
458
|
+
|
|
459
|
+
const client = new LSBibleClient();
|
|
460
|
+
const verse = await client.getVerse(BookName.JOHN, 3, 16);
|
|
461
|
+
|
|
462
|
+
for (const v of verse.verses) {
|
|
463
|
+
console.log(`\n${v.reference.toString()}\n`);
|
|
464
|
+
|
|
465
|
+
for (const segment of v.segments) {
|
|
466
|
+
let text = segment.text;
|
|
467
|
+
if (segment.isRedLetter) text = `\x1b[31m${text}\x1b[0m`; // Red
|
|
468
|
+
if (segment.isItalic) text = `\x1b[3m${text}\x1b[0m`; // Italic
|
|
469
|
+
if (segment.isSmallCaps) text = text.toUpperCase(); // Small caps -> uppercase
|
|
470
|
+
process.stdout.write(text + " ");
|
|
471
|
+
}
|
|
472
|
+
console.log("\n");
|
|
473
|
+
}
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
### Example 2: Find All Occurrences of a Word
|
|
477
|
+
|
|
478
|
+
```typescript
|
|
479
|
+
import { LSBibleClient } from "lsbible";
|
|
480
|
+
|
|
481
|
+
const client = new LSBibleClient();
|
|
482
|
+
const results = await client.search("faith");
|
|
483
|
+
|
|
484
|
+
console.log(`Found "${results.query}" ${results.matchCount} times\n`);
|
|
485
|
+
|
|
486
|
+
for (const passage of results.passages) {
|
|
487
|
+
for (const verse of passage.verses) {
|
|
488
|
+
console.log(`${verse.reference.toString()}: ${verse.plainText}`);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
### Example 3: Read an Entire Book
|
|
494
|
+
|
|
495
|
+
```typescript
|
|
496
|
+
import { LSBibleClient, BookName, BIBLE_STRUCTURE } from "lsbible";
|
|
497
|
+
|
|
498
|
+
const client = new LSBibleClient();
|
|
499
|
+
const bookNum = 57; // Philemon
|
|
500
|
+
const bookInfo = BIBLE_STRUCTURE[bookNum];
|
|
501
|
+
|
|
502
|
+
console.log(`Reading ${bookInfo.name}\n`);
|
|
503
|
+
|
|
504
|
+
for (let chapter = 1; chapter <= bookInfo.chapters; chapter++) {
|
|
505
|
+
const passage = await client.getChapter(BookName.PHILEMON, chapter);
|
|
506
|
+
|
|
507
|
+
console.log(`\nChapter ${chapter}\n`);
|
|
508
|
+
|
|
509
|
+
for (const verse of passage.verses) {
|
|
510
|
+
console.log(`${verse.verseNumber}. ${verse.plainText}`);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
## Contributing
|
|
516
|
+
|
|
517
|
+
This SDK is part of the LSBible monorepo. Contributions are welcome!
|
|
518
|
+
|
|
519
|
+
See the main repository for contribution guidelines: https://github.com/kdcokenny/lsbible
|
|
520
|
+
|
|
521
|
+
## License
|
|
522
|
+
|
|
523
|
+
MIT License - See LICENSE file for details.
|
|
524
|
+
|
|
525
|
+
## Related
|
|
526
|
+
|
|
527
|
+
- [Python SDK](../python-sdk) - Official Python implementation
|
|
528
|
+
- [API Documentation](../../.specs/SPEC.md) - Complete SDK specification
|
|
529
|
+
- [LSBible Website](https://read.lsbible.org) - Read the Legacy Standard Bible online
|