@nbtca/docs 0.1.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 ADDED
@@ -0,0 +1,65 @@
1
+ # @nbtca/docs
2
+
3
+ Data-only library for the [NBTCA documents repository](https://github.com/nbtca/documents).
4
+ Fetches directory listings and raw markdown files from GitHub with built-in TTL caching,
5
+ stale-while-revalidate fallback, and rate-limit handling.
6
+
7
+ Rendering is the consumer's job (e.g. `@nbtca/prompt`).
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install @nbtca/docs
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ```ts
18
+ import { createDocsClient } from '@nbtca/docs';
19
+
20
+ const docs = createDocsClient(); // defaults to nbtca/documents@main
21
+
22
+ const items = await docs.listDir('tutorial'); // DocItem[]
23
+ const md = await docs.getFile('repair/guide.md'); // string (raw markdown)
24
+ ```
25
+
26
+ Custom target:
27
+
28
+ ```ts
29
+ const docs = createDocsClient({
30
+ owner: 'my-org',
31
+ repo: 'my-docs',
32
+ branch: 'main',
33
+ token: process.env.GITHUB_TOKEN,
34
+ });
35
+ ```
36
+
37
+ ## API
38
+
39
+ ### `createDocsClient(options?)`
40
+
41
+ | Option | Default | Description |
42
+ |---|---|---|
43
+ | `owner` | `'nbtca'` | GitHub org/user |
44
+ | `repo` | `'documents'` | Repository name |
45
+ | `branch` | `'main'` | Branch or ref |
46
+ | `token` | `GITHUB_TOKEN` env | Auth token (raises rate limit) |
47
+ | `cacheTtlMs.dir` | `300000` (5 min) | Directory listing cache TTL |
48
+ | `cacheTtlMs.file` | `600000` (10 min) | File content cache TTL |
49
+
50
+ ### `docs.listDir(path?)`
51
+
52
+ Returns `DocItem[]` for the given path (root if omitted).
53
+ Filters out hidden files, non-markdown files, and repository metadata.
54
+
55
+ ### `docs.getFile(path)`
56
+
57
+ Returns raw markdown as a string. Falls back to stale cache on network error.
58
+
59
+ ### `DocsFetchError`
60
+
61
+ Thrown when a fetch fails with no stale cache available. Has `.path` and `.status` fields.
62
+
63
+ ## License
64
+
65
+ MIT
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cache.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/cache.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,42 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { TtlCache } from '../cache.js';
3
+ describe('TtlCache', () => {
4
+ beforeEach(() => vi.useFakeTimers());
5
+ afterEach(() => vi.useRealTimers());
6
+ it('returns value before expiry', () => {
7
+ const c = new TtlCache(1000);
8
+ c.set('k', 'v');
9
+ expect(c.get('k')).toBe('v');
10
+ });
11
+ it('returns undefined after expiry', () => {
12
+ const c = new TtlCache(1000);
13
+ c.set('k', 'v');
14
+ vi.advanceTimersByTime(1001);
15
+ expect(c.get('k')).toBeUndefined();
16
+ });
17
+ it('getStale returns expired value', () => {
18
+ const c = new TtlCache(1000);
19
+ c.set('k', 'v');
20
+ vi.advanceTimersByTime(1001);
21
+ expect(c.getStale('k')).toBe('v');
22
+ });
23
+ it('evicts oldest when over maxSize', () => {
24
+ const c = new TtlCache(10000, 2);
25
+ c.set('a', 1);
26
+ vi.advanceTimersByTime(1);
27
+ c.set('b', 2);
28
+ vi.advanceTimersByTime(1);
29
+ c.set('c', 3); // should evict 'a'
30
+ expect(c.get('a')).toBeUndefined();
31
+ expect(c.get('b')).toBe(2);
32
+ expect(c.get('c')).toBe(3);
33
+ });
34
+ it('clear removes all entries', () => {
35
+ const c = new TtlCache(10000);
36
+ c.set('k', 'v');
37
+ c.clear();
38
+ expect(c.get('k')).toBeUndefined();
39
+ expect(c.getStale('k')).toBeUndefined();
40
+ });
41
+ });
42
+ //# sourceMappingURL=cache.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.test.js","sourceRoot":"","sources":["../../src/__tests__/cache.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=client.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/client.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,62 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { createDocsClient } from '../client.js';
3
+ import { DocsFetchError } from '../types.js';
4
+ const mockDir = [
5
+ { name: 'repair', path: 'repair', type: 'dir' },
6
+ { name: 'guide.md', path: 'repair/guide.md', type: 'file' },
7
+ { name: 'node_modules', path: 'node_modules', type: 'dir' },
8
+ { name: '.github', path: '.github', type: 'dir' },
9
+ { name: 'image.png', path: 'repair/image.png', type: 'file' },
10
+ ];
11
+ function mockFetch(response) {
12
+ vi.stubGlobal('fetch', vi.fn().mockResolvedValue(response));
13
+ }
14
+ beforeEach(() => vi.restoreAllMocks());
15
+ describe('createDocsClient', () => {
16
+ it('filters skipped names and non-md files', async () => {
17
+ mockFetch({ ok: true, json: async () => mockDir });
18
+ const client = createDocsClient();
19
+ const items = await client.listDir('repair');
20
+ expect(items.map(i => i.name)).not.toContain('node_modules');
21
+ expect(items.map(i => i.name)).not.toContain('.github');
22
+ expect(items.map(i => i.name)).not.toContain('image.png');
23
+ expect(items.find(i => i.name === 'guide.md')).toBeDefined();
24
+ });
25
+ it('sorts dirs before files', async () => {
26
+ mockFetch({ ok: true, json: async () => mockDir });
27
+ const client = createDocsClient();
28
+ const items = await client.listDir();
29
+ const types = items.map(i => i.type);
30
+ const firstFile = types.indexOf('file');
31
+ const lastDir = types.lastIndexOf('dir');
32
+ expect(lastDir).toBeLessThan(firstFile === -1 ? Infinity : firstFile);
33
+ });
34
+ it('caches directory results', async () => {
35
+ const spy = vi.fn().mockResolvedValue({ ok: true, json: async () => [] });
36
+ vi.stubGlobal('fetch', spy);
37
+ const client = createDocsClient();
38
+ await client.listDir('tutorial');
39
+ await client.listDir('tutorial');
40
+ expect(spy).toHaveBeenCalledTimes(1);
41
+ });
42
+ it('throws DocsFetchError on HTTP error', async () => {
43
+ mockFetch({ ok: false, status: 404 });
44
+ const client = createDocsClient();
45
+ await expect(client.listDir('nonexistent')).rejects.toBeInstanceOf(DocsFetchError);
46
+ });
47
+ it('getFile fetches raw content', async () => {
48
+ mockFetch({ ok: true, text: async () => '# Hello' });
49
+ const client = createDocsClient();
50
+ const content = await client.getFile('repair/guide.md');
51
+ expect(content).toBe('# Hello');
52
+ });
53
+ it('getFile caches content', async () => {
54
+ const spy = vi.fn().mockResolvedValue({ ok: true, text: async () => '# Doc' });
55
+ vi.stubGlobal('fetch', spy);
56
+ const client = createDocsClient();
57
+ await client.getFile('repair/guide.md');
58
+ await client.getFile('repair/guide.md');
59
+ expect(spy).toHaveBeenCalledTimes(1);
60
+ });
61
+ });
62
+ //# sourceMappingURL=client.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.test.js","sourceRoot":"","sources":["../../src/__tests__/client.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export declare class TtlCache<T> {
2
+ private readonly ttlMs;
3
+ private readonly maxSize;
4
+ private readonly map;
5
+ constructor(ttlMs: number, maxSize?: number);
6
+ get(key: string): T | undefined;
7
+ getStale(key: string): T | undefined;
8
+ set(key: string, value: T): void;
9
+ clear(): void;
10
+ private evictOldest;
11
+ }
12
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAKA,qBAAa,QAAQ,CAAC,CAAC;IAInB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA+B;gBAGhC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,MAAW;IAGvC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAO/B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAIpC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAKhC,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,WAAW;CAMpB"}
package/dist/cache.js ADDED
@@ -0,0 +1,34 @@
1
+ export class TtlCache {
2
+ constructor(ttlMs, maxSize = 50) {
3
+ this.ttlMs = ttlMs;
4
+ this.maxSize = maxSize;
5
+ this.map = new Map();
6
+ }
7
+ get(key) {
8
+ const entry = this.map.get(key);
9
+ if (!entry)
10
+ return undefined;
11
+ if (Date.now() < entry.expiresAt)
12
+ return entry.value;
13
+ return undefined;
14
+ }
15
+ getStale(key) {
16
+ return this.map.get(key)?.value;
17
+ }
18
+ set(key, value) {
19
+ this.map.set(key, { value, expiresAt: Date.now() + this.ttlMs });
20
+ if (this.map.size > this.maxSize)
21
+ this.evictOldest();
22
+ }
23
+ clear() {
24
+ this.map.clear();
25
+ }
26
+ evictOldest() {
27
+ const oldest = [...this.map.entries()]
28
+ .sort((a, b) => a[1].expiresAt - b[1].expiresAt)
29
+ .slice(0, this.map.size - this.maxSize);
30
+ for (const [key] of oldest)
31
+ this.map.delete(key);
32
+ }
33
+ }
34
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAKA,MAAM,OAAO,QAAQ;IAGnB,YACmB,KAAa,EACb,UAAkB,EAAE;QADpB,UAAK,GAAL,KAAK,CAAQ;QACb,YAAO,GAAP,OAAO,CAAa;QAJtB,QAAG,GAAG,IAAI,GAAG,EAAoB,CAAC;IAKhD,CAAC;IAEJ,GAAG,CAAC,GAAW;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAC7B,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS;YAAE,OAAO,KAAK,CAAC,KAAK,CAAC;QACrD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,QAAQ,CAAC,GAAW;QAClB,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC;IAClC,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,KAAQ;QACvB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACjE,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,WAAW,EAAE,CAAC;IACvD,CAAC;IAED,KAAK;QACH,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;IAEO,WAAW;QACjB,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;aACnC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;aAC/C,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1C,KAAK,MAAM,CAAC,GAAG,CAAC,IAAI,MAAM;YAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACnD,CAAC;CACF"}
@@ -0,0 +1,3 @@
1
+ import type { DocsClient, DocsClientOptions } from './types.js';
2
+ export declare function createDocsClient(options?: DocsClientOptions): DocsClient;
3
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAW,UAAU,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AA4BzE,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,iBAAsB,GAAG,UAAU,CAuF5E"}
package/dist/client.js ADDED
@@ -0,0 +1,109 @@
1
+ import { TtlCache } from './cache.js';
2
+ import { DocsFetchError } from './types.js';
3
+ const DEFAULTS = {
4
+ owner: 'nbtca',
5
+ repo: 'documents',
6
+ branch: 'main',
7
+ dirTtlMs: 5 * 60 * 1000,
8
+ fileTtlMs: 10 * 60 * 1000,
9
+ };
10
+ const SKIP = new Set(['.github', '.husky', '.vitepress', '.vscode', 'node_modules',
11
+ 'assets', 'public', 'scripts', 'utils', 'package.json', 'pnpm-lock.yaml',
12
+ 'tsconfig.json', 'eslint.config.mjs', '.nvmrc', '.gitignore',
13
+ '.markdownlint-cli2.jsonc', 'CONTRIBUTING.md', 'CONTEXT.md']);
14
+ function filterAndSort(raw) {
15
+ return raw
16
+ .filter(i => !i.name.startsWith('.') && !SKIP.has(i.name) &&
17
+ (i.type === 'dir' || i.name.endsWith('.md')))
18
+ .map(i => ({ name: i.name, path: i.path, type: (i.type === 'dir' ? 'dir' : 'file') }))
19
+ .sort((a, b) => {
20
+ if (a.type !== b.type)
21
+ return a.type === 'dir' ? -1 : 1;
22
+ return a.name.localeCompare(b.name);
23
+ });
24
+ }
25
+ export function createDocsClient(options = {}) {
26
+ const owner = options.owner ?? DEFAULTS.owner;
27
+ const repo = options.repo ?? DEFAULTS.repo;
28
+ const branch = options.branch ?? DEFAULTS.branch;
29
+ const token = options.token ?? (typeof process !== 'undefined'
30
+ ? (process.env['GITHUB_TOKEN'] ?? process.env['GH_TOKEN'])
31
+ : undefined);
32
+ const dirCache = new TtlCache(options.cacheTtlMs?.dir ?? DEFAULTS.dirTtlMs, 30);
33
+ const fileCache = new TtlCache(options.cacheTtlMs?.file ?? DEFAULTS.fileTtlMs, 50);
34
+ function headers() {
35
+ const h = { 'Accept': 'application/vnd.github.v3+json' };
36
+ if (token)
37
+ h['Authorization'] = `Bearer ${token}`;
38
+ return h;
39
+ }
40
+ async function ghFetch(url, timeoutMs = 10000) {
41
+ const ctrl = new AbortController();
42
+ const timer = setTimeout(() => ctrl.abort(), timeoutMs);
43
+ try {
44
+ const res = await fetch(url, { signal: ctrl.signal, headers: headers() });
45
+ return res;
46
+ }
47
+ finally {
48
+ clearTimeout(timer);
49
+ }
50
+ }
51
+ async function listDir(path = '') {
52
+ const key = path || '__root__';
53
+ const hit = dirCache.get(key);
54
+ if (hit)
55
+ return hit;
56
+ const url = `https://api.github.com/repos/${owner}/${repo}/contents/${path}?ref=${branch}`;
57
+ let res;
58
+ try {
59
+ res = await ghFetch(url);
60
+ }
61
+ catch (err) {
62
+ const stale = dirCache.getStale(key);
63
+ if (stale)
64
+ return stale;
65
+ const msg = err instanceof Error && err.name === 'AbortError'
66
+ ? 'Request timed out' : String(err);
67
+ throw new DocsFetchError(path, null, msg);
68
+ }
69
+ if (!res.ok) {
70
+ const stale = dirCache.getStale(key);
71
+ if (stale)
72
+ return stale;
73
+ throw new DocsFetchError(path, res.status, `HTTP ${res.status}`);
74
+ }
75
+ const data = (await res.json());
76
+ const items = filterAndSort(data);
77
+ dirCache.set(key, items);
78
+ return items;
79
+ }
80
+ async function getFile(path) {
81
+ const hit = fileCache.get(path);
82
+ if (hit)
83
+ return hit;
84
+ const url = `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/${path}`;
85
+ let res;
86
+ try {
87
+ res = await ghFetch(url, 15000);
88
+ }
89
+ catch (err) {
90
+ const stale = fileCache.getStale(path);
91
+ if (stale)
92
+ return stale;
93
+ const msg = err instanceof Error && err.name === 'AbortError'
94
+ ? 'Request timed out' : String(err);
95
+ throw new DocsFetchError(path, null, msg);
96
+ }
97
+ if (!res.ok) {
98
+ const stale = fileCache.getStale(path);
99
+ if (stale)
100
+ return stale;
101
+ throw new DocsFetchError(path, res.status, `HTTP ${res.status}`);
102
+ }
103
+ const content = await res.text();
104
+ fileCache.set(path, content);
105
+ return content;
106
+ }
107
+ return { listDir, getFile };
108
+ }
109
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { createDocsClient } from './client.js';
2
+ export type { DocItem, DocsClient, DocsClientOptions } from './types.js';
3
+ export { DocsFetchError } from './types.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { createDocsClient } from './client.js';
2
+ export { DocsFetchError } from './types.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,25 @@
1
+ export interface DocItem {
2
+ name: string;
3
+ path: string;
4
+ type: 'file' | 'dir';
5
+ }
6
+ export interface DocsClientOptions {
7
+ owner?: string;
8
+ repo?: string;
9
+ branch?: string;
10
+ token?: string;
11
+ cacheTtlMs?: {
12
+ dir?: number;
13
+ file?: number;
14
+ };
15
+ }
16
+ export interface DocsClient {
17
+ listDir(path?: string): Promise<DocItem[]>;
18
+ getFile(path: string): Promise<string>;
19
+ }
20
+ export declare class DocsFetchError extends Error {
21
+ readonly path: string;
22
+ readonly status: number | null;
23
+ constructor(path: string, status: number | null, message: string);
24
+ }
25
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE;QACX,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACxC;AAED,qBAAa,cAAe,SAAQ,KAAK;aAErB,IAAI,EAAE,MAAM;aACZ,MAAM,EAAE,MAAM,GAAG,IAAI;gBADrB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GAAG,IAAI,EACrC,OAAO,EAAE,MAAM;CAKlB"}
package/dist/types.js ADDED
@@ -0,0 +1,9 @@
1
+ export class DocsFetchError extends Error {
2
+ constructor(path, status, message) {
3
+ super(message);
4
+ this.path = path;
5
+ this.status = status;
6
+ this.name = 'DocsFetchError';
7
+ }
8
+ }
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAsBA,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,YACkB,IAAY,EACZ,MAAqB,EACrC,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAC;QAJC,SAAI,GAAJ,IAAI,CAAQ;QACZ,WAAM,GAAN,MAAM,CAAe;QAIrC,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF"}
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@nbtca/docs",
3
+ "version": "0.1.0",
4
+ "description": "Data-only library for the NBTCA documents repository",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "scripts": {
18
+ "build": "tsc",
19
+ "test": "vitest run",
20
+ "prepublishOnly": "npm run build && npm test"
21
+ },
22
+ "keywords": [
23
+ "nbtca",
24
+ "documents",
25
+ "github"
26
+ ],
27
+ "license": "MIT",
28
+ "devDependencies": {
29
+ "@types/node": "^26.0.0",
30
+ "typescript": "^5.4.0",
31
+ "vitest": "^2.0.0"
32
+ }
33
+ }