@veritas-lex/contract-analysis-package 1.2.3 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -177
- package/dist/config/storage.config.d.ts +4 -0
- package/dist/config/storage.config.d.ts.map +1 -1
- package/dist/config/storage.config.js +6 -0
- package/dist/config/storage.config.js.map +1 -1
- package/dist/constants/file-validation.constants.d.ts +23 -0
- package/dist/constants/file-validation.constants.d.ts.map +1 -1
- package/dist/constants/file-validation.constants.js +126 -0
- package/dist/constants/file-validation.constants.js.map +1 -1
- package/dist/constants/index.d.ts +1 -1
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/constants/index.js +4 -1
- package/dist/constants/index.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/storage/base-storage.service.d.ts +70 -0
- package/dist/storage/base-storage.service.d.ts.map +1 -0
- package/dist/storage/base-storage.service.js +160 -0
- package/dist/storage/base-storage.service.js.map +1 -0
- package/dist/storage/index.d.ts +2 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +6 -0
- package/dist/storage/index.js.map +1 -0
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -1,181 +1,5 @@
|
|
|
1
|
-
# @ignatg/contract-analysis-package
|
|
2
|
-
|
|
3
|
-
Shared NestJS infrastructure for the Contract Analysis platform. This package extracts duplicated infrastructure code from `contract-analysis-api` and `ai-analysis-api` into a single, versioned package.
|
|
4
|
-
|
|
5
1
|
## Installation
|
|
6
2
|
|
|
7
3
|
```bash
|
|
8
|
-
npm install @
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
Or reference locally during development:
|
|
12
|
-
|
|
13
|
-
```json
|
|
14
|
-
{
|
|
15
|
-
"dependencies": {
|
|
16
|
-
"@ignatg/contract-analysis-package": "^1.0.0",
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## What's Included
|
|
22
|
-
|
|
23
|
-
| Module | Exports | Description |
|
|
24
|
-
|--------|---------|-------------|
|
|
25
|
-
| **Auth** | `JwtAuthGuard`, `BaseJwtStrategy`, `AuthCoreModule`, `CurrentUser`, `Public` | JWT authentication with Supabase JWKS support |
|
|
26
|
-
| **Config** | `createAppConfig`, `createDatabaseConfig`, `createDocConfig`, `createJwtConfig`, `createLoggingConfig`, `createSecurityConfig`, `buildPinoParams`, `RedisConfig`, `StorageConfig` | Parameterised config factories |
|
|
27
|
-
| **Constants** | `CRITICAL_PII_TYPES`, `HIGH_RISK_PII_TYPES`, `STANDARD_PII_TYPES`, `CONTEXTUAL_ENTITIES`, `ContractStatus`, `JobType`, `JobStatus`, `TaskStatus`, `TaskPriority`, `RiskLevel`, `RuleKind`, `RuleDirection` | PII classification + workflow enums |
|
|
28
|
-
| **Database** | `DatabaseModule`, `BaseEntity`, `RedisModule`, `RedisProvider` | TypeORM + BullMQ infrastructure |
|
|
29
|
-
| **DTO** | `ApiResponseDto` | Standard API response wrapper |
|
|
30
|
-
| **Filters** | `AllExceptionsFilter` | Global exception filter |
|
|
31
|
-
| **Helpers** | `TransformInterceptor` | Response transformation interceptor |
|
|
32
|
-
| **Swagger** | `SwaggerDocs` | Swagger/OpenAPI documentation setup |
|
|
33
|
-
| **Bootstrap** | `configureApp` | Shared application bootstrap helper |
|
|
34
|
-
|
|
35
|
-
## Usage
|
|
36
|
-
|
|
37
|
-
### Config Factories
|
|
38
|
-
|
|
39
|
-
Each API calls factory functions with its own defaults:
|
|
40
|
-
|
|
41
|
-
```typescript
|
|
42
|
-
// config/index.ts
|
|
43
|
-
import {
|
|
44
|
-
createAppConfig,
|
|
45
|
-
createDatabaseConfig,
|
|
46
|
-
createDocConfig,
|
|
47
|
-
createJwtConfig,
|
|
48
|
-
createLoggingConfig,
|
|
49
|
-
createSecurityConfig,
|
|
50
|
-
RedisConfig,
|
|
51
|
-
StorageConfig,
|
|
52
|
-
} from '@ignatg/contract-analysis-package';
|
|
53
|
-
|
|
54
|
-
const AppConfig = createAppConfig({
|
|
55
|
-
name: 'My API',
|
|
56
|
-
port: 3000,
|
|
57
|
-
corsOrigins: 'http://localhost:3333',
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
const DatabaseConfig = createDatabaseConfig({
|
|
61
|
-
defaultDbName: 'mydb',
|
|
62
|
-
defaultPoolMax: 20,
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
const DocConfig = createDocConfig({
|
|
66
|
-
name: 'My API Specification',
|
|
67
|
-
description: 'API documentation',
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
const JwtConfig = createJwtConfig({ strict: true });
|
|
71
|
-
const LoggingConfig = createLoggingConfig({ defaultLevel: 'debug' });
|
|
72
|
-
const SecurityConfig = createSecurityConfig({ includeEncryptionKey: true });
|
|
73
|
-
|
|
74
|
-
export default [
|
|
75
|
-
AppConfig,
|
|
76
|
-
DatabaseConfig,
|
|
77
|
-
DocConfig,
|
|
78
|
-
JwtConfig,
|
|
79
|
-
LoggingConfig,
|
|
80
|
-
SecurityConfig,
|
|
81
|
-
RedisConfig,
|
|
82
|
-
StorageConfig,
|
|
83
|
-
];
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
### Auth Module
|
|
87
|
-
|
|
88
|
-
Extend `BaseJwtStrategy` with your custom `validate()` logic:
|
|
89
|
-
|
|
90
|
-
```typescript
|
|
91
|
-
import { Injectable } from '@nestjs/common';
|
|
92
|
-
import { ConfigService } from '@nestjs/config';
|
|
93
|
-
import { BaseJwtStrategy, JwtPayload } from '@ignatg/contract-analysis-package';
|
|
94
|
-
|
|
95
|
-
@Injectable()
|
|
96
|
-
export class JwtStrategy extends BaseJwtStrategy {
|
|
97
|
-
constructor(configService: ConfigService) {
|
|
98
|
-
super(configService);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
validate(payload: JwtPayload) {
|
|
102
|
-
this.validateCorePayload(payload);
|
|
103
|
-
return {
|
|
104
|
-
userId: payload.sub,
|
|
105
|
-
email: payload.email || '',
|
|
106
|
-
role: payload.role || 'user',
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
### Bootstrap Helper
|
|
113
|
-
|
|
114
|
-
Simplify your `main.ts`:
|
|
115
|
-
|
|
116
|
-
```typescript
|
|
117
|
-
import { NestFactory, NestApplication } from '@nestjs/core';
|
|
118
|
-
import { ConfigService } from '@nestjs/config';
|
|
119
|
-
import { Logger } from 'nestjs-pino';
|
|
120
|
-
import { configureApp } from '@ignatg/contract-analysis-package';
|
|
121
|
-
import { MainModule } from './main.module';
|
|
122
|
-
|
|
123
|
-
async function bootstrap() {
|
|
124
|
-
const app = await NestFactory.create<NestApplication>(MainModule, { bufferLogs: true });
|
|
125
|
-
await configureApp(app);
|
|
126
|
-
|
|
127
|
-
const configService = app.get(ConfigService);
|
|
128
|
-
const port = configService.get<number>('app.port');
|
|
129
|
-
const logger = app.get(Logger);
|
|
130
|
-
logger.log(`Main app will serve on PORT ${port}`, 'MainApplication');
|
|
131
|
-
await app.listen(port);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
bootstrap();
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### Database Module
|
|
138
|
-
|
|
139
|
-
```typescript
|
|
140
|
-
import { Module } from '@nestjs/common';
|
|
141
|
-
import { DatabaseModule } from '@ignatg/contract-analysis-package';
|
|
142
|
-
|
|
143
|
-
@Module({
|
|
144
|
-
imports: [DatabaseModule.register()],
|
|
145
|
-
})
|
|
146
|
-
export class MainModule {}
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
### Shared Enums
|
|
150
|
-
|
|
151
|
-
```typescript
|
|
152
|
-
import { ContractStatus, JobStatus, RiskLevel } from '@ignatg/contract-analysis-package';
|
|
153
|
-
|
|
154
|
-
// Use in entity files (re-export pattern)
|
|
155
|
-
export { ContractStatus } from '@ignatg/contract-analysis-package';
|
|
156
|
-
|
|
157
|
-
// Use in services
|
|
158
|
-
if (contract.status === ContractStatus.READY) { ... }
|
|
159
|
-
if (job.status === JobStatus.QUEUED) { ... }
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
Available enums: `ContractStatus`, `JobType`, `JobStatus`, `TaskStatus`, `TaskPriority`, `RiskLevel`, `RuleKind`, `RuleDirection`
|
|
163
|
-
|
|
164
|
-
## Peer Dependencies
|
|
165
|
-
|
|
166
|
-
This package declares all NestJS ecosystem packages as `peerDependencies` to avoid version conflicts. Your consuming application must have them installed.
|
|
167
|
-
|
|
168
|
-
## Building
|
|
169
|
-
|
|
170
|
-
```bash
|
|
171
|
-
npm run build # Compiles TypeScript to dist/
|
|
172
|
-
npm run clean # Removes dist/
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
## Publishing
|
|
176
|
-
|
|
177
|
-
Configured for GitHub Packages:
|
|
178
|
-
|
|
179
|
-
```bash
|
|
180
|
-
npm publish
|
|
4
|
+
npm install @veritas-lex/contract-analysis-package
|
|
181
5
|
```
|
|
@@ -7,6 +7,8 @@ declare const _default: (() => {
|
|
|
7
7
|
key: string | undefined;
|
|
8
8
|
bucket: string;
|
|
9
9
|
signedUrlExpiry: number;
|
|
10
|
+
uploadUrlExpiry: number;
|
|
11
|
+
downloadUrlExpiry: number;
|
|
10
12
|
};
|
|
11
13
|
}) & import("@nestjs/config").ConfigFactoryKeyHost<{
|
|
12
14
|
supabase: {
|
|
@@ -14,6 +16,8 @@ declare const _default: (() => {
|
|
|
14
16
|
key: string | undefined;
|
|
15
17
|
bucket: string;
|
|
16
18
|
signedUrlExpiry: number;
|
|
19
|
+
uploadUrlExpiry: number;
|
|
20
|
+
downloadUrlExpiry: number;
|
|
17
21
|
};
|
|
18
22
|
}>;
|
|
19
23
|
export default _default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.config.d.ts","sourceRoot":"","sources":["../../src/config/storage.config.ts"],"names":[],"mappings":"AAEA;;GAEG
|
|
1
|
+
{"version":3,"file":"storage.config.d.ts","sourceRoot":"","sources":["../../src/config/storage.config.ts"],"names":[],"mappings":"AAEA;;GAEG;;;;;;;;;;;;;;;;;;;;AACH,wBAeI"}
|
|
@@ -11,6 +11,12 @@ exports.default = (0, config_1.registerAs)("storage", () => ({
|
|
|
11
11
|
bucket: process.env.SUPABASE_STORAGE_BUCKET || "contracts",
|
|
12
12
|
signedUrlExpiry: process.env.SUPABASE_SIGNED_URL_EXPIRY
|
|
13
13
|
? parseInt(process.env.SUPABASE_SIGNED_URL_EXPIRY, 10)
|
|
14
|
+
: 3600, // Default to 1 hour (backward compat)
|
|
15
|
+
uploadUrlExpiry: process.env.SUPABASE_UPLOAD_URL_EXPIRY
|
|
16
|
+
? parseInt(process.env.SUPABASE_UPLOAD_URL_EXPIRY, 10)
|
|
17
|
+
: 600, // Default to 10 minutes — uploads should be short-lived
|
|
18
|
+
downloadUrlExpiry: process.env.SUPABASE_DOWNLOAD_URL_EXPIRY
|
|
19
|
+
? parseInt(process.env.SUPABASE_DOWNLOAD_URL_EXPIRY, 10)
|
|
14
20
|
: 3600, // Default to 1 hour
|
|
15
21
|
},
|
|
16
22
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.config.js","sourceRoot":"","sources":["../../src/config/storage.config.ts"],"names":[],"mappings":";;AAAA,2CAA4C;AAE5C;;GAEG;AACH,kBAAe,IAAA,mBAAU,EAAC,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;IAC1C,QAAQ,EAAE;QACR,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;QAC7B,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,yBAAyB;QAC1C,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,WAAW;QAC1D,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,0BAA0B;YACrD,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,EAAE,CAAC;YACtD,CAAC,CAAC,IAAI,EAAE,oBAAoB;KAC/B;CACF,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"storage.config.js","sourceRoot":"","sources":["../../src/config/storage.config.ts"],"names":[],"mappings":";;AAAA,2CAA4C;AAE5C;;GAEG;AACH,kBAAe,IAAA,mBAAU,EAAC,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;IAC1C,QAAQ,EAAE;QACR,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;QAC7B,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,yBAAyB;QAC1C,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,WAAW;QAC1D,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,0BAA0B;YACrD,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,EAAE,CAAC;YACtD,CAAC,CAAC,IAAI,EAAE,sCAAsC;QAChD,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,0BAA0B;YACrD,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,EAAE,CAAC;YACtD,CAAC,CAAC,GAAG,EAAE,wDAAwD;QACjE,iBAAiB,EAAE,OAAO,CAAC,GAAG,CAAC,4BAA4B;YACzD,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,EAAE,CAAC;YACxD,CAAC,CAAC,IAAI,EAAE,oBAAoB;KAC/B;CACF,CAAC,CAAC,CAAC"}
|
|
@@ -25,4 +25,27 @@ export declare const MIME_TO_EXTENSIONS: Record<AllowedMimeType, string[]>;
|
|
|
25
25
|
* @returns `null` if valid, or a human-readable error string if mismatched.
|
|
26
26
|
*/
|
|
27
27
|
export declare function validateExtensionMimeMatch(filename: string, mimeType: string): string | null;
|
|
28
|
+
/**
|
|
29
|
+
* Detect MIME type from the magic bytes of a file buffer.
|
|
30
|
+
* Returns only types from the {@link AllowedMimeType} union (for upload validation).
|
|
31
|
+
*
|
|
32
|
+
* @param buffer - First 4-16 bytes of the file (only the head is needed)
|
|
33
|
+
* @returns The detected allowed MIME type, or `null` if unrecognised.
|
|
34
|
+
*/
|
|
35
|
+
export declare function detectMimeFromMagicBytes(buffer: Buffer): AllowedMimeType | null;
|
|
36
|
+
/**
|
|
37
|
+
* Detect MIME type from buffer magic bytes (general purpose).
|
|
38
|
+
* Supports all known formats including image types used by OCR (WebP, GIF, BMP).
|
|
39
|
+
* Falls back to `'application/pdf'` if detection fails.
|
|
40
|
+
*
|
|
41
|
+
* @param buffer - Raw file or page buffer
|
|
42
|
+
* @returns The detected MIME type string, never null.
|
|
43
|
+
*/
|
|
44
|
+
export declare function detectMimeType(buffer: Buffer): string;
|
|
45
|
+
/**
|
|
46
|
+
* Validate that a file's magic bytes are compatible with the declared MIME type.
|
|
47
|
+
*
|
|
48
|
+
* @returns `null` if valid, or a human-readable error string if mismatched.
|
|
49
|
+
*/
|
|
50
|
+
export declare function validateMagicBytes(buffer: Buffer, declaredMimeType: string): string | null;
|
|
28
51
|
//# sourceMappingURL=file-validation.constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-validation.constants.d.ts","sourceRoot":"","sources":["../../src/constants/file-validation.constants.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,4EAA4E;AAC5E,eAAO,MAAM,qBAAqB,YAAc,CAAC;AAEjD,uDAAuD;AACvD,eAAO,MAAM,kBAAkB,wKAOrB,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAElE;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,EAAE,CAW/D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,EAAE,CAa7D,CAAC;AAEL;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,IAAI,CAmBf"}
|
|
1
|
+
{"version":3,"file":"file-validation.constants.d.ts","sourceRoot":"","sources":["../../src/constants/file-validation.constants.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,4EAA4E;AAC5E,eAAO,MAAM,qBAAqB,YAAc,CAAC;AAEjD,uDAAuD;AACvD,eAAO,MAAM,kBAAkB,wKAOrB,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAElE;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,EAAE,CAW/D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,EAAE,CAa7D,CAAC;AAEL;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,IAAI,CAmBf;AAsGD;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,GACb,eAAe,GAAG,IAAI,CAUxB;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAUrD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,MAAM,GACvB,MAAM,GAAG,IAAI,CAsBf"}
|
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.MIME_TO_EXTENSIONS = exports.EXTENSION_TO_MIME = exports.ALLOWED_MIME_TYPES = exports.MAX_UPLOAD_SIZE_BYTES = void 0;
|
|
11
11
|
exports.validateExtensionMimeMatch = validateExtensionMimeMatch;
|
|
12
|
+
exports.detectMimeFromMagicBytes = detectMimeFromMagicBytes;
|
|
13
|
+
exports.detectMimeType = detectMimeType;
|
|
14
|
+
exports.validateMagicBytes = validateMagicBytes;
|
|
12
15
|
/** Maximum upload size in bytes (100 MB — matches Supabase bucket limit) */
|
|
13
16
|
exports.MAX_UPLOAD_SIZE_BYTES = 104_857_600;
|
|
14
17
|
/** Allowed MIME types for contract document uploads */
|
|
@@ -78,4 +81,127 @@ function getFileExtension(filename) {
|
|
|
78
81
|
const match = filename.match(/\.[a-zA-Z0-9]+$/);
|
|
79
82
|
return match ? match[0].toLowerCase() : null;
|
|
80
83
|
}
|
|
84
|
+
const MAGIC_BYTE_SIGNATURES = [
|
|
85
|
+
// PDF: %PDF
|
|
86
|
+
{
|
|
87
|
+
check: (buf) => buf[0] === 0x25 && buf[1] === 0x50 && buf[2] === 0x44 && buf[3] === 0x46,
|
|
88
|
+
uploadMimes: ["application/pdf"],
|
|
89
|
+
detectedMime: "application/pdf",
|
|
90
|
+
},
|
|
91
|
+
// PNG: 0x89 PNG
|
|
92
|
+
{
|
|
93
|
+
check: (buf) => buf[0] === 0x89 && buf[1] === 0x50 && buf[2] === 0x4e && buf[3] === 0x47,
|
|
94
|
+
uploadMimes: ["image/png"],
|
|
95
|
+
detectedMime: "image/png",
|
|
96
|
+
},
|
|
97
|
+
// JPEG: 0xFF 0xD8
|
|
98
|
+
{
|
|
99
|
+
check: (buf) => buf[0] === 0xff && buf[1] === 0xd8,
|
|
100
|
+
uploadMimes: ["image/jpeg"],
|
|
101
|
+
detectedMime: "image/jpeg",
|
|
102
|
+
},
|
|
103
|
+
// TIFF: II (little-endian) or MM (big-endian)
|
|
104
|
+
{
|
|
105
|
+
check: (buf) => (buf[0] === 0x49 && buf[1] === 0x49) ||
|
|
106
|
+
(buf[0] === 0x4d && buf[1] === 0x4d),
|
|
107
|
+
uploadMimes: ["image/tiff"],
|
|
108
|
+
detectedMime: "image/tiff",
|
|
109
|
+
},
|
|
110
|
+
// WebP: RIFF....WEBP
|
|
111
|
+
{
|
|
112
|
+
check: (buf) => buf.length > 11 &&
|
|
113
|
+
buf[0] === 0x52 &&
|
|
114
|
+
buf[1] === 0x49 &&
|
|
115
|
+
buf[2] === 0x46 &&
|
|
116
|
+
buf[3] === 0x46 &&
|
|
117
|
+
buf[8] === 0x57 &&
|
|
118
|
+
buf[9] === 0x45 &&
|
|
119
|
+
buf[10] === 0x42 &&
|
|
120
|
+
buf[11] === 0x50,
|
|
121
|
+
uploadMimes: [],
|
|
122
|
+
detectedMime: "image/webp",
|
|
123
|
+
},
|
|
124
|
+
// GIF: GIF8
|
|
125
|
+
{
|
|
126
|
+
check: (buf) => buf[0] === 0x47 && buf[1] === 0x49 && buf[2] === 0x46 && buf[3] === 0x38,
|
|
127
|
+
uploadMimes: [],
|
|
128
|
+
detectedMime: "image/gif",
|
|
129
|
+
},
|
|
130
|
+
// BMP: BM
|
|
131
|
+
{
|
|
132
|
+
check: (buf) => buf[0] === 0x42 && buf[1] === 0x4d,
|
|
133
|
+
uploadMimes: [],
|
|
134
|
+
detectedMime: "image/bmp",
|
|
135
|
+
},
|
|
136
|
+
// ZIP-based Office documents (DOCX, XLSX, PPTX): PK signature
|
|
137
|
+
{
|
|
138
|
+
check: (buf) => buf[0] === 0x50 && buf[1] === 0x4b,
|
|
139
|
+
uploadMimes: [
|
|
140
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
141
|
+
"application/msword",
|
|
142
|
+
],
|
|
143
|
+
detectedMime: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
144
|
+
},
|
|
145
|
+
// Legacy MS Office compound binary (DOC, XLS, PPT): D0 CF 11 E0
|
|
146
|
+
{
|
|
147
|
+
check: (buf) => buf[0] === 0xd0 && buf[1] === 0xcf && buf[2] === 0x11 && buf[3] === 0xe0,
|
|
148
|
+
uploadMimes: ["application/msword"],
|
|
149
|
+
detectedMime: "application/msword",
|
|
150
|
+
},
|
|
151
|
+
];
|
|
152
|
+
/**
|
|
153
|
+
* Detect MIME type from the magic bytes of a file buffer.
|
|
154
|
+
* Returns only types from the {@link AllowedMimeType} union (for upload validation).
|
|
155
|
+
*
|
|
156
|
+
* @param buffer - First 4-16 bytes of the file (only the head is needed)
|
|
157
|
+
* @returns The detected allowed MIME type, or `null` if unrecognised.
|
|
158
|
+
*/
|
|
159
|
+
function detectMimeFromMagicBytes(buffer) {
|
|
160
|
+
if (!buffer || buffer.length < 2)
|
|
161
|
+
return null;
|
|
162
|
+
for (const sig of MAGIC_BYTE_SIGNATURES) {
|
|
163
|
+
if (sig.check(buffer) && sig.uploadMimes.length > 0) {
|
|
164
|
+
return sig.uploadMimes[0];
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Detect MIME type from buffer magic bytes (general purpose).
|
|
171
|
+
* Supports all known formats including image types used by OCR (WebP, GIF, BMP).
|
|
172
|
+
* Falls back to `'application/pdf'` if detection fails.
|
|
173
|
+
*
|
|
174
|
+
* @param buffer - Raw file or page buffer
|
|
175
|
+
* @returns The detected MIME type string, never null.
|
|
176
|
+
*/
|
|
177
|
+
function detectMimeType(buffer) {
|
|
178
|
+
if (!buffer || buffer.length < 2)
|
|
179
|
+
return "application/pdf";
|
|
180
|
+
for (const sig of MAGIC_BYTE_SIGNATURES) {
|
|
181
|
+
if (sig.check(buffer)) {
|
|
182
|
+
return sig.detectedMime;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return "application/pdf";
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Validate that a file's magic bytes are compatible with the declared MIME type.
|
|
189
|
+
*
|
|
190
|
+
* @returns `null` if valid, or a human-readable error string if mismatched.
|
|
191
|
+
*/
|
|
192
|
+
function validateMagicBytes(buffer, declaredMimeType) {
|
|
193
|
+
const detectedMime = detectMimeFromMagicBytes(buffer);
|
|
194
|
+
if (!detectedMime) {
|
|
195
|
+
return `Unable to determine file type from content. The uploaded file may be corrupted or unsupported.`;
|
|
196
|
+
}
|
|
197
|
+
// Find all upload MIME types that share the same magic byte signature
|
|
198
|
+
const matchedSignature = MAGIC_BYTE_SIGNATURES.find((sig) => sig.check(buffer));
|
|
199
|
+
const compatibleMimes = matchedSignature?.uploadMimes ?? [detectedMime];
|
|
200
|
+
if (!compatibleMimes.includes(declaredMimeType)) {
|
|
201
|
+
return (`File content does not match declared type "${declaredMimeType}". ` +
|
|
202
|
+
`Detected content type: "${detectedMime}". ` +
|
|
203
|
+
`Please ensure you are uploading the correct file.`);
|
|
204
|
+
}
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
81
207
|
//# sourceMappingURL=file-validation.constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-validation.constants.js","sourceRoot":"","sources":["../../src/constants/file-validation.constants.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAyDH,gEAsBC;
|
|
1
|
+
{"version":3,"file":"file-validation.constants.js","sourceRoot":"","sources":["../../src/constants/file-validation.constants.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { CRITICAL_PII_TYPES, HIGH_RISK_PII_TYPES, CONTEXTUAL_ENTITIES, STANDARD_PII_TYPES, ALL_MASKABLE_PII_TYPES, APPROVAL_REQUIRED_PII_TYPES, } from "./pii-classifications.constants";
|
|
2
2
|
export type { PiiRiskLevel } from "./pii-classifications.constants";
|
|
3
|
-
export { MAX_UPLOAD_SIZE_BYTES, ALLOWED_MIME_TYPES, EXTENSION_TO_MIME, MIME_TO_EXTENSIONS, validateExtensionMimeMatch, } from "./file-validation.constants";
|
|
3
|
+
export { MAX_UPLOAD_SIZE_BYTES, ALLOWED_MIME_TYPES, EXTENSION_TO_MIME, MIME_TO_EXTENSIONS, validateExtensionMimeMatch, detectMimeFromMagicBytes, detectMimeType, validateMagicBytes, } from "./file-validation.constants";
|
|
4
4
|
export type { AllowedMimeType } from "./file-validation.constants";
|
|
5
5
|
export { ContractStatus, JobType, JobStatus, TaskStatus, TaskPriority, RiskLevel, RuleKind, RuleDirection, } from "./enums";
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,2BAA2B,GAC5B,MAAM,iCAAiC,CAAC;AACzC,YAAY,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAEpE,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,0BAA0B,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,2BAA2B,GAC5B,MAAM,iCAAiC,CAAC;AACzC,YAAY,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAEpE,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,0BAA0B,EAC1B,wBAAwB,EACxB,cAAc,EACd,kBAAkB,GACnB,MAAM,6BAA6B,CAAC;AACrC,YAAY,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEnE,OAAO,EACL,cAAc,EACd,OAAO,EACP,SAAS,EACT,UAAU,EACV,YAAY,EACZ,SAAS,EACT,QAAQ,EACR,aAAa,GACd,MAAM,SAAS,CAAC"}
|
package/dist/constants/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RuleDirection = exports.RuleKind = exports.RiskLevel = exports.TaskPriority = exports.TaskStatus = exports.JobStatus = exports.JobType = exports.ContractStatus = exports.validateExtensionMimeMatch = exports.MIME_TO_EXTENSIONS = exports.EXTENSION_TO_MIME = exports.ALLOWED_MIME_TYPES = exports.MAX_UPLOAD_SIZE_BYTES = exports.APPROVAL_REQUIRED_PII_TYPES = exports.ALL_MASKABLE_PII_TYPES = exports.STANDARD_PII_TYPES = exports.CONTEXTUAL_ENTITIES = exports.HIGH_RISK_PII_TYPES = exports.CRITICAL_PII_TYPES = void 0;
|
|
3
|
+
exports.RuleDirection = exports.RuleKind = exports.RiskLevel = exports.TaskPriority = exports.TaskStatus = exports.JobStatus = exports.JobType = exports.ContractStatus = exports.validateMagicBytes = exports.detectMimeType = exports.detectMimeFromMagicBytes = exports.validateExtensionMimeMatch = exports.MIME_TO_EXTENSIONS = exports.EXTENSION_TO_MIME = exports.ALLOWED_MIME_TYPES = exports.MAX_UPLOAD_SIZE_BYTES = exports.APPROVAL_REQUIRED_PII_TYPES = exports.ALL_MASKABLE_PII_TYPES = exports.STANDARD_PII_TYPES = exports.CONTEXTUAL_ENTITIES = exports.HIGH_RISK_PII_TYPES = exports.CRITICAL_PII_TYPES = void 0;
|
|
4
4
|
var pii_classifications_constants_1 = require("./pii-classifications.constants");
|
|
5
5
|
Object.defineProperty(exports, "CRITICAL_PII_TYPES", { enumerable: true, get: function () { return pii_classifications_constants_1.CRITICAL_PII_TYPES; } });
|
|
6
6
|
Object.defineProperty(exports, "HIGH_RISK_PII_TYPES", { enumerable: true, get: function () { return pii_classifications_constants_1.HIGH_RISK_PII_TYPES; } });
|
|
@@ -14,6 +14,9 @@ Object.defineProperty(exports, "ALLOWED_MIME_TYPES", { enumerable: true, get: fu
|
|
|
14
14
|
Object.defineProperty(exports, "EXTENSION_TO_MIME", { enumerable: true, get: function () { return file_validation_constants_1.EXTENSION_TO_MIME; } });
|
|
15
15
|
Object.defineProperty(exports, "MIME_TO_EXTENSIONS", { enumerable: true, get: function () { return file_validation_constants_1.MIME_TO_EXTENSIONS; } });
|
|
16
16
|
Object.defineProperty(exports, "validateExtensionMimeMatch", { enumerable: true, get: function () { return file_validation_constants_1.validateExtensionMimeMatch; } });
|
|
17
|
+
Object.defineProperty(exports, "detectMimeFromMagicBytes", { enumerable: true, get: function () { return file_validation_constants_1.detectMimeFromMagicBytes; } });
|
|
18
|
+
Object.defineProperty(exports, "detectMimeType", { enumerable: true, get: function () { return file_validation_constants_1.detectMimeType; } });
|
|
19
|
+
Object.defineProperty(exports, "validateMagicBytes", { enumerable: true, get: function () { return file_validation_constants_1.validateMagicBytes; } });
|
|
17
20
|
var enums_1 = require("./enums");
|
|
18
21
|
Object.defineProperty(exports, "ContractStatus", { enumerable: true, get: function () { return enums_1.ContractStatus; } });
|
|
19
22
|
Object.defineProperty(exports, "JobType", { enumerable: true, get: function () { return enums_1.JobType; } });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":";;;AAAA,iFAOyC;AANvC,mIAAA,kBAAkB,OAAA;AAClB,oIAAA,mBAAmB,OAAA;AACnB,oIAAA,mBAAmB,OAAA;AACnB,mIAAA,kBAAkB,OAAA;AAClB,uIAAA,sBAAsB,OAAA;AACtB,4IAAA,2BAA2B,OAAA;AAI7B,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":";;;AAAA,iFAOyC;AANvC,mIAAA,kBAAkB,OAAA;AAClB,oIAAA,mBAAmB,OAAA;AACnB,oIAAA,mBAAmB,OAAA;AACnB,mIAAA,kBAAkB,OAAA;AAClB,uIAAA,sBAAsB,OAAA;AACtB,4IAAA,2BAA2B,OAAA;AAI7B,yEASqC;AARnC,kIAAA,qBAAqB,OAAA;AACrB,+HAAA,kBAAkB,OAAA;AAClB,8HAAA,iBAAiB,OAAA;AACjB,+HAAA,kBAAkB,OAAA;AAClB,uIAAA,0BAA0B,OAAA;AAC1B,qIAAA,wBAAwB,OAAA;AACxB,2HAAA,cAAc,OAAA;AACd,+HAAA,kBAAkB,OAAA;AAIpB,iCASiB;AARf,uGAAA,cAAc,OAAA;AACd,gGAAA,OAAO,OAAA;AACP,kGAAA,SAAS,OAAA;AACT,mGAAA,UAAU,OAAA;AACV,qGAAA,YAAY,OAAA;AACZ,kGAAA,SAAS,OAAA;AACT,iGAAA,QAAQ,OAAA;AACR,sGAAA,aAAa,OAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export { CurrentUser, IS_PUBLIC_KEY, Public, JwtAuthGuard, BaseJwtStrategy, Auth
|
|
|
2
2
|
export type { JwtPayload } from "./auth";
|
|
3
3
|
export { createAppConfig, createDatabaseConfig, createDocConfig, createJwtConfig, createLoggingConfig, createSecurityConfig, buildPinoParams, RedisConfig, StorageConfig, createBaseValidationRules, } from "./config";
|
|
4
4
|
export type { AppConfigOptions, DatabaseConfigOptions, DocConfigOptions, JwtConfigOptions, LoggingConfigOptions, SecurityConfigOptions, BaseValidationOptions, } from "./config";
|
|
5
|
-
export { CRITICAL_PII_TYPES, HIGH_RISK_PII_TYPES, CONTEXTUAL_ENTITIES, STANDARD_PII_TYPES, ALL_MASKABLE_PII_TYPES, APPROVAL_REQUIRED_PII_TYPES, ContractStatus, JobType, JobStatus, TaskStatus, TaskPriority, RiskLevel, RuleKind, RuleDirection, MAX_UPLOAD_SIZE_BYTES, ALLOWED_MIME_TYPES, EXTENSION_TO_MIME, MIME_TO_EXTENSIONS, validateExtensionMimeMatch, } from "./constants";
|
|
5
|
+
export { CRITICAL_PII_TYPES, HIGH_RISK_PII_TYPES, CONTEXTUAL_ENTITIES, STANDARD_PII_TYPES, ALL_MASKABLE_PII_TYPES, APPROVAL_REQUIRED_PII_TYPES, ContractStatus, JobType, JobStatus, TaskStatus, TaskPriority, RiskLevel, RuleKind, RuleDirection, MAX_UPLOAD_SIZE_BYTES, ALLOWED_MIME_TYPES, EXTENSION_TO_MIME, MIME_TO_EXTENSIONS, validateExtensionMimeMatch, detectMimeFromMagicBytes, detectMimeType, validateMagicBytes, } from "./constants";
|
|
6
6
|
export type { PiiRiskLevel, AllowedMimeType } from "./constants";
|
|
7
7
|
export { UserTier } from "./database";
|
|
8
8
|
export { BaseEntity, DatabaseModule, RedisModule, RedisProvider, BaseUsersProfileEntity, BaseContractEntity, PiiEntity, BaseJobEntity, BaseContractTextEntity, BaseContractChunkEntity, BaseContractRedFlagEntity, BaseContractPiiReplacementEntity, BaseContractTaskEntity, BaseContractKeyDateRuleEntity, BaseContractEventEntity, BaseAuditLogEntity, BaseQnaQuestionEntity, BaseScoringCriteriaEntity, QnaQuestionTemplate, QnaResponse, } from "./database";
|
|
@@ -14,4 +14,6 @@ export { SwaggerDocs } from "./swagger";
|
|
|
14
14
|
export { configureApp } from "./bootstrap";
|
|
15
15
|
export type { AppBootstrapOptions } from "./bootstrap";
|
|
16
16
|
export { CryptoService } from "./helpers";
|
|
17
|
+
export { BaseSupabaseStorageService } from "./storage";
|
|
18
|
+
export type { DownloadUrlResult, StorageMetadata } from "./storage";
|
|
17
19
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,aAAa,EACb,MAAM,EACN,YAAY,EACZ,eAAe,EACf,cAAc,GACf,MAAM,QAAQ,CAAC;AAChB,YAAY,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAGzC,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,WAAW,EACX,aAAa,EACb,yBAAyB,GAC1B,MAAM,UAAU,CAAC;AAClB,YAAY,EACV,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,2BAA2B,EAC3B,cAAc,EACd,OAAO,EACP,SAAS,EACT,UAAU,EACV,YAAY,EACZ,SAAS,EACT,QAAQ,EACR,aAAa,EACb,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,0BAA0B,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,aAAa,EACb,MAAM,EACN,YAAY,EACZ,eAAe,EACf,cAAc,GACf,MAAM,QAAQ,CAAC;AAChB,YAAY,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAGzC,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,WAAW,EACX,aAAa,EACb,yBAAyB,GAC1B,MAAM,UAAU,CAAC;AAClB,YAAY,EACV,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,2BAA2B,EAC3B,cAAc,EACd,OAAO,EACP,SAAS,EACT,UAAU,EACV,YAAY,EACZ,SAAS,EACT,QAAQ,EACR,aAAa,EACb,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,0BAA0B,EAC1B,wBAAwB,EACxB,cAAc,EACd,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC,OAAO,EACL,UAAU,EACV,cAAc,EACd,WAAW,EACX,aAAa,EAEb,sBAAsB,EACtB,kBAAkB,EAClB,SAAS,EACT,aAAa,EACb,sBAAsB,EACtB,uBAAuB,EACvB,yBAAyB,EACzB,gCAAgC,EAChC,sBAAsB,EACtB,6BAA6B,EAC7B,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,yBAAyB,EAEzB,mBAAmB,EACnB,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAGxD,OAAO,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG/C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAGxC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGvD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG1C,OAAO,EAAE,0BAA0B,EAAE,MAAM,WAAW,CAAC;AACvD,YAAY,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.CryptoService = exports.configureApp = exports.SwaggerDocs = exports.AllExceptionsFilter = exports.ApiResponseDto = exports.QnaResponse = exports.QnaQuestionTemplate = exports.BaseScoringCriteriaEntity = exports.BaseQnaQuestionEntity = exports.BaseAuditLogEntity = void 0;
|
|
3
|
+
exports.BaseContractPiiReplacementEntity = exports.BaseContractRedFlagEntity = exports.BaseContractChunkEntity = exports.BaseContractTextEntity = exports.BaseJobEntity = exports.BaseContractEntity = exports.BaseUsersProfileEntity = exports.RedisProvider = exports.RedisModule = exports.DatabaseModule = exports.BaseEntity = exports.UserTier = exports.validateMagicBytes = exports.detectMimeType = exports.detectMimeFromMagicBytes = exports.validateExtensionMimeMatch = exports.MIME_TO_EXTENSIONS = exports.EXTENSION_TO_MIME = exports.ALLOWED_MIME_TYPES = exports.MAX_UPLOAD_SIZE_BYTES = exports.RuleDirection = exports.RuleKind = exports.RiskLevel = exports.TaskPriority = exports.TaskStatus = exports.JobStatus = exports.JobType = exports.ContractStatus = exports.APPROVAL_REQUIRED_PII_TYPES = exports.ALL_MASKABLE_PII_TYPES = exports.STANDARD_PII_TYPES = exports.CONTEXTUAL_ENTITIES = exports.HIGH_RISK_PII_TYPES = exports.CRITICAL_PII_TYPES = exports.createBaseValidationRules = exports.StorageConfig = exports.RedisConfig = exports.buildPinoParams = exports.createSecurityConfig = exports.createLoggingConfig = exports.createJwtConfig = exports.createDocConfig = exports.createDatabaseConfig = exports.createAppConfig = exports.AuthCoreModule = exports.BaseJwtStrategy = exports.JwtAuthGuard = exports.Public = exports.IS_PUBLIC_KEY = exports.CurrentUser = void 0;
|
|
4
|
+
exports.BaseSupabaseStorageService = exports.CryptoService = exports.configureApp = exports.SwaggerDocs = exports.AllExceptionsFilter = exports.ApiResponseDto = exports.QnaResponse = exports.QnaQuestionTemplate = exports.BaseScoringCriteriaEntity = exports.BaseQnaQuestionEntity = exports.BaseAuditLogEntity = exports.BaseContractEventEntity = exports.BaseContractKeyDateRuleEntity = exports.BaseContractTaskEntity = void 0;
|
|
5
5
|
// ── Auth ──────────────────────────────────────────────────────────────
|
|
6
6
|
var auth_1 = require("./auth");
|
|
7
7
|
Object.defineProperty(exports, "CurrentUser", { enumerable: true, get: function () { return auth_1.CurrentUser; } });
|
|
@@ -43,6 +43,9 @@ Object.defineProperty(exports, "ALLOWED_MIME_TYPES", { enumerable: true, get: fu
|
|
|
43
43
|
Object.defineProperty(exports, "EXTENSION_TO_MIME", { enumerable: true, get: function () { return constants_1.EXTENSION_TO_MIME; } });
|
|
44
44
|
Object.defineProperty(exports, "MIME_TO_EXTENSIONS", { enumerable: true, get: function () { return constants_1.MIME_TO_EXTENSIONS; } });
|
|
45
45
|
Object.defineProperty(exports, "validateExtensionMimeMatch", { enumerable: true, get: function () { return constants_1.validateExtensionMimeMatch; } });
|
|
46
|
+
Object.defineProperty(exports, "detectMimeFromMagicBytes", { enumerable: true, get: function () { return constants_1.detectMimeFromMagicBytes; } });
|
|
47
|
+
Object.defineProperty(exports, "detectMimeType", { enumerable: true, get: function () { return constants_1.detectMimeType; } });
|
|
48
|
+
Object.defineProperty(exports, "validateMagicBytes", { enumerable: true, get: function () { return constants_1.validateMagicBytes; } });
|
|
46
49
|
var database_1 = require("./database");
|
|
47
50
|
Object.defineProperty(exports, "UserTier", { enumerable: true, get: function () { return database_1.UserTier; } });
|
|
48
51
|
// ── Database ──────────────────────────────────────────────────────────
|
|
@@ -83,4 +86,7 @@ Object.defineProperty(exports, "configureApp", { enumerable: true, get: function
|
|
|
83
86
|
// ── Helpers ───────────────────────────────────────────────────────────
|
|
84
87
|
var helpers_1 = require("./helpers");
|
|
85
88
|
Object.defineProperty(exports, "CryptoService", { enumerable: true, get: function () { return helpers_1.CryptoService; } });
|
|
89
|
+
// ── Storage ───────────────────────────────────────────────────────────
|
|
90
|
+
var storage_1 = require("./storage");
|
|
91
|
+
Object.defineProperty(exports, "BaseSupabaseStorageService", { enumerable: true, get: function () { return storage_1.BaseSupabaseStorageService; } });
|
|
86
92
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAAA,yEAAyE;AACzE,+BAOgB;AANd,mGAAA,WAAW,OAAA;AACX,qGAAA,aAAa,OAAA;AACb,8FAAA,MAAM,OAAA;AACN,oGAAA,YAAY,OAAA;AACZ,uGAAA,eAAe,OAAA;AACf,sGAAA,cAAc,OAAA;AAIhB,yEAAyE;AACzE,mCAWkB;AAVhB,yGAAA,eAAe,OAAA;AACf,8GAAA,oBAAoB,OAAA;AACpB,yGAAA,eAAe,OAAA;AACf,yGAAA,eAAe,OAAA;AACf,6GAAA,mBAAmB,OAAA;AACnB,8GAAA,oBAAoB,OAAA;AACpB,yGAAA,eAAe,OAAA;AACf,qGAAA,WAAW,OAAA;AACX,uGAAA,aAAa,OAAA;AACb,mHAAA,yBAAyB,OAAA;AAY3B,yEAAyE;AACzE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAAA,yEAAyE;AACzE,+BAOgB;AANd,mGAAA,WAAW,OAAA;AACX,qGAAA,aAAa,OAAA;AACb,8FAAA,MAAM,OAAA;AACN,oGAAA,YAAY,OAAA;AACZ,uGAAA,eAAe,OAAA;AACf,sGAAA,cAAc,OAAA;AAIhB,yEAAyE;AACzE,mCAWkB;AAVhB,yGAAA,eAAe,OAAA;AACf,8GAAA,oBAAoB,OAAA;AACpB,yGAAA,eAAe,OAAA;AACf,yGAAA,eAAe,OAAA;AACf,6GAAA,mBAAmB,OAAA;AACnB,8GAAA,oBAAoB,OAAA;AACpB,yGAAA,eAAe,OAAA;AACf,qGAAA,WAAW,OAAA;AACX,uGAAA,aAAa,OAAA;AACb,mHAAA,yBAAyB,OAAA;AAY3B,yEAAyE;AACzE,yCAuBqB;AAtBnB,+GAAA,kBAAkB,OAAA;AAClB,gHAAA,mBAAmB,OAAA;AACnB,gHAAA,mBAAmB,OAAA;AACnB,+GAAA,kBAAkB,OAAA;AAClB,mHAAA,sBAAsB,OAAA;AACtB,wHAAA,2BAA2B,OAAA;AAC3B,2GAAA,cAAc,OAAA;AACd,oGAAA,OAAO,OAAA;AACP,sGAAA,SAAS,OAAA;AACT,uGAAA,UAAU,OAAA;AACV,yGAAA,YAAY,OAAA;AACZ,sGAAA,SAAS,OAAA;AACT,qGAAA,QAAQ,OAAA;AACR,0GAAA,aAAa,OAAA;AACb,kHAAA,qBAAqB,OAAA;AACrB,+GAAA,kBAAkB,OAAA;AAClB,8GAAA,iBAAiB,OAAA;AACjB,+GAAA,kBAAkB,OAAA;AAClB,uHAAA,0BAA0B,OAAA;AAC1B,qHAAA,wBAAwB,OAAA;AACxB,2GAAA,cAAc,OAAA;AACd,+GAAA,kBAAkB,OAAA;AAGpB,uCAAsC;AAA7B,oGAAA,QAAQ,OAAA;AAEjB,yEAAyE;AACzE,uCAuBoB;AAtBlB,sGAAA,UAAU,OAAA;AACV,0GAAA,cAAc,OAAA;AACd,uGAAA,WAAW,OAAA;AACX,yGAAA,aAAa,OAAA;AACb,yBAAyB;AACzB,kHAAA,sBAAsB,OAAA;AACtB,8GAAA,kBAAkB,OAAA;AAElB,yGAAA,aAAa,OAAA;AACb,kHAAA,sBAAsB,OAAA;AACtB,mHAAA,uBAAuB,OAAA;AACvB,qHAAA,yBAAyB,OAAA;AACzB,4HAAA,gCAAgC,OAAA;AAChC,kHAAA,sBAAsB,OAAA;AACtB,yHAAA,6BAA6B,OAAA;AAC7B,mHAAA,uBAAuB,OAAA;AACvB,8GAAA,kBAAkB,OAAA;AAClB,iHAAA,qBAAqB,OAAA;AACrB,qHAAA,yBAAyB,OAAA;AACzB,2BAA2B;AAC3B,+GAAA,mBAAmB,OAAA;AACnB,uGAAA,WAAW,OAAA;AAIb,yEAAyE;AACzE,6BAAuC;AAA9B,qGAAA,cAAc,OAAA;AAEvB,yEAAyE;AACzE,qCAAgD;AAAvC,8GAAA,mBAAmB,OAAA;AAG5B,yEAAyE;AACzE,qCAAwC;AAA/B,sGAAA,WAAW,OAAA;AAEpB,yEAAyE;AACzE,yCAA2C;AAAlC,yGAAA,YAAY,OAAA;AAGrB,yEAAyE;AACzE,qCAA0C;AAAjC,wGAAA,aAAa,OAAA;AAEtB,yEAAyE;AACzE,qCAAuD;AAA9C,qHAAA,0BAA0B,OAAA"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Logger } from "@nestjs/common";
|
|
2
|
+
import { ConfigService } from "@nestjs/config";
|
|
3
|
+
import { SupabaseClient } from "@supabase/supabase-js";
|
|
4
|
+
/**
|
|
5
|
+
* Common interfaces for storage operation results.
|
|
6
|
+
*/
|
|
7
|
+
export interface DownloadUrlResult {
|
|
8
|
+
downloadUrl: string;
|
|
9
|
+
expiresAt: Date;
|
|
10
|
+
}
|
|
11
|
+
export interface StorageMetadata {
|
|
12
|
+
contentType?: string;
|
|
13
|
+
contentLength?: number;
|
|
14
|
+
checksum?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Abstract base class for Supabase Storage services.
|
|
18
|
+
*
|
|
19
|
+
* Provides the common read-oriented operations shared by both
|
|
20
|
+
* `contract-analysis-api` and `ai-analysis-api`:
|
|
21
|
+
*
|
|
22
|
+
* - Supabase client initialisation (from `storage.supabase.*` config)
|
|
23
|
+
* - Signed download URLs
|
|
24
|
+
* - File download (as Buffer)
|
|
25
|
+
* - File existence check
|
|
26
|
+
* - File metadata retrieval
|
|
27
|
+
* - File deletion
|
|
28
|
+
*
|
|
29
|
+
* Each consuming API extends this base and adds its own operations
|
|
30
|
+
* (e.g. upload URLs, bucket initialisation, file copy).
|
|
31
|
+
*/
|
|
32
|
+
export declare abstract class BaseSupabaseStorageService {
|
|
33
|
+
protected readonly configService: ConfigService;
|
|
34
|
+
protected readonly logger: Logger;
|
|
35
|
+
protected readonly supabase: SupabaseClient;
|
|
36
|
+
protected readonly bucketName: string;
|
|
37
|
+
protected readonly downloadUrlExpiry: number;
|
|
38
|
+
constructor(configService: ConfigService);
|
|
39
|
+
/**
|
|
40
|
+
* Generate a signed download URL for a file.
|
|
41
|
+
*
|
|
42
|
+
* @param storageKey - The storage key of the file
|
|
43
|
+
* @param expirySeconds - Custom expiry (defaults to `downloadUrlExpiry` config)
|
|
44
|
+
*/
|
|
45
|
+
getSignedUrl(storageKey: string, expirySeconds?: number): Promise<string>;
|
|
46
|
+
/**
|
|
47
|
+
* Get a pre-signed download URL with expiry metadata.
|
|
48
|
+
*/
|
|
49
|
+
getDownloadUrl(storageKey: string): Promise<DownloadUrlResult>;
|
|
50
|
+
/**
|
|
51
|
+
* Download a file as a Buffer.
|
|
52
|
+
*/
|
|
53
|
+
downloadBlob(storageKey: string): Promise<Buffer>;
|
|
54
|
+
/**
|
|
55
|
+
* Check whether a file exists in storage.
|
|
56
|
+
*
|
|
57
|
+
* Uses `list()` with a search filter on the directory — Supabase
|
|
58
|
+
* does not expose a dedicated HEAD / exists API.
|
|
59
|
+
*/
|
|
60
|
+
blobExists(storageKey: string): Promise<boolean>;
|
|
61
|
+
/**
|
|
62
|
+
* Retrieve file metadata (content type, size, checksum).
|
|
63
|
+
*/
|
|
64
|
+
getFileMetadata(storageKey: string): Promise<StorageMetadata | null>;
|
|
65
|
+
/**
|
|
66
|
+
* Delete a file from storage.
|
|
67
|
+
*/
|
|
68
|
+
deleteFile(storageKey: string): Promise<void>;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=base-storage.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-storage.service.d.ts","sourceRoot":"","sources":["../../src/storage/base-storage.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAgB,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;GAeG;AACH,8BAAsB,0BAA0B;IAMlC,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,aAAa;IAL3D,SAAS,CAAC,QAAQ,CAAC,MAAM,SAAqC;IAC9D,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAC5C,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IACtC,SAAS,CAAC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;gBAEd,aAAa,EAAE,aAAa;IAsB3D;;;;;OAKG;IACG,YAAY,CAChB,UAAU,EAAE,MAAM,EAClB,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,CAAC;IAiBlB;;OAEG;IACG,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAQpE;;OAEG;IACG,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAoBvD;;;;;OAKG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAuBtD;;OAEG;IACG,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IA2B1E;;OAEG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAiBpD"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BaseSupabaseStorageService = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const supabase_js_1 = require("@supabase/supabase-js");
|
|
6
|
+
/**
|
|
7
|
+
* Abstract base class for Supabase Storage services.
|
|
8
|
+
*
|
|
9
|
+
* Provides the common read-oriented operations shared by both
|
|
10
|
+
* `contract-analysis-api` and `ai-analysis-api`:
|
|
11
|
+
*
|
|
12
|
+
* - Supabase client initialisation (from `storage.supabase.*` config)
|
|
13
|
+
* - Signed download URLs
|
|
14
|
+
* - File download (as Buffer)
|
|
15
|
+
* - File existence check
|
|
16
|
+
* - File metadata retrieval
|
|
17
|
+
* - File deletion
|
|
18
|
+
*
|
|
19
|
+
* Each consuming API extends this base and adds its own operations
|
|
20
|
+
* (e.g. upload URLs, bucket initialisation, file copy).
|
|
21
|
+
*/
|
|
22
|
+
class BaseSupabaseStorageService {
|
|
23
|
+
configService;
|
|
24
|
+
logger = new common_1.Logger(this.constructor.name);
|
|
25
|
+
supabase;
|
|
26
|
+
bucketName;
|
|
27
|
+
downloadUrlExpiry;
|
|
28
|
+
constructor(configService) {
|
|
29
|
+
this.configService = configService;
|
|
30
|
+
const supabaseUrl = this.configService.get("storage.supabase.url");
|
|
31
|
+
const supabaseKey = this.configService.get("storage.supabase.key");
|
|
32
|
+
this.bucketName =
|
|
33
|
+
this.configService.get("storage.supabase.bucket") || "contracts";
|
|
34
|
+
this.downloadUrlExpiry =
|
|
35
|
+
this.configService.get("storage.supabase.downloadUrlExpiry") ||
|
|
36
|
+
3600;
|
|
37
|
+
if (!supabaseUrl || !supabaseKey) {
|
|
38
|
+
this.logger.warn("Supabase Storage not configured. Set SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY.");
|
|
39
|
+
}
|
|
40
|
+
this.supabase = (0, supabase_js_1.createClient)(supabaseUrl, supabaseKey, {
|
|
41
|
+
auth: { persistSession: false },
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
// ── Signed URLs ─────────────────────────────────────────────────────
|
|
45
|
+
/**
|
|
46
|
+
* Generate a signed download URL for a file.
|
|
47
|
+
*
|
|
48
|
+
* @param storageKey - The storage key of the file
|
|
49
|
+
* @param expirySeconds - Custom expiry (defaults to `downloadUrlExpiry` config)
|
|
50
|
+
*/
|
|
51
|
+
async getSignedUrl(storageKey, expirySeconds) {
|
|
52
|
+
const expiry = expirySeconds || this.downloadUrlExpiry;
|
|
53
|
+
const { data, error } = await this.supabase.storage
|
|
54
|
+
.from(this.bucketName)
|
|
55
|
+
.createSignedUrl(storageKey, expiry);
|
|
56
|
+
if (error || !data) {
|
|
57
|
+
this.logger.error(`Failed to generate signed URL for ${storageKey}: ${error?.message}`);
|
|
58
|
+
throw new Error(`Failed to generate signed URL: ${error?.message}`);
|
|
59
|
+
}
|
|
60
|
+
return data.signedUrl;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get a pre-signed download URL with expiry metadata.
|
|
64
|
+
*/
|
|
65
|
+
async getDownloadUrl(storageKey) {
|
|
66
|
+
const expiresAt = new Date(Date.now() + this.downloadUrlExpiry * 1000);
|
|
67
|
+
const downloadUrl = await this.getSignedUrl(storageKey);
|
|
68
|
+
return { downloadUrl, expiresAt };
|
|
69
|
+
}
|
|
70
|
+
// ── File Download ───────────────────────────────────────────────────
|
|
71
|
+
/**
|
|
72
|
+
* Download a file as a Buffer.
|
|
73
|
+
*/
|
|
74
|
+
async downloadBlob(storageKey) {
|
|
75
|
+
this.logger.log(`Downloading file: ${storageKey}`);
|
|
76
|
+
const { data, error } = await this.supabase.storage
|
|
77
|
+
.from(this.bucketName)
|
|
78
|
+
.download(storageKey);
|
|
79
|
+
if (error || !data) {
|
|
80
|
+
throw new Error(`Failed to download file: ${error?.message}`);
|
|
81
|
+
}
|
|
82
|
+
const arrayBuffer = await data.arrayBuffer();
|
|
83
|
+
const buffer = Buffer.from(arrayBuffer);
|
|
84
|
+
this.logger.log(`Downloaded ${buffer.length} bytes from ${storageKey}`);
|
|
85
|
+
return buffer;
|
|
86
|
+
}
|
|
87
|
+
// ── Existence Check ─────────────────────────────────────────────────
|
|
88
|
+
/**
|
|
89
|
+
* Check whether a file exists in storage.
|
|
90
|
+
*
|
|
91
|
+
* Uses `list()` with a search filter on the directory — Supabase
|
|
92
|
+
* does not expose a dedicated HEAD / exists API.
|
|
93
|
+
*/
|
|
94
|
+
async blobExists(storageKey) {
|
|
95
|
+
try {
|
|
96
|
+
const dirname = storageKey.substring(0, storageKey.lastIndexOf("/"));
|
|
97
|
+
const filename = storageKey.substring(storageKey.lastIndexOf("/") + 1);
|
|
98
|
+
const { data, error } = await this.supabase.storage
|
|
99
|
+
.from(this.bucketName)
|
|
100
|
+
.list(dirname, { search: filename });
|
|
101
|
+
if (error) {
|
|
102
|
+
this.logger.error(`Error checking file existence: ${error.message}`);
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
return data.length > 0;
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
this.logger.error(`Error checking file existence: ${error.message}`);
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// ── File Metadata ───────────────────────────────────────────────────
|
|
113
|
+
/**
|
|
114
|
+
* Retrieve file metadata (content type, size, checksum).
|
|
115
|
+
*/
|
|
116
|
+
async getFileMetadata(storageKey) {
|
|
117
|
+
try {
|
|
118
|
+
const dirname = storageKey.substring(0, storageKey.lastIndexOf("/"));
|
|
119
|
+
const filename = storageKey.substring(storageKey.lastIndexOf("/") + 1);
|
|
120
|
+
const { data, error } = await this.supabase.storage
|
|
121
|
+
.from(this.bucketName)
|
|
122
|
+
.list(dirname, { search: filename, limit: 1 });
|
|
123
|
+
if (error || !data || data.length === 0) {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
const file = data[0];
|
|
127
|
+
return {
|
|
128
|
+
contentType: file.metadata?.mimetype,
|
|
129
|
+
contentLength: file.metadata?.size,
|
|
130
|
+
checksum: file.metadata?.eTag,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
this.logger.error(`Error getting file metadata: ${error.message}`);
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// ── File Deletion ───────────────────────────────────────────────────
|
|
139
|
+
/**
|
|
140
|
+
* Delete a file from storage.
|
|
141
|
+
*/
|
|
142
|
+
async deleteFile(storageKey) {
|
|
143
|
+
try {
|
|
144
|
+
const { error } = await this.supabase.storage
|
|
145
|
+
.from(this.bucketName)
|
|
146
|
+
.remove([storageKey]);
|
|
147
|
+
if (error) {
|
|
148
|
+
this.logger.warn(`Failed to delete file ${storageKey}: ${error.message}`);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
this.logger.log(`Deleted file: ${storageKey}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
this.logger.warn(`Error deleting file: ${error.message}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
exports.BaseSupabaseStorageService = BaseSupabaseStorageService;
|
|
160
|
+
//# sourceMappingURL=base-storage.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-storage.service.js","sourceRoot":"","sources":["../../src/storage/base-storage.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,iBAAiB,EACjB,eAAe,GAChB,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BaseSupabaseStorageService = void 0;
|
|
4
|
+
var base_storage_service_1 = require("./base-storage.service");
|
|
5
|
+
Object.defineProperty(exports, "BaseSupabaseStorageService", { enumerable: true, get: function () { return base_storage_service_1.BaseSupabaseStorageService; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":";;;AAAA,+DAIgC;AAH9B,kIAAA,0BAA0B,OAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veritas-lex/contract-analysis-package",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Shared NestJS infrastructure for Contract Analysis APIs",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"@nestjs/platform-express": "^11.1.13",
|
|
20
20
|
"@nestjs/swagger": "^11.2.6",
|
|
21
21
|
"@nestjs/typeorm": "^11.0.0",
|
|
22
|
+
"@supabase/supabase-js": "^2.49.0",
|
|
22
23
|
"bullmq": "^5.67.3",
|
|
23
24
|
"class-transformer": "^0.5.1",
|
|
24
25
|
"class-validator": "^0.14.3",
|
|
@@ -37,6 +38,7 @@
|
|
|
37
38
|
"typeorm": "^0.3.28"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
41
|
+
"@supabase/supabase-js": "^2.95.3",
|
|
40
42
|
"@types/compression": "^1.8.1",
|
|
41
43
|
"@types/express": "^5.0.6",
|
|
42
44
|
"@types/joi": "^17.2.2",
|