@uploadista/client-core 0.0.3
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/.turbo/turbo-build.log +5 -0
- package/LICENSE +21 -0
- package/README.md +100 -0
- package/dist/auth/auth-http-client.d.ts +50 -0
- package/dist/auth/auth-http-client.d.ts.map +1 -0
- package/dist/auth/auth-http-client.js +110 -0
- package/dist/auth/direct-auth.d.ts +38 -0
- package/dist/auth/direct-auth.d.ts.map +1 -0
- package/dist/auth/direct-auth.js +95 -0
- package/dist/auth/index.d.ts +6 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +5 -0
- package/dist/auth/no-auth.d.ts +26 -0
- package/dist/auth/no-auth.d.ts.map +1 -0
- package/dist/auth/no-auth.js +33 -0
- package/dist/auth/saas-auth.d.ts +80 -0
- package/dist/auth/saas-auth.d.ts.map +1 -0
- package/dist/auth/saas-auth.js +167 -0
- package/dist/auth/types.d.ts +101 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +8 -0
- package/dist/chunk-buffer.d.ts +209 -0
- package/dist/chunk-buffer.d.ts.map +1 -0
- package/dist/chunk-buffer.js +236 -0
- package/dist/client/create-uploadista-client.d.ts +369 -0
- package/dist/client/create-uploadista-client.d.ts.map +1 -0
- package/dist/client/create-uploadista-client.js +518 -0
- package/dist/client/index.d.ts +4 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +3 -0
- package/dist/client/uploadista-api.d.ts +284 -0
- package/dist/client/uploadista-api.d.ts.map +1 -0
- package/dist/client/uploadista-api.js +444 -0
- package/dist/client/uploadista-websocket-manager.d.ts +110 -0
- package/dist/client/uploadista-websocket-manager.d.ts.map +1 -0
- package/dist/client/uploadista-websocket-manager.js +207 -0
- package/dist/error.d.ts +106 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +69 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/logger.d.ts +70 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +59 -0
- package/dist/mock-data-store.d.ts +30 -0
- package/dist/mock-data-store.d.ts.map +1 -0
- package/dist/mock-data-store.js +88 -0
- package/dist/network-monitor.d.ts +262 -0
- package/dist/network-monitor.d.ts.map +1 -0
- package/dist/network-monitor.js +291 -0
- package/dist/services/abort-controller-service.d.ts +19 -0
- package/dist/services/abort-controller-service.d.ts.map +1 -0
- package/dist/services/abort-controller-service.js +4 -0
- package/dist/services/checksum-service.d.ts +4 -0
- package/dist/services/checksum-service.d.ts.map +1 -0
- package/dist/services/checksum-service.js +1 -0
- package/dist/services/file-reader-service.d.ts +38 -0
- package/dist/services/file-reader-service.d.ts.map +1 -0
- package/dist/services/file-reader-service.js +4 -0
- package/dist/services/fingerprint-service.d.ts +4 -0
- package/dist/services/fingerprint-service.d.ts.map +1 -0
- package/dist/services/fingerprint-service.js +1 -0
- package/dist/services/http-client.d.ts +182 -0
- package/dist/services/http-client.d.ts.map +1 -0
- package/dist/services/http-client.js +1 -0
- package/dist/services/id-generation-service.d.ts +10 -0
- package/dist/services/id-generation-service.d.ts.map +1 -0
- package/dist/services/id-generation-service.js +1 -0
- package/dist/services/index.d.ts +11 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +10 -0
- package/dist/services/platform-service.d.ts +48 -0
- package/dist/services/platform-service.d.ts.map +1 -0
- package/dist/services/platform-service.js +10 -0
- package/dist/services/service-container.d.ts +25 -0
- package/dist/services/service-container.d.ts.map +1 -0
- package/dist/services/service-container.js +1 -0
- package/dist/services/storage-service.d.ts +26 -0
- package/dist/services/storage-service.d.ts.map +1 -0
- package/dist/services/storage-service.js +1 -0
- package/dist/services/websocket-service.d.ts +36 -0
- package/dist/services/websocket-service.d.ts.map +1 -0
- package/dist/services/websocket-service.js +4 -0
- package/dist/smart-chunker.d.ts +72 -0
- package/dist/smart-chunker.d.ts.map +1 -0
- package/dist/smart-chunker.js +317 -0
- package/dist/storage/client-storage.d.ts +148 -0
- package/dist/storage/client-storage.d.ts.map +1 -0
- package/dist/storage/client-storage.js +62 -0
- package/dist/storage/in-memory-storage-service.d.ts +7 -0
- package/dist/storage/in-memory-storage-service.d.ts.map +1 -0
- package/dist/storage/in-memory-storage-service.js +24 -0
- package/dist/storage/index.d.ts +3 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +2 -0
- package/dist/types/buffered-chunk.d.ts +6 -0
- package/dist/types/buffered-chunk.d.ts.map +1 -0
- package/dist/types/buffered-chunk.js +1 -0
- package/dist/types/chunk-metrics.d.ts +12 -0
- package/dist/types/chunk-metrics.d.ts.map +1 -0
- package/dist/types/chunk-metrics.js +1 -0
- package/dist/types/flow-result.d.ts +11 -0
- package/dist/types/flow-result.d.ts.map +1 -0
- package/dist/types/flow-result.js +1 -0
- package/dist/types/flow-upload-config.d.ts +54 -0
- package/dist/types/flow-upload-config.d.ts.map +1 -0
- package/dist/types/flow-upload-config.js +1 -0
- package/dist/types/flow-upload-item.d.ts +16 -0
- package/dist/types/flow-upload-item.d.ts.map +1 -0
- package/dist/types/flow-upload-item.js +1 -0
- package/dist/types/flow-upload-options.d.ts +41 -0
- package/dist/types/flow-upload-options.d.ts.map +1 -0
- package/dist/types/flow-upload-options.js +1 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +13 -0
- package/dist/types/multi-flow-upload-options.d.ts +33 -0
- package/dist/types/multi-flow-upload-options.d.ts.map +1 -0
- package/dist/types/multi-flow-upload-options.js +1 -0
- package/dist/types/multi-flow-upload-state.d.ts +9 -0
- package/dist/types/multi-flow-upload-state.d.ts.map +1 -0
- package/dist/types/multi-flow-upload-state.js +1 -0
- package/dist/types/performance-insights.d.ts +11 -0
- package/dist/types/performance-insights.d.ts.map +1 -0
- package/dist/types/performance-insights.js +1 -0
- package/dist/types/previous-upload.d.ts +20 -0
- package/dist/types/previous-upload.d.ts.map +1 -0
- package/dist/types/previous-upload.js +9 -0
- package/dist/types/upload-options.d.ts +40 -0
- package/dist/types/upload-options.d.ts.map +1 -0
- package/dist/types/upload-options.js +1 -0
- package/dist/types/upload-response.d.ts +6 -0
- package/dist/types/upload-response.d.ts.map +1 -0
- package/dist/types/upload-response.js +1 -0
- package/dist/types/upload-result.d.ts +57 -0
- package/dist/types/upload-result.d.ts.map +1 -0
- package/dist/types/upload-result.js +1 -0
- package/dist/types/upload-session-metrics.d.ts +16 -0
- package/dist/types/upload-session-metrics.d.ts.map +1 -0
- package/dist/types/upload-session-metrics.js +1 -0
- package/dist/upload/chunk-upload.d.ts +40 -0
- package/dist/upload/chunk-upload.d.ts.map +1 -0
- package/dist/upload/chunk-upload.js +82 -0
- package/dist/upload/flow-upload.d.ts +48 -0
- package/dist/upload/flow-upload.d.ts.map +1 -0
- package/dist/upload/flow-upload.js +240 -0
- package/dist/upload/index.d.ts +3 -0
- package/dist/upload/index.d.ts.map +1 -0
- package/dist/upload/index.js +2 -0
- package/dist/upload/parallel-upload.d.ts +65 -0
- package/dist/upload/parallel-upload.d.ts.map +1 -0
- package/dist/upload/parallel-upload.js +231 -0
- package/dist/upload/single-upload.d.ts +118 -0
- package/dist/upload/single-upload.d.ts.map +1 -0
- package/dist/upload/single-upload.js +332 -0
- package/dist/upload/upload-manager.d.ts +30 -0
- package/dist/upload/upload-manager.d.ts.map +1 -0
- package/dist/upload/upload-manager.js +57 -0
- package/dist/upload/upload-metrics.d.ts +37 -0
- package/dist/upload/upload-metrics.d.ts.map +1 -0
- package/dist/upload/upload-metrics.js +236 -0
- package/dist/upload/upload-storage.d.ts +32 -0
- package/dist/upload/upload-storage.d.ts.map +1 -0
- package/dist/upload/upload-storage.js +46 -0
- package/dist/upload/upload-strategy.d.ts +66 -0
- package/dist/upload/upload-strategy.d.ts.map +1 -0
- package/dist/upload/upload-strategy.js +171 -0
- package/dist/upload/upload-utils.d.ts +26 -0
- package/dist/upload/upload-utils.d.ts.map +1 -0
- package/dist/upload/upload-utils.js +80 -0
- package/package.json +29 -0
- package/src/__tests__/smart-chunking.test.ts +399 -0
- package/src/auth/__tests__/auth-http-client.test.ts +327 -0
- package/src/auth/__tests__/direct-auth.test.ts +135 -0
- package/src/auth/__tests__/no-auth.test.ts +40 -0
- package/src/auth/__tests__/saas-auth.test.ts +337 -0
- package/src/auth/auth-http-client.ts +150 -0
- package/src/auth/direct-auth.ts +121 -0
- package/src/auth/index.ts +5 -0
- package/src/auth/no-auth.ts +39 -0
- package/src/auth/saas-auth.ts +218 -0
- package/src/auth/types.ts +105 -0
- package/src/chunk-buffer.ts +287 -0
- package/src/client/create-uploadista-client.ts +901 -0
- package/src/client/index.ts +3 -0
- package/src/client/uploadista-api.ts +857 -0
- package/src/client/uploadista-websocket-manager.ts +275 -0
- package/src/error.ts +149 -0
- package/src/index.ts +13 -0
- package/src/logger.ts +104 -0
- package/src/mock-data-store.ts +97 -0
- package/src/network-monitor.ts +445 -0
- package/src/services/abort-controller-service.ts +21 -0
- package/src/services/checksum-service.ts +3 -0
- package/src/services/file-reader-service.ts +44 -0
- package/src/services/fingerprint-service.ts +6 -0
- package/src/services/http-client.ts +229 -0
- package/src/services/id-generation-service.ts +9 -0
- package/src/services/index.ts +10 -0
- package/src/services/platform-service.ts +65 -0
- package/src/services/service-container.ts +24 -0
- package/src/services/storage-service.ts +29 -0
- package/src/services/websocket-service.ts +33 -0
- package/src/smart-chunker.ts +451 -0
- package/src/storage/client-storage.ts +186 -0
- package/src/storage/in-memory-storage-service.ts +33 -0
- package/src/storage/index.ts +2 -0
- package/src/types/buffered-chunk.ts +5 -0
- package/src/types/chunk-metrics.ts +11 -0
- package/src/types/flow-result.ts +14 -0
- package/src/types/flow-upload-config.ts +56 -0
- package/src/types/flow-upload-item.ts +16 -0
- package/src/types/flow-upload-options.ts +56 -0
- package/src/types/index.ts +13 -0
- package/src/types/multi-flow-upload-options.ts +39 -0
- package/src/types/multi-flow-upload-state.ts +9 -0
- package/src/types/performance-insights.ts +7 -0
- package/src/types/previous-upload.ts +22 -0
- package/src/types/upload-options.ts +56 -0
- package/src/types/upload-response.ts +6 -0
- package/src/types/upload-result.ts +60 -0
- package/src/types/upload-session-metrics.ts +15 -0
- package/src/upload/chunk-upload.ts +151 -0
- package/src/upload/flow-upload.ts +367 -0
- package/src/upload/index.ts +2 -0
- package/src/upload/parallel-upload.ts +387 -0
- package/src/upload/single-upload.ts +554 -0
- package/src/upload/upload-manager.ts +106 -0
- package/src/upload/upload-metrics.ts +340 -0
- package/src/upload/upload-storage.ts +87 -0
- package/src/upload/upload-strategy.ts +296 -0
- package/src/upload/upload-utils.ts +114 -0
- package/tsconfig.json +23 -0
- package/tsconfig.tsbuildinfo +1 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 uploadista
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# @uploadista/client-core
|
|
2
|
+
|
|
3
|
+
Platform-agnostic core upload client logic for Uploadista.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package contains the core upload orchestration logic that is shared across all platform-specific client implementations (browser, React Native, Expo, etc.). It provides:
|
|
8
|
+
|
|
9
|
+
- Service interfaces for dependency injection
|
|
10
|
+
- Platform-agnostic types and error handling
|
|
11
|
+
- Network monitoring and performance tracking
|
|
12
|
+
- Chunk buffering utilities
|
|
13
|
+
- Upload fingerprinting abstractions
|
|
14
|
+
|
|
15
|
+
## Architecture
|
|
16
|
+
|
|
17
|
+
The client-core package is designed to be platform-independent and does NOT include any browser-specific or React Native-specific dependencies. It uses ES2020 as the target and does not include DOM types.
|
|
18
|
+
|
|
19
|
+
### Service Interfaces
|
|
20
|
+
|
|
21
|
+
Platform-specific implementations must provide concrete implementations of these services:
|
|
22
|
+
|
|
23
|
+
- `StorageService` - Persistent storage for upload state (localStorage, AsyncStorage, etc.)
|
|
24
|
+
- `IdGenerationService` - Unique ID generation (crypto.randomUUID, uuid library, etc.)
|
|
25
|
+
- `HttpClient` - HTTP request handling with connection pooling
|
|
26
|
+
- `FileReaderService` - File reading and slicing for chunked uploads
|
|
27
|
+
- `Base64Service` (optional) - Base64 encoding/decoding
|
|
28
|
+
|
|
29
|
+
### Service Container
|
|
30
|
+
|
|
31
|
+
The `ServiceContainer` interface defines the required services that must be injected into the upload client:
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
interface ServiceContainer {
|
|
35
|
+
storage: StorageService;
|
|
36
|
+
idGeneration: IdGenerationService;
|
|
37
|
+
httpClient: HttpClient;
|
|
38
|
+
fileReader: FileReaderService;
|
|
39
|
+
base64?: Base64Service;
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Usage
|
|
44
|
+
|
|
45
|
+
This package is not meant to be used directly. Instead, use one of the platform-specific implementations:
|
|
46
|
+
|
|
47
|
+
- `@uploadista/client-browser` - For web browsers
|
|
48
|
+
- `@uploadista/client-react-native` - For React Native apps
|
|
49
|
+
- `@uploadista/client-expo` - For Expo apps
|
|
50
|
+
|
|
51
|
+
## Exports
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
// Service interfaces
|
|
55
|
+
export * from "./services";
|
|
56
|
+
|
|
57
|
+
// Core types
|
|
58
|
+
export * from "./types";
|
|
59
|
+
export * from "./error";
|
|
60
|
+
export * from "./logger";
|
|
61
|
+
export * from "./previous-upload";
|
|
62
|
+
export * from "./generate-fingerprint";
|
|
63
|
+
|
|
64
|
+
// Utilities
|
|
65
|
+
export * from "./network-monitor";
|
|
66
|
+
export * from "./chunk-buffer";
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## TypeScript Configuration
|
|
70
|
+
|
|
71
|
+
This package uses strict TypeScript configuration with:
|
|
72
|
+
- Target: ES2020
|
|
73
|
+
- Lib: ES2020 only (no DOM)
|
|
74
|
+
- Strict mode enabled
|
|
75
|
+
- No unchecked indexed access
|
|
76
|
+
|
|
77
|
+
## Dependencies
|
|
78
|
+
|
|
79
|
+
Minimal dependencies:
|
|
80
|
+
- `@uploadista/core` - Core uploadista types and utilities
|
|
81
|
+
|
|
82
|
+
## Development
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# Format code
|
|
86
|
+
pnpm run format
|
|
87
|
+
|
|
88
|
+
# Lint code
|
|
89
|
+
pnpm run lint
|
|
90
|
+
|
|
91
|
+
# Check (format + lint)
|
|
92
|
+
pnpm run check
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Design Principles
|
|
96
|
+
|
|
97
|
+
1. **Platform Independence** - No platform-specific code or dependencies
|
|
98
|
+
2. **Dependency Injection** - All platform-specific services are injected
|
|
99
|
+
3. **Type Safety** - Full TypeScript support with strict mode
|
|
100
|
+
4. **Zero Runtime Assumptions** - No assumptions about the runtime environment
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { HttpClient, HttpRequestOptions, HttpResponse } from "../services/http-client";
|
|
2
|
+
import type { DirectAuthManager } from "./direct-auth";
|
|
3
|
+
import type { NoAuthManager } from "./no-auth";
|
|
4
|
+
import type { SaasAuthManager } from "./saas-auth";
|
|
5
|
+
/**
|
|
6
|
+
* Union type of all auth managers
|
|
7
|
+
*/
|
|
8
|
+
export type AuthManager = DirectAuthManager | SaasAuthManager | NoAuthManager;
|
|
9
|
+
/**
|
|
10
|
+
* Auth-aware HTTP client wrapper.
|
|
11
|
+
*
|
|
12
|
+
* Wraps a standard HttpClient and automatically attaches authentication
|
|
13
|
+
* credentials/tokens to all HTTP requests based on the configured auth manager.
|
|
14
|
+
*
|
|
15
|
+
* The wrapper delegates all non-auth concerns (connection pooling, metrics, etc.)
|
|
16
|
+
* to the underlying HttpClient and only adds the auth layer on top.
|
|
17
|
+
*/
|
|
18
|
+
export declare class AuthHttpClient implements HttpClient {
|
|
19
|
+
private httpClient;
|
|
20
|
+
private authManager;
|
|
21
|
+
constructor(httpClient: HttpClient, authManager: AuthManager);
|
|
22
|
+
/**
|
|
23
|
+
* Make an HTTP request with authentication credentials attached.
|
|
24
|
+
* Calls the auth manager to attach credentials before delegating to the underlying client.
|
|
25
|
+
*/
|
|
26
|
+
request(url: string, options?: HttpRequestOptions): Promise<HttpResponse>;
|
|
27
|
+
/**
|
|
28
|
+
* Attach authentication credentials to request headers.
|
|
29
|
+
* Delegates to the appropriate auth manager method.
|
|
30
|
+
*/
|
|
31
|
+
private attachAuthCredentials;
|
|
32
|
+
/**
|
|
33
|
+
* Extract job ID from URL for SaaS mode token caching.
|
|
34
|
+
* Looks for patterns like /upload/{id} or /jobs/{id} in the URL.
|
|
35
|
+
*/
|
|
36
|
+
private extractJobIdFromUrl;
|
|
37
|
+
/**
|
|
38
|
+
* Delegate metrics methods to underlying HTTP client
|
|
39
|
+
*/
|
|
40
|
+
getMetrics(): import("..").ConnectionMetrics;
|
|
41
|
+
getDetailedMetrics(): import("..").DetailedConnectionMetrics;
|
|
42
|
+
reset(): void;
|
|
43
|
+
close(): Promise<void>;
|
|
44
|
+
warmupConnections(urls: string[]): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Get the underlying auth manager for advanced use cases
|
|
47
|
+
*/
|
|
48
|
+
getAuthManager(): AuthManager;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=auth-http-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-http-client.d.ts","sourceRoot":"","sources":["../../src/auth/auth-http-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,kBAAkB,EAClB,YAAY,EACb,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG,eAAe,GAAG,aAAa,CAAC;AAE9E;;;;;;;;GAQG;AACH,qBAAa,cAAe,YAAW,UAAU;IAE7C,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,WAAW;gBADX,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,WAAW;IAGlC;;;OAGG;IACG,OAAO,CACX,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,YAAY,CAAC;IA8BxB;;;OAGG;YACW,qBAAqB;IAoBnC;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IA0B3B;;OAEG;IACH,UAAU;IAIV,kBAAkB;IAIlB,KAAK;IAIC,KAAK;IAIL,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE;IAItC;;OAEG;IACH,cAAc,IAAI,WAAW;CAG9B"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth-aware HTTP client wrapper.
|
|
3
|
+
*
|
|
4
|
+
* Wraps a standard HttpClient and automatically attaches authentication
|
|
5
|
+
* credentials/tokens to all HTTP requests based on the configured auth manager.
|
|
6
|
+
*
|
|
7
|
+
* The wrapper delegates all non-auth concerns (connection pooling, metrics, etc.)
|
|
8
|
+
* to the underlying HttpClient and only adds the auth layer on top.
|
|
9
|
+
*/
|
|
10
|
+
export class AuthHttpClient {
|
|
11
|
+
constructor(httpClient, authManager) {
|
|
12
|
+
this.httpClient = httpClient;
|
|
13
|
+
this.authManager = authManager;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Make an HTTP request with authentication credentials attached.
|
|
17
|
+
* Calls the auth manager to attach credentials before delegating to the underlying client.
|
|
18
|
+
*/
|
|
19
|
+
async request(url, options = {}) {
|
|
20
|
+
try {
|
|
21
|
+
// Attach auth credentials to request headers
|
|
22
|
+
const authenticatedHeaders = await this.attachAuthCredentials(options.headers || {}, url);
|
|
23
|
+
// Delegate to underlying HTTP client with authenticated headers
|
|
24
|
+
return await this.httpClient.request(url, {
|
|
25
|
+
...options,
|
|
26
|
+
headers: authenticatedHeaders,
|
|
27
|
+
// include credentials for cors if needed
|
|
28
|
+
credentials: this.authManager.getType() === "no-auth" ||
|
|
29
|
+
this.authManager.getType() === "saas"
|
|
30
|
+
? "omit"
|
|
31
|
+
: (options.credentials ?? "include"),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
// If auth fails, wrap error with context
|
|
36
|
+
if (error instanceof Error && error.message.includes("auth")) {
|
|
37
|
+
throw error; // Re-throw auth errors as-is
|
|
38
|
+
}
|
|
39
|
+
// For other errors, let them propagate
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Attach authentication credentials to request headers.
|
|
45
|
+
* Delegates to the appropriate auth manager method.
|
|
46
|
+
*/
|
|
47
|
+
async attachAuthCredentials(headers, url) {
|
|
48
|
+
// Check if this is a DirectAuthManager or SaasAuthManager
|
|
49
|
+
if ("attachCredentials" in this.authManager) {
|
|
50
|
+
// DirectAuthManager or NoAuthManager
|
|
51
|
+
return await this.authManager.attachCredentials(headers);
|
|
52
|
+
}
|
|
53
|
+
if ("attachToken" in this.authManager) {
|
|
54
|
+
// SaasAuthManager - extract job ID from URL if present
|
|
55
|
+
const jobId = this.extractJobIdFromUrl(url);
|
|
56
|
+
return await this.authManager.attachToken(headers, jobId);
|
|
57
|
+
}
|
|
58
|
+
// Fallback - return headers unchanged
|
|
59
|
+
return headers;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Extract job ID from URL for SaaS mode token caching.
|
|
63
|
+
* Looks for patterns like /upload/{id} or /jobs/{id} in the URL.
|
|
64
|
+
*/
|
|
65
|
+
extractJobIdFromUrl(url) {
|
|
66
|
+
// Match patterns like:
|
|
67
|
+
// - /api/upload/{uploadId}
|
|
68
|
+
// - /api/flow/{flowId}/{storageId}
|
|
69
|
+
// - /api/jobs/{jobId}/status
|
|
70
|
+
// - /api/jobs/{jobId}/continue/{nodeId}
|
|
71
|
+
const uploadMatch = url.match(/\/api\/upload\/([^/?]+)/);
|
|
72
|
+
if (uploadMatch) {
|
|
73
|
+
return uploadMatch[1];
|
|
74
|
+
}
|
|
75
|
+
const flowMatch = url.match(/\/api\/flow\/([^/?]+)/);
|
|
76
|
+
if (flowMatch) {
|
|
77
|
+
return flowMatch[1];
|
|
78
|
+
}
|
|
79
|
+
const jobMatch = url.match(/\/api\/jobs\/([^/?]+)/);
|
|
80
|
+
if (jobMatch) {
|
|
81
|
+
return jobMatch[1];
|
|
82
|
+
}
|
|
83
|
+
// No job ID found - SaaS mode will use global token
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Delegate metrics methods to underlying HTTP client
|
|
88
|
+
*/
|
|
89
|
+
getMetrics() {
|
|
90
|
+
return this.httpClient.getMetrics();
|
|
91
|
+
}
|
|
92
|
+
getDetailedMetrics() {
|
|
93
|
+
return this.httpClient.getDetailedMetrics();
|
|
94
|
+
}
|
|
95
|
+
reset() {
|
|
96
|
+
this.httpClient.reset();
|
|
97
|
+
}
|
|
98
|
+
async close() {
|
|
99
|
+
await this.httpClient.close();
|
|
100
|
+
}
|
|
101
|
+
async warmupConnections(urls) {
|
|
102
|
+
await this.httpClient.warmupConnections(urls);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get the underlying auth manager for advanced use cases
|
|
106
|
+
*/
|
|
107
|
+
getAuthManager() {
|
|
108
|
+
return this.authManager;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Logger } from "../logger";
|
|
2
|
+
import type { PlatformService } from "../services/platform-service";
|
|
3
|
+
import type { DirectAuthConfig } from "./types";
|
|
4
|
+
import { BaseAuthManager } from "./types";
|
|
5
|
+
/**
|
|
6
|
+
* Direct auth manager - handles credential attachment for "bring your own auth" mode.
|
|
7
|
+
*
|
|
8
|
+
* This manager calls the user-provided getCredentials() function before each request
|
|
9
|
+
* and attaches the returned credentials (headers, cookies) to the HTTP request.
|
|
10
|
+
*
|
|
11
|
+
* Supports any authentication protocol: OAuth, JWT, API keys, session cookies, etc.
|
|
12
|
+
*/
|
|
13
|
+
export declare class DirectAuthManager extends BaseAuthManager {
|
|
14
|
+
private config;
|
|
15
|
+
private platformService;
|
|
16
|
+
private logger;
|
|
17
|
+
constructor(config: DirectAuthConfig, platformService: PlatformService, logger: Logger);
|
|
18
|
+
/**
|
|
19
|
+
* Attach credentials to an HTTP request by calling getCredentials() and
|
|
20
|
+
* merging the returned headers/cookies with the request.
|
|
21
|
+
*
|
|
22
|
+
* @param headers - Existing request headers
|
|
23
|
+
* @returns Updated headers with credentials attached
|
|
24
|
+
* @throws Error if getCredentials() throws or returns invalid data
|
|
25
|
+
*/
|
|
26
|
+
attachCredentials(headers?: Record<string, string>): Promise<Record<string, string>>;
|
|
27
|
+
/**
|
|
28
|
+
* Validate that headers is a valid object with string keys and values
|
|
29
|
+
*/
|
|
30
|
+
private validateHeaders;
|
|
31
|
+
/**
|
|
32
|
+
* Attach cookies to request headers.
|
|
33
|
+
* In browser environments, cookies are automatically handled by fetch().
|
|
34
|
+
* In Node.js, we need to manually add them to the Cookie header.
|
|
35
|
+
*/
|
|
36
|
+
private attachCookies;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=direct-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"direct-auth.d.ts","sourceRoot":"","sources":["../../src/auth/direct-auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C;;;;;;;GAOG;AACH,qBAAa,iBAAkB,SAAQ,eAAe;IAElD,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,eAAe;IACvB,OAAO,CAAC,MAAM;gBAFN,MAAM,EAAE,gBAAgB,EACxB,eAAe,EAAE,eAAe,EAChC,MAAM,EAAE,MAAM;IAKxB;;;;;;;OAOG;IACG,iBAAiB,CACrB,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACnC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAuClC;;OAEG;IACH,OAAO,CAAC,eAAe;IAcvB;;;;OAIG;IACH,OAAO,CAAC,aAAa;CA2BtB"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { BaseAuthManager } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Direct auth manager - handles credential attachment for "bring your own auth" mode.
|
|
4
|
+
*
|
|
5
|
+
* This manager calls the user-provided getCredentials() function before each request
|
|
6
|
+
* and attaches the returned credentials (headers, cookies) to the HTTP request.
|
|
7
|
+
*
|
|
8
|
+
* Supports any authentication protocol: OAuth, JWT, API keys, session cookies, etc.
|
|
9
|
+
*/
|
|
10
|
+
export class DirectAuthManager extends BaseAuthManager {
|
|
11
|
+
constructor(config, platformService, logger) {
|
|
12
|
+
super("direct");
|
|
13
|
+
this.config = config;
|
|
14
|
+
this.platformService = platformService;
|
|
15
|
+
this.logger = logger;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Attach credentials to an HTTP request by calling getCredentials() and
|
|
19
|
+
* merging the returned headers/cookies with the request.
|
|
20
|
+
*
|
|
21
|
+
* @param headers - Existing request headers
|
|
22
|
+
* @returns Updated headers with credentials attached
|
|
23
|
+
* @throws Error if getCredentials() throws or returns invalid data
|
|
24
|
+
*/
|
|
25
|
+
async attachCredentials(headers = {}) {
|
|
26
|
+
try {
|
|
27
|
+
if (!this.config.getCredentials) {
|
|
28
|
+
return headers;
|
|
29
|
+
}
|
|
30
|
+
// Call user's credential provider (may be async)
|
|
31
|
+
const credentials = await Promise.resolve(this.config.getCredentials());
|
|
32
|
+
// Validate credentials
|
|
33
|
+
if (!credentials || typeof credentials !== "object") {
|
|
34
|
+
throw new Error("getCredentials() must return an object with headers and/or cookies");
|
|
35
|
+
}
|
|
36
|
+
// Merge credential headers with existing headers
|
|
37
|
+
const updatedHeaders = { ...headers };
|
|
38
|
+
if (credentials.headers) {
|
|
39
|
+
this.validateHeaders(credentials.headers);
|
|
40
|
+
Object.assign(updatedHeaders, credentials.headers);
|
|
41
|
+
}
|
|
42
|
+
// Note: Cookie handling would be browser-specific
|
|
43
|
+
// For now, we only support headers as cookies are automatically
|
|
44
|
+
// handled by the browser when using fetch()
|
|
45
|
+
if (credentials.cookies) {
|
|
46
|
+
this.attachCookies(updatedHeaders, credentials.cookies);
|
|
47
|
+
}
|
|
48
|
+
return updatedHeaders;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
// Wrap errors with context
|
|
52
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
53
|
+
throw new Error(`Failed to attach auth credentials: ${message}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Validate that headers is a valid object with string keys and values
|
|
58
|
+
*/
|
|
59
|
+
validateHeaders(headers) {
|
|
60
|
+
if (typeof headers !== "object" || headers === null) {
|
|
61
|
+
throw new Error("headers must be an object");
|
|
62
|
+
}
|
|
63
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
64
|
+
if (typeof key !== "string" || typeof value !== "string") {
|
|
65
|
+
throw new Error(`Invalid header: key and value must be strings (got ${key}: ${typeof value})`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Attach cookies to request headers.
|
|
71
|
+
* In browser environments, cookies are automatically handled by fetch().
|
|
72
|
+
* In Node.js, we need to manually add them to the Cookie header.
|
|
73
|
+
*/
|
|
74
|
+
attachCookies(headers, cookies) {
|
|
75
|
+
// Check if we're in a browser environment
|
|
76
|
+
const isBrowser = this.platformService.isBrowser();
|
|
77
|
+
if (isBrowser) {
|
|
78
|
+
// In browsers, fetch() automatically sends cookies for same-origin requests
|
|
79
|
+
// For cross-origin, the server needs to set CORS headers and credentials: 'include'
|
|
80
|
+
// We can't manually set cookies in headers for security reasons
|
|
81
|
+
// So we just warn if cookies are provided in direct mode
|
|
82
|
+
this.logger.warn("DirectAuth: Cookies are automatically handled by the browser. " +
|
|
83
|
+
"Ensure your server has proper CORS configuration with credentials support.");
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// In Node.js, we can manually build the Cookie header
|
|
87
|
+
const cookieString = Object.entries(cookies)
|
|
88
|
+
.map(([key, value]) => `${key}=${value}`)
|
|
89
|
+
.join("; ");
|
|
90
|
+
if (cookieString) {
|
|
91
|
+
headers.Cookie = cookieString;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { BaseAuthManager } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* No-auth manager - pass-through implementation for backward compatibility.
|
|
4
|
+
*
|
|
5
|
+
* When no auth configuration is provided, this manager is used to maintain
|
|
6
|
+
* a consistent interface without adding any authentication to requests.
|
|
7
|
+
*/
|
|
8
|
+
export declare class NoAuthManager extends BaseAuthManager {
|
|
9
|
+
constructor();
|
|
10
|
+
/**
|
|
11
|
+
* Pass through headers without modification.
|
|
12
|
+
*
|
|
13
|
+
* @param headers - Existing request headers
|
|
14
|
+
* @returns Same headers unchanged
|
|
15
|
+
*/
|
|
16
|
+
attachCredentials(headers?: Record<string, string>): Promise<Record<string, string>>;
|
|
17
|
+
/**
|
|
18
|
+
* No-op for clearing tokens (NoAuthManager doesn't cache anything)
|
|
19
|
+
*/
|
|
20
|
+
clearToken(_jobId: string): void;
|
|
21
|
+
/**
|
|
22
|
+
* No-op for clearing all tokens
|
|
23
|
+
*/
|
|
24
|
+
clearAllTokens(): void;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=no-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-auth.d.ts","sourceRoot":"","sources":["../../src/auth/no-auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C;;;;;GAKG;AACH,qBAAa,aAAc,SAAQ,eAAe;;IAKhD;;;;;OAKG;IACG,iBAAiB,CACrB,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACnC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAIlC;;OAEG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAIhC;;OAEG;IACH,cAAc,IAAI,IAAI;CAGvB"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { BaseAuthManager } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* No-auth manager - pass-through implementation for backward compatibility.
|
|
4
|
+
*
|
|
5
|
+
* When no auth configuration is provided, this manager is used to maintain
|
|
6
|
+
* a consistent interface without adding any authentication to requests.
|
|
7
|
+
*/
|
|
8
|
+
export class NoAuthManager extends BaseAuthManager {
|
|
9
|
+
constructor() {
|
|
10
|
+
super("no-auth");
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Pass through headers without modification.
|
|
14
|
+
*
|
|
15
|
+
* @param headers - Existing request headers
|
|
16
|
+
* @returns Same headers unchanged
|
|
17
|
+
*/
|
|
18
|
+
async attachCredentials(headers = {}) {
|
|
19
|
+
return headers;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* No-op for clearing tokens (NoAuthManager doesn't cache anything)
|
|
23
|
+
*/
|
|
24
|
+
clearToken(_jobId) {
|
|
25
|
+
// No-op
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* No-op for clearing all tokens
|
|
29
|
+
*/
|
|
30
|
+
clearAllTokens() {
|
|
31
|
+
// No-op
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { HttpClient } from "../services/http-client";
|
|
2
|
+
import { BaseAuthManager, type SaasAuthConfig } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Token response from the auth server
|
|
5
|
+
*/
|
|
6
|
+
export type TokenResponse = {
|
|
7
|
+
/** JWT token to use for authentication */
|
|
8
|
+
token: string;
|
|
9
|
+
/** Token expiration time in seconds (optional) */
|
|
10
|
+
expiresIn?: number;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* SaaS auth manager - handles JWT token exchange with an auth server.
|
|
14
|
+
*
|
|
15
|
+
* Token exchange flow:
|
|
16
|
+
* 1. Client calls getCredentials() to get user credentials
|
|
17
|
+
* 2. Manager sends credentials to authServerUrl
|
|
18
|
+
* 3. Auth server validates credentials and returns JWT token
|
|
19
|
+
* 4. Manager caches token and attaches it to uploadista requests
|
|
20
|
+
* 5. Token is cached per job to minimize auth overhead
|
|
21
|
+
*
|
|
22
|
+
* Security: API keys are kept server-side in the auth server, never exposed to clients.
|
|
23
|
+
*/
|
|
24
|
+
export declare class SaasAuthManager extends BaseAuthManager {
|
|
25
|
+
private config;
|
|
26
|
+
private httpClient;
|
|
27
|
+
/** Token cache: maps job ID to cached token */
|
|
28
|
+
private tokenCache;
|
|
29
|
+
/** Global token for requests without a specific job ID */
|
|
30
|
+
private globalToken;
|
|
31
|
+
constructor(config: SaasAuthConfig, httpClient: HttpClient);
|
|
32
|
+
/**
|
|
33
|
+
* Fetch a JWT token from the auth server using user credentials.
|
|
34
|
+
*
|
|
35
|
+
* @returns Token response with JWT and optional expiry
|
|
36
|
+
* @throws Error if auth server is unreachable or returns an error
|
|
37
|
+
*/
|
|
38
|
+
fetchToken(): Promise<TokenResponse>;
|
|
39
|
+
/**
|
|
40
|
+
* Get a cached token for a specific job, or fetch a new one if not cached.
|
|
41
|
+
*
|
|
42
|
+
* @param jobId - Optional job ID to cache token for specific job
|
|
43
|
+
* @returns Cached or newly fetched token
|
|
44
|
+
*/
|
|
45
|
+
private getOrFetchToken;
|
|
46
|
+
/**
|
|
47
|
+
* Check if a cached token is expired.
|
|
48
|
+
* Adds a 60-second buffer to avoid using tokens that are about to expire.
|
|
49
|
+
*/
|
|
50
|
+
private isTokenExpired;
|
|
51
|
+
/**
|
|
52
|
+
* Attach JWT token to an HTTP request as Authorization Bearer header.
|
|
53
|
+
*
|
|
54
|
+
* @param headers - Existing request headers
|
|
55
|
+
* @param jobId - Optional job ID to use cached token for specific job
|
|
56
|
+
* @returns Updated headers with Authorization header
|
|
57
|
+
* @throws Error if token fetch fails
|
|
58
|
+
*/
|
|
59
|
+
attachToken(headers?: Record<string, string>, jobId?: string): Promise<Record<string, string>>;
|
|
60
|
+
/**
|
|
61
|
+
* Clear cached token for a specific job.
|
|
62
|
+
* Should be called when a job completes to free memory.
|
|
63
|
+
*
|
|
64
|
+
* @param jobId - Job ID to clear token for
|
|
65
|
+
*/
|
|
66
|
+
clearToken(jobId: string): void;
|
|
67
|
+
/**
|
|
68
|
+
* Clear all cached tokens.
|
|
69
|
+
* Useful for logout or when switching users.
|
|
70
|
+
*/
|
|
71
|
+
clearAllTokens(): void;
|
|
72
|
+
/**
|
|
73
|
+
* Get cache statistics for debugging and monitoring.
|
|
74
|
+
*/
|
|
75
|
+
getCacheStats(): {
|
|
76
|
+
cachedJobCount: number;
|
|
77
|
+
hasGlobalToken: boolean;
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=saas-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"saas-auth.d.ts","sourceRoot":"","sources":["../../src/auth/saas-auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAE/D;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAUF;;;;;;;;;;;GAWG;AACH,qBAAa,eAAgB,SAAQ,eAAe;IAQhD,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,UAAU;IARpB,+CAA+C;IAC/C,OAAO,CAAC,UAAU,CAAkC;IAEpD,0DAA0D;IAC1D,OAAO,CAAC,WAAW,CAA4B;gBAGrC,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE,UAAU;IAKhC;;;;;OAKG;IACG,UAAU,IAAI,OAAO,CAAC,aAAa,CAAC;IAgD1C;;;;;OAKG;YACW,eAAe;IAqC7B;;;OAGG;IACH,OAAO,CAAC,cAAc;IAWtB;;;;;;;OAOG;IACG,WAAW,CACf,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EACpC,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAgBlC;;;;;OAKG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI/B;;;OAGG;IACH,cAAc,IAAI,IAAI;IAKtB;;OAEG;IACH,aAAa,IAAI;QACf,cAAc,EAAE,MAAM,CAAC;QACvB,cAAc,EAAE,OAAO,CAAC;KACzB;CAMF"}
|