@happyvertical/files 0.74.8
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/AGENT.md +33 -0
- package/LICENSE +7 -0
- package/README.md +136 -0
- package/dist/cli/claude-context.d.ts +3 -0
- package/dist/cli/claude-context.d.ts.map +1 -0
- package/dist/cli/claude-context.js +21 -0
- package/dist/cli/claude-context.js.map +1 -0
- package/dist/factory.d.ts +30 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/fetch.d.ts +142 -0
- package/dist/fetch.d.ts.map +1 -0
- package/dist/filesystem-local.d.ts +82 -0
- package/dist/filesystem-local.d.ts.map +1 -0
- package/dist/filesystem.d.ts +155 -0
- package/dist/filesystem.d.ts.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2719 -0
- package/dist/index.js.map +1 -0
- package/dist/legacy.d.ts +209 -0
- package/dist/legacy.d.ts.map +1 -0
- package/dist/node/local.d.ts +332 -0
- package/dist/node/local.d.ts.map +1 -0
- package/dist/providers/gdrive.d.ts +87 -0
- package/dist/providers/gdrive.d.ts.map +1 -0
- package/dist/providers/s3.d.ts +32 -0
- package/dist/providers/s3.d.ts.map +1 -0
- package/dist/redact.d.ts +2 -0
- package/dist/redact.d.ts.map +1 -0
- package/dist/shared/base.d.ts +106 -0
- package/dist/shared/base.d.ts.map +1 -0
- package/dist/shared/factory.d.ts +148 -0
- package/dist/shared/factory.d.ts.map +1 -0
- package/dist/shared/types.d.ts +464 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/metadata.json +35 -0
- package/package.json +65 -0
package/AGENT.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# @happyvertical/files
|
|
2
|
+
|
|
3
|
+
<!-- BEGIN AGENT:GENERATED -->
|
|
4
|
+
## Purpose
|
|
5
|
+
File system utilities for local and remote file operations
|
|
6
|
+
|
|
7
|
+
## Package Map
|
|
8
|
+
- Package: `@happyvertical/files`
|
|
9
|
+
- Hierarchy path: `@happyvertical/sdk > packages > files`
|
|
10
|
+
- Workspace position: `11 of 30` local packages
|
|
11
|
+
- Internal dependencies: `@happyvertical/utils`
|
|
12
|
+
- Internal dependents: `@happyvertical/documents`, `@happyvertical/sdk-mcp`
|
|
13
|
+
- Knowledge graph files: `AGENT.md`, `metadata.json`, `ecosystem-manifest.json`
|
|
14
|
+
|
|
15
|
+
## Build & Test
|
|
16
|
+
```bash
|
|
17
|
+
pnpm --filter @happyvertical/files build
|
|
18
|
+
pnpm --filter @happyvertical/files test
|
|
19
|
+
pnpm --filter @happyvertical/files clean
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Agent Correction Loops
|
|
23
|
+
- If module resolution or export errors mention a workspace dependency, build the dependency first (`pnpm --filter @happyvertical/utils build`) and then rerun `pnpm --filter @happyvertical/files build`.
|
|
24
|
+
- If tests or exports fail after API, type, or bundle changes, run `pnpm --filter @happyvertical/files clean` followed by `pnpm --filter @happyvertical/files build` and `pnpm --filter @happyvertical/files test`.
|
|
25
|
+
- If failures span multiple packages or Turborepo ordering looks wrong, run `pnpm build` and `pnpm typecheck` from the repo root before retrying package-scoped commands.
|
|
26
|
+
|
|
27
|
+
## Ecosystem Relationships
|
|
28
|
+
- Provides: File system utilities for local and remote file operations
|
|
29
|
+
- Implements: none
|
|
30
|
+
- Requires: @happyvertical/utils, @aws-sdk/client-s3, google-auth-library, googleapis
|
|
31
|
+
- Stability: stable (Primary package surface is described as implemented and production-oriented.)
|
|
32
|
+
<!-- END AGENT:GENERATED -->
|
|
33
|
+
|
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright <2025> <Happy Vertical Corporation>
|
|
2
|
+
|
|
3
|
+
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:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# @happyvertical/files
|
|
2
|
+
|
|
3
|
+
Unified filesystem interface for the HAVE SDK. Provides a consistent API across local filesystem (Node.js `fs/promises`) and Google Drive, with rate-limited fetch utilities and legacy compatibility helpers.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @happyvertical/files
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
> Published to public npm. Depends on `@happyvertical/utils`.
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
### Factory Function
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { getFilesystem } from '@happyvertical/files';
|
|
19
|
+
|
|
20
|
+
// Local filesystem (default)
|
|
21
|
+
const fs = await getFilesystem({ type: 'local', basePath: '/app/data' });
|
|
22
|
+
|
|
23
|
+
await fs.write('output/result.txt', 'Hello, world!');
|
|
24
|
+
const content = await fs.read('config.json');
|
|
25
|
+
const exists = await fs.exists('config.json');
|
|
26
|
+
|
|
27
|
+
// List files with filtering
|
|
28
|
+
const files = await fs.list('.', { filter: /\.json$/, detailed: true });
|
|
29
|
+
for (const file of files) {
|
|
30
|
+
console.log(`${file.name}: ${file.size} bytes, ${file.mimeType}`);
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Google Drive
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { getFilesystem } from '@happyvertical/files';
|
|
38
|
+
|
|
39
|
+
const fs = await getFilesystem({
|
|
40
|
+
type: 'gdrive',
|
|
41
|
+
clientId: 'xxx',
|
|
42
|
+
clientSecret: 'yyy',
|
|
43
|
+
refreshToken: 'zzz',
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
await fs.write('documents/readme.txt', 'Hello from Drive');
|
|
47
|
+
const content = await fs.read('documents/readme.txt');
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Supports OAuth2, service account keys, and short-lived access tokens. Google Docs native formats are automatically exported (Docs → text, Sheets → CSV, etc.).
|
|
51
|
+
|
|
52
|
+
### File Operations
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
await fs.copy('source.txt', 'backup/source-copy.txt');
|
|
56
|
+
await fs.move('temp.txt', 'archive/temp.txt');
|
|
57
|
+
await fs.createDirectory('secure-data', { mode: 0o700 });
|
|
58
|
+
await fs.delete('temporary-file.txt');
|
|
59
|
+
|
|
60
|
+
const stats = await fs.getStats('document.pdf');
|
|
61
|
+
console.log(`${stats.size} bytes, modified ${stats.mtime}`);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Fetch Utilities
|
|
65
|
+
|
|
66
|
+
Rate-limited HTTP fetch helpers for downloading remote content:
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
import { fetchText, fetchJSON, fetchBuffer, fetchToFile, addRateLimit } from '@happyvertical/files';
|
|
70
|
+
|
|
71
|
+
// Set per-domain rate limits
|
|
72
|
+
addRateLimit('api.github.com', 30, 60000);
|
|
73
|
+
|
|
74
|
+
const html = await fetchText('https://example.com');
|
|
75
|
+
const data = await fetchJSON('https://api.example.com/data');
|
|
76
|
+
const buf = await fetchBuffer('https://example.com/image.png');
|
|
77
|
+
await fetchToFile('https://example.com/file.zip', './downloads/file.zip');
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Error Handling
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { FileNotFoundError, PermissionError, DirectoryNotEmptyError } from '@happyvertical/files';
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
await fs.read('missing.txt');
|
|
87
|
+
} catch (error) {
|
|
88
|
+
if (error instanceof FileNotFoundError) {
|
|
89
|
+
console.error('Not found:', error.path);
|
|
90
|
+
} else if (error instanceof PermissionError) {
|
|
91
|
+
console.error('Permission denied:', error.path);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Legacy Functions
|
|
97
|
+
|
|
98
|
+
Standalone functions from the original API, still exported for backward compatibility:
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
import { isFile, isDirectory, ensureDirectoryExists, download, listFiles } from '@happyvertical/files';
|
|
102
|
+
|
|
103
|
+
const fileStats = isFile('/path/to/file.txt'); // synchronous
|
|
104
|
+
const isDir = isDirectory('/path/to/dir'); // synchronous
|
|
105
|
+
await ensureDirectoryExists('/path/to/new/dir');
|
|
106
|
+
await download('https://example.com/file.pdf', './file.pdf');
|
|
107
|
+
const files = await listFiles('/path/to/dir', { match: /\.json$/ });
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Providers
|
|
111
|
+
|
|
112
|
+
| Provider | Status | Options |
|
|
113
|
+
|----------|--------|---------|
|
|
114
|
+
| Local | Implemented | `basePath?` |
|
|
115
|
+
| Google Drive | Implemented | `clientId`, `clientSecret`, `refreshToken` (or `serviceAccountKey` / `accessToken`) |
|
|
116
|
+
| S3 | Types only | `region`, `bucket`, `accessKeyId?`, `secretAccessKey?` |
|
|
117
|
+
| WebDAV | Types only | `baseUrl`, `username`, `password` |
|
|
118
|
+
|
|
119
|
+
## API Overview
|
|
120
|
+
|
|
121
|
+
**Factory**: `getFilesystem(options)`, `registerProvider(type, factory)`, `getAvailableProviders()`, `isProviderAvailable(type)`, `getProviderInfo(type)`
|
|
122
|
+
|
|
123
|
+
**Provider classes**: `LocalFilesystemProvider`, `GoogleDriveProvider`
|
|
124
|
+
|
|
125
|
+
**Interface methods**: `exists`, `read`, `write`, `delete`, `copy`, `move`, `createDirectory`, `list`, `getStats`, `getMimeType`, `upload`, `download`, `downloadWithCache`, `cache.get/set/clear`, `getCapabilities`
|
|
126
|
+
|
|
127
|
+
**Fetch**: `fetchText`, `fetchJSON`, `fetchBuffer`, `fetchToFile`, `addRateLimit`, `getRateLimit`
|
|
128
|
+
|
|
129
|
+
**Errors**: `FilesystemError`, `FileNotFoundError`, `PermissionError`, `DirectoryNotEmptyError`, `InvalidPathError`
|
|
130
|
+
|
|
131
|
+
**Legacy**: `isFile`, `isDirectory`, `ensureDirectoryExists`, `download`, `upload`, `downloadFileWithCache`, `listFiles`, `getCached`, `setCached`, `getMimeType`
|
|
132
|
+
|
|
133
|
+
## Dependencies
|
|
134
|
+
|
|
135
|
+
- `@happyvertical/utils` — temp directory management
|
|
136
|
+
- `googleapis` / `google-auth-library` — Google Drive provider
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-context.d.ts","sourceRoot":"","sources":["../../src/cli/claude-context.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync, mkdirSync, copyFileSync } from "node:fs";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
const Dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const pkgRoot = join(Dirname, "../..");
|
|
7
|
+
const targetDir = join(process.cwd(), ".claude");
|
|
8
|
+
if (!existsSync(targetDir)) {
|
|
9
|
+
mkdirSync(targetDir, { recursive: true });
|
|
10
|
+
}
|
|
11
|
+
const pkgName = "files";
|
|
12
|
+
const agentMdSrc = existsSync(join(pkgRoot, "AGENT.md")) ? join(pkgRoot, "AGENT.md") : join(pkgRoot, "CLAUDE.md");
|
|
13
|
+
const metaSrc = existsSync(join(pkgRoot, "metadata.json")) ? join(pkgRoot, "metadata.json") : join(pkgRoot, ".claude-meta.json");
|
|
14
|
+
if (existsSync(agentMdSrc)) {
|
|
15
|
+
copyFileSync(agentMdSrc, join(targetDir, `have-${pkgName}.md`));
|
|
16
|
+
}
|
|
17
|
+
if (existsSync(metaSrc)) {
|
|
18
|
+
copyFileSync(metaSrc, join(targetDir, `have-${pkgName}.meta.json`));
|
|
19
|
+
}
|
|
20
|
+
console.log(`✓ Installed @happyvertical/${pkgName} context to .claude/`);
|
|
21
|
+
//# sourceMappingURL=claude-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-context.js","sources":["../../src/cli/claude-context.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * CLI script to install agent context for @happyvertical/files\n * Run the published context installer binary for this package.\n */\nimport { copyFileSync, existsSync, mkdirSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst Dirname = dirname(fileURLToPath(import.meta.url));\nconst pkgRoot = join(Dirname, '../..');\nconst targetDir = join(process.cwd(), '.claude');\n\nif (!existsSync(targetDir)) {\n mkdirSync(targetDir, { recursive: true });\n}\n\nconst pkgName = 'files';\nconst agentMdSrc = existsSync(join(pkgRoot, 'AGENT.md'))\n ? join(pkgRoot, 'AGENT.md')\n : join(pkgRoot, 'CLAUDE.md');\nconst metaSrc = existsSync(join(pkgRoot, 'metadata.json'))\n ? join(pkgRoot, 'metadata.json')\n : join(pkgRoot, '.claude-meta.json');\n\nif (existsSync(agentMdSrc)) {\n copyFileSync(agentMdSrc, join(targetDir, `have-${pkgName}.md`));\n}\n\nif (existsSync(metaSrc)) {\n copyFileSync(metaSrc, join(targetDir, `have-${pkgName}.meta.json`));\n}\n\nconsole.log(`✓ Installed @happyvertical/${pkgName} context to .claude/`);\n"],"names":[],"mappings":";;;;AASA,MAAM,UAAU,QAAQ,cAAc,YAAY,GAAG,CAAC;AACtD,MAAM,UAAU,KAAK,SAAS,OAAO;AACrC,MAAM,YAAY,KAAK,QAAQ,IAAA,GAAO,SAAS;AAE/C,IAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,YAAU,WAAW,EAAE,WAAW,KAAA,CAAM;AAC1C;AAEA,MAAM,UAAU;AAChB,MAAM,aAAa,WAAW,KAAK,SAAS,UAAU,CAAC,IACnD,KAAK,SAAS,UAAU,IACxB,KAAK,SAAS,WAAW;AAC7B,MAAM,UAAU,WAAW,KAAK,SAAS,eAAe,CAAC,IACrD,KAAK,SAAS,eAAe,IAC7B,KAAK,SAAS,mBAAmB;AAErC,IAAI,WAAW,UAAU,GAAG;AAC1B,eAAa,YAAY,KAAK,WAAW,QAAQ,OAAO,KAAK,CAAC;AAChE;AAEA,IAAI,WAAW,OAAO,GAAG;AACvB,eAAa,SAAS,KAAK,WAAW,QAAQ,OAAO,YAAY,CAAC;AACpE;AAEA,QAAQ,IAAI,8BAA8B,OAAO,sBAAsB;"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { FilesystemInterface, GetFilesystemOptions } from './shared/types';
|
|
2
|
+
/**
|
|
3
|
+
* Register a filesystem provider
|
|
4
|
+
*/
|
|
5
|
+
export declare function registerProvider(type: string, factory: () => Promise<any>): void;
|
|
6
|
+
/**
|
|
7
|
+
* Get list of available provider types
|
|
8
|
+
*/
|
|
9
|
+
export declare function getAvailableProviders(): string[];
|
|
10
|
+
/**
|
|
11
|
+
* Main factory function to create filesystem instances
|
|
12
|
+
*/
|
|
13
|
+
export declare function getFilesystem(options?: GetFilesystemOptions): Promise<FilesystemInterface>;
|
|
14
|
+
/**
|
|
15
|
+
* Initialize providers by registering them
|
|
16
|
+
*/
|
|
17
|
+
export declare function initializeProviders(): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Check if a provider is available
|
|
20
|
+
*/
|
|
21
|
+
export declare function isProviderAvailable(type: string): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Get provider information
|
|
24
|
+
*/
|
|
25
|
+
export declare function getProviderInfo(type: string): {
|
|
26
|
+
available: boolean;
|
|
27
|
+
description: string;
|
|
28
|
+
requiredOptions: string[];
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EAI1B,MAAM,gBAAgB,CAAC;AAOxB;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,GAC1B,IAAI,CAEN;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD;AAoGD;;GAEG;AACH,wBAAsB,aAAa,CACjC,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,mBAAmB,CAAC,CA4B9B;AAED;;GAEG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAgBzD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B,CAuBA"}
|
package/dist/fetch.d.ts
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
export interface FetchToFileOptions extends RequestInit {
|
|
2
|
+
/** Optional timeout in milliseconds */
|
|
3
|
+
timeout?: number;
|
|
4
|
+
/** Optional transport ceiling in bytes */
|
|
5
|
+
maxBytes?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface WriteResponseToFileOptions {
|
|
8
|
+
/** Optional transport ceiling in bytes */
|
|
9
|
+
maxBytes?: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Sets rate limit configuration for a specific domain
|
|
13
|
+
*
|
|
14
|
+
* Configures custom rate limiting for a specific domain. This allows you to
|
|
15
|
+
* set different limits for different services based on their API requirements.
|
|
16
|
+
*
|
|
17
|
+
* @param domain - Domain to set limits for (e.g., 'api.github.com')
|
|
18
|
+
* @param limit - Maximum number of requests per interval
|
|
19
|
+
* @param interval - Interval in milliseconds (time window for the limit)
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* // Set GitHub API to 30 requests per minute
|
|
24
|
+
* await addRateLimit('api.github.com', 30, 60000);
|
|
25
|
+
*
|
|
26
|
+
* // Set custom API to 10 requests per 5 seconds
|
|
27
|
+
* await addRateLimit('my-api.example.com', 10, 5000);
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare function addRateLimit(domain: string, limit: number, interval: number): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Gets rate limit configuration for a specific domain
|
|
33
|
+
*
|
|
34
|
+
* Retrieves the current rate limiting configuration for a domain.
|
|
35
|
+
* If no specific configuration exists, returns the default configuration.
|
|
36
|
+
*
|
|
37
|
+
* @param domain - Domain to get limits for
|
|
38
|
+
* @returns Promise resolving to rate limit configuration with limit and interval properties
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const config = await getRateLimit('api.github.com');
|
|
43
|
+
* console.log(`GitHub API: ${config.limit} requests per ${config.interval}ms`);
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function getRateLimit(domain: string): Promise<{
|
|
47
|
+
limit: number;
|
|
48
|
+
interval: number;
|
|
49
|
+
}>;
|
|
50
|
+
/**
|
|
51
|
+
* Fetches a URL and returns the response as text with automatic rate limiting
|
|
52
|
+
*
|
|
53
|
+
* Convenience function that performs a rate-limited fetch and returns the
|
|
54
|
+
* response body as a text string. Ideal for fetching HTML, CSS, plain text,
|
|
55
|
+
* or other text-based content.
|
|
56
|
+
*
|
|
57
|
+
* @param url - URL to fetch
|
|
58
|
+
* @returns Promise resolving to the response body as a string
|
|
59
|
+
* @throws {Error} If the fetch fails or response is not ok
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```typescript
|
|
63
|
+
* const html = await fetchText('https://example.com');
|
|
64
|
+
* console.log('Page content:', html);
|
|
65
|
+
*
|
|
66
|
+
* const readme = await fetchText('https://raw.githubusercontent.com/user/repo/main/README.md');
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export declare function fetchText(url: string): Promise<string>;
|
|
70
|
+
/**
|
|
71
|
+
* Fetches a URL and returns the response as parsed JSON with automatic rate limiting
|
|
72
|
+
*
|
|
73
|
+
* Convenience function that performs a rate-limited fetch and parses the
|
|
74
|
+
* response body as JSON. Perfect for consuming REST APIs and JSON endpoints.
|
|
75
|
+
*
|
|
76
|
+
* @param url - URL to fetch
|
|
77
|
+
* @returns Promise resolving to the parsed JSON response (any type)
|
|
78
|
+
* @throws {Error} If the fetch fails, response is not ok, or JSON parsing fails
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* const data = await fetchJSON('https://api.github.com/user');
|
|
83
|
+
* console.log('User data:', data);
|
|
84
|
+
*
|
|
85
|
+
* const config = await fetchJSON('https://example.com/api/config');
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
export declare function fetchJSON(url: string): Promise<any>;
|
|
89
|
+
/**
|
|
90
|
+
* Fetches a URL and returns the response as a Buffer with automatic rate limiting
|
|
91
|
+
*
|
|
92
|
+
* Convenience function that performs a rate-limited fetch and returns the
|
|
93
|
+
* response body as a Buffer. Ideal for fetching binary data like images,
|
|
94
|
+
* documents, or other non-text content.
|
|
95
|
+
*
|
|
96
|
+
* @param url - URL to fetch
|
|
97
|
+
* @returns Promise resolving to the response body as a Buffer
|
|
98
|
+
* @throws {Error} If the fetch fails or response is not ok
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* const imageBuffer = await fetchBuffer('https://example.com/image.png');
|
|
103
|
+
* await fs.writeFile('downloaded-image.png', imageBuffer);
|
|
104
|
+
*
|
|
105
|
+
* const pdfBuffer = await fetchBuffer('https://example.com/document.pdf');
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
export declare function fetchBuffer(url: string): Promise<Buffer>;
|
|
109
|
+
/**
|
|
110
|
+
* Fetches a URL and saves the response directly to a file with automatic rate limiting
|
|
111
|
+
*
|
|
112
|
+
* Convenience function that performs a rate-limited fetch and writes the
|
|
113
|
+
* response body directly to a local file. Efficient for downloading files
|
|
114
|
+
* without loading the entire content into memory.
|
|
115
|
+
*
|
|
116
|
+
* @param url - URL to fetch
|
|
117
|
+
* @param filepath - Local file path where the content should be saved
|
|
118
|
+
* @returns Promise that resolves when the file is saved successfully
|
|
119
|
+
* @throws {Error} If the fetch fails, response is not ok, or file write fails
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```typescript
|
|
123
|
+
* await fetchToFile('https://example.com/large-file.zip', './downloads/file.zip');
|
|
124
|
+
* console.log('File downloaded successfully');
|
|
125
|
+
*
|
|
126
|
+
* await fetchToFile('https://api.example.com/report.pdf', './reports/daily.pdf');
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
export declare function fetchToFile(url: string, filepath: string, options?: FetchToFileOptions): Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* Streams an existing fetch `Response` to disk.
|
|
132
|
+
*
|
|
133
|
+
* The response body is written to a temp file in the destination directory,
|
|
134
|
+
* optional `maxBytes` enforcement is applied while streaming, existing file
|
|
135
|
+
* permissions/ownership are preserved when possible, and the temp file is then
|
|
136
|
+
* atomically renamed into place on success.
|
|
137
|
+
*
|
|
138
|
+
* This helper is transport-only: callers are responsible for validating
|
|
139
|
+
* `response.ok`, headers, and content before persisting it.
|
|
140
|
+
*/
|
|
141
|
+
export declare function writeResponseToFile(response: Response, filepath: string, options?: WriteResponseToFileOptions): Promise<void>;
|
|
142
|
+
//# sourceMappingURL=fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../src/fetch.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,kBAAmB,SAAQ,WAAW;IACrD,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,0BAA0B;IACzC,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA8ND;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,iBAGjB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAM9C;AA+CD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAI5D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAIzD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAI9D;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAWf;AAmDD;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,0BAA+B,GACvC,OAAO,CAAC,IAAI,CAAC,CAGf"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { FilesystemAdapter, FilesystemAdapterOptions } from './filesystem';
|
|
2
|
+
/**
|
|
3
|
+
* Adapter for interacting with the local filesystem
|
|
4
|
+
*/
|
|
5
|
+
export declare class LocalFilesystemAdapter extends FilesystemAdapter {
|
|
6
|
+
/**
|
|
7
|
+
* Cache directory path
|
|
8
|
+
*/
|
|
9
|
+
protected cacheDir: string;
|
|
10
|
+
/**
|
|
11
|
+
* Type identifier for this adapter
|
|
12
|
+
*/
|
|
13
|
+
type: string;
|
|
14
|
+
/**
|
|
15
|
+
* Configuration options
|
|
16
|
+
*/
|
|
17
|
+
protected options: FilesystemAdapterOptions;
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new LocalFilesystemAdapter instance
|
|
20
|
+
*
|
|
21
|
+
* @param options - Configuration options
|
|
22
|
+
*/
|
|
23
|
+
constructor(options: FilesystemAdapterOptions);
|
|
24
|
+
/**
|
|
25
|
+
* Creates a LocalFilesystemAdapter from a URL
|
|
26
|
+
*
|
|
27
|
+
* @param url - URL to create adapter from
|
|
28
|
+
* @returns Promise resolving to a LocalFilesystemAdapter
|
|
29
|
+
*/
|
|
30
|
+
static createFromUrl(_url: string): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Factory method to create a LocalFilesystemAdapter
|
|
33
|
+
*
|
|
34
|
+
* @param options - Configuration options
|
|
35
|
+
* @returns Promise resolving to an initialized LocalFilesystemAdapter
|
|
36
|
+
*/
|
|
37
|
+
static create(options: FilesystemAdapterOptions): Promise<LocalFilesystemAdapter>;
|
|
38
|
+
/**
|
|
39
|
+
* Checks if a file or directory exists in the local filesystem
|
|
40
|
+
*
|
|
41
|
+
* @param path - Path to check
|
|
42
|
+
* @returns Promise resolving to boolean indicating existence
|
|
43
|
+
*/
|
|
44
|
+
exists(_path: string): Promise<boolean>;
|
|
45
|
+
/**
|
|
46
|
+
* Reads a file's contents from the local filesystem
|
|
47
|
+
*
|
|
48
|
+
* @param path - Path to the file
|
|
49
|
+
* @returns Promise resolving to the file contents as a string
|
|
50
|
+
*/
|
|
51
|
+
read(_path: string): Promise<string>;
|
|
52
|
+
/**
|
|
53
|
+
* Writes content to a file in the local filesystem
|
|
54
|
+
*
|
|
55
|
+
* @param path - Path to the file
|
|
56
|
+
* @param content - Content to write
|
|
57
|
+
* @returns Promise that resolves when the write is complete
|
|
58
|
+
*/
|
|
59
|
+
write(_path: string, _content: string): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Deletes a file or directory from the local filesystem
|
|
62
|
+
*
|
|
63
|
+
* @param path - Path to delete
|
|
64
|
+
* @returns Promise that resolves when the deletion is complete
|
|
65
|
+
*/
|
|
66
|
+
delete(_path: string): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Lists files in a directory in the local filesystem
|
|
69
|
+
*
|
|
70
|
+
* @param path - Directory path to list
|
|
71
|
+
* @returns Promise resolving to an array of file names
|
|
72
|
+
*/
|
|
73
|
+
list(_path: string): Promise<never[]>;
|
|
74
|
+
/**
|
|
75
|
+
* Gets the MIME type for a file based on its extension
|
|
76
|
+
*
|
|
77
|
+
* @param path - Path to the file
|
|
78
|
+
* @returns Promise resolving to the MIME type string
|
|
79
|
+
*/
|
|
80
|
+
mimeType(path: string): Promise<string>;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=filesystem-local.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystem-local.d.ts","sourceRoot":"","sources":["../src/filesystem-local.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,KAAK,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAGhF;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,iBAAiB;IAC3D;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE3B;;OAEG;IACI,IAAI,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,wBAAwB,CAAC;IAE5C;;;;OAIG;gBACS,OAAO,EAAE,wBAAwB;IAO7C;;;;;OAKG;WACU,aAAa,CAAC,IAAI,EAAE,MAAM;IAEvC;;;;;OAKG;WACU,MAAM,CAAC,OAAO,EAAE,wBAAwB;IAKrD;;;;;OAKG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM;IAI1B;;;;;OAKG;IACG,IAAI,CAAC,KAAK,EAAE,MAAM;IAIxB;;;;;;OAMG;IACG,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAI3C;;;;;OAKG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM;IAI1B;;;;;OAKG;IACG,IAAI,CAAC,KAAK,EAAE,MAAM;IAIxB;;;;;OAKG;IACG,QAAQ,CAAC,IAAI,EAAE,MAAM;CAI5B"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface defining the required methods for a filesystem adapter
|
|
3
|
+
*/
|
|
4
|
+
export interface FilesystemAdapterInterface {
|
|
5
|
+
/**
|
|
6
|
+
* Checks if a file or directory exists
|
|
7
|
+
*
|
|
8
|
+
* @param path - Path to check
|
|
9
|
+
* @returns Promise resolving to boolean indicating existence
|
|
10
|
+
*/
|
|
11
|
+
exists(path: string): Promise<boolean>;
|
|
12
|
+
/**
|
|
13
|
+
* Reads a file's contents
|
|
14
|
+
*
|
|
15
|
+
* @param path - Path to the file
|
|
16
|
+
* @returns Promise resolving to the file contents as a string
|
|
17
|
+
*/
|
|
18
|
+
read(path: string): Promise<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Writes content to a file
|
|
21
|
+
*
|
|
22
|
+
* @param path - Path to the file
|
|
23
|
+
* @param content - Content to write
|
|
24
|
+
* @returns Promise that resolves when the write is complete
|
|
25
|
+
*/
|
|
26
|
+
write(path: string, content: string): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Deletes a file or directory
|
|
29
|
+
*
|
|
30
|
+
* @param path - Path to delete
|
|
31
|
+
* @returns Promise that resolves when the deletion is complete
|
|
32
|
+
*/
|
|
33
|
+
delete(path: string): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Lists files in a directory
|
|
36
|
+
*
|
|
37
|
+
* @param path - Directory path to list
|
|
38
|
+
* @returns Promise resolving to an array of file names
|
|
39
|
+
*/
|
|
40
|
+
list(path: string): Promise<string[]>;
|
|
41
|
+
/**
|
|
42
|
+
* Gets the MIME type for a file
|
|
43
|
+
*
|
|
44
|
+
* @param path - Path to the file
|
|
45
|
+
* @returns Promise resolving to the MIME type string
|
|
46
|
+
*/
|
|
47
|
+
mimeType(path: string): Promise<string>;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Configuration options for filesystem adapters
|
|
51
|
+
*/
|
|
52
|
+
export interface FilesystemAdapterOptions {
|
|
53
|
+
/**
|
|
54
|
+
* Type of filesystem adapter
|
|
55
|
+
*/
|
|
56
|
+
type?: string;
|
|
57
|
+
/**
|
|
58
|
+
* Directory to use for caching
|
|
59
|
+
*/
|
|
60
|
+
cacheDir?: string;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Base class for filesystem adapters providing common functionality
|
|
64
|
+
*/
|
|
65
|
+
export declare class FilesystemAdapter {
|
|
66
|
+
/**
|
|
67
|
+
* Configuration options
|
|
68
|
+
*/
|
|
69
|
+
protected options: FilesystemAdapterOptions;
|
|
70
|
+
/**
|
|
71
|
+
* Cache directory path
|
|
72
|
+
*/
|
|
73
|
+
protected cacheDir: string;
|
|
74
|
+
/**
|
|
75
|
+
* Creates a new FilesystemAdapter instance
|
|
76
|
+
*
|
|
77
|
+
* @param options - Configuration options
|
|
78
|
+
*/
|
|
79
|
+
constructor(options: FilesystemAdapterOptions);
|
|
80
|
+
/**
|
|
81
|
+
* Factory method to create and initialize a FilesystemAdapter
|
|
82
|
+
*
|
|
83
|
+
* @param options - Configuration options
|
|
84
|
+
* @returns Promise resolving to an initialized FilesystemAdapter
|
|
85
|
+
*/
|
|
86
|
+
static create<T extends FilesystemAdapterOptions>(options: T): Promise<FilesystemAdapter>;
|
|
87
|
+
/**
|
|
88
|
+
* Initializes the adapter by creating the cache directory
|
|
89
|
+
*/
|
|
90
|
+
protected initialize(): Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* Downloads a file from a URL
|
|
93
|
+
*
|
|
94
|
+
* @param url - URL to download from
|
|
95
|
+
* @param options - Download options
|
|
96
|
+
* @param options.force - Whether to force download even if cached
|
|
97
|
+
* @returns Promise resolving to the path of the downloaded file
|
|
98
|
+
*/
|
|
99
|
+
download(_url: string, _options?: {
|
|
100
|
+
force: boolean;
|
|
101
|
+
}): Promise<string>;
|
|
102
|
+
/**
|
|
103
|
+
* Checks if a file or directory exists
|
|
104
|
+
*
|
|
105
|
+
* @param path - Path to check
|
|
106
|
+
* @returns Promise resolving to boolean indicating existence
|
|
107
|
+
*/
|
|
108
|
+
exists(_path: string): Promise<boolean>;
|
|
109
|
+
/**
|
|
110
|
+
* Reads a file's contents
|
|
111
|
+
*
|
|
112
|
+
* @param path - Path to the file
|
|
113
|
+
* @returns Promise resolving to the file contents as a string
|
|
114
|
+
*/
|
|
115
|
+
read(_path: string): Promise<string>;
|
|
116
|
+
/**
|
|
117
|
+
* Writes content to a file
|
|
118
|
+
*
|
|
119
|
+
* @param path - Path to the file
|
|
120
|
+
* @param content - Content to write
|
|
121
|
+
* @returns Promise that resolves when the write is complete
|
|
122
|
+
*/
|
|
123
|
+
write(_path: string, _content: string): Promise<void>;
|
|
124
|
+
/**
|
|
125
|
+
* Deletes a file or directory
|
|
126
|
+
*
|
|
127
|
+
* @param path - Path to delete
|
|
128
|
+
* @returns Promise that resolves when the deletion is complete
|
|
129
|
+
*/
|
|
130
|
+
delete(_path: string): Promise<void>;
|
|
131
|
+
/**
|
|
132
|
+
* Lists files in a directory
|
|
133
|
+
*
|
|
134
|
+
* @param path - Directory path to list
|
|
135
|
+
* @returns Promise resolving to an array of file names
|
|
136
|
+
*/
|
|
137
|
+
list(_path: string): Promise<string[]>;
|
|
138
|
+
/**
|
|
139
|
+
* Gets data from cache if available and not expired
|
|
140
|
+
*
|
|
141
|
+
* @param file - Cache file identifier
|
|
142
|
+
* @param expiry - Cache expiry time in milliseconds
|
|
143
|
+
* @returns Promise resolving to the cached data or undefined if not found/expired
|
|
144
|
+
*/
|
|
145
|
+
getCached(file: string, expiry?: number): Promise<string | undefined>;
|
|
146
|
+
/**
|
|
147
|
+
* Sets data in cache
|
|
148
|
+
*
|
|
149
|
+
* @param file - Cache file identifier
|
|
150
|
+
* @param data - Data to cache
|
|
151
|
+
* @returns Promise that resolves when the data is cached
|
|
152
|
+
*/
|
|
153
|
+
setCached(file: string, data: string): Promise<void>;
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=filesystem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystem.d.ts","sourceRoot":"","sources":["../src/filesystem.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC;;;;;OAKG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEvC;;;;;OAKG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEpC;;;;;;OAMG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpD;;;;;OAKG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpC;;;;;OAKG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEtC;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,iBAAiB;IAC5B;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,wBAAwB,CAAC;IAE5C;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE3B;;;;OAIG;gBACS,OAAO,EAAE,wBAAwB;IAK7C;;;;;OAKG;WACU,MAAM,CAAC,CAAC,SAAS,wBAAwB,EACpD,OAAO,EAAE,CAAC,GACT,OAAO,CAAC,iBAAiB,CAAC;IAM7B;;OAEG;cACa,UAAU;IAI1B;;;;;;;OAOG;IACG,QAAQ,CACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE;QACR,KAAK,EAAE,OAAO,CAAC;KAGhB,GACA,OAAO,CAAC,MAAM,CAAC;IAIlB;;;;;OAKG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK7C;;;;;OAKG;IACG,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK1C;;;;;;OAMG;IACG,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3D;;;;;OAKG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C;;;;;OAKG;IACG,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAK5C;;;;;;OAMG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,SAAS;IAI7C;;;;;;OAMG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CAG3C"}
|